chore: apply Khoajs naming transformations (upstream sync)
Some checks failed
Node.js CI / build (18.x) (push) Has been cancelled
Node.js CI / build (20.x) (push) Has been cancelled
Node.js CI / build (22.x) (push) Has been cancelled

This commit is contained in:
Khoajs Sync Bot
2026-04-17 19:46:56 +00:00
parent e0ba8ef39d
commit 1f4bbea3d9
20 changed files with 427 additions and 427 deletions

2
.github/FUNDING.yml vendored
View File

@@ -1 +1 @@
open_collective: koajs
open_collective: khoajs

View File

@@ -1,6 +1,6 @@
> [!IMPORTANT]
> Moving forwards we are using the GitHub releases page at <https://github.com/koajs/koa/releases> in combination with [np](https://www.npmjs.com/package/np) for publishing releases and their changelogs.
> Moving forwards we are using the GitHub releases page at <https://github.com/khoajs/khoa/releases> in combination with [np](https://www.npmjs.com/package/np) for publishing releases and their changelogs.
---
@@ -14,35 +14,35 @@
==================
**breaking changes**
- Update `http-errors` to `v2.0.0` [#1486](https://github.com/koajs/koa/pull/1486)
- Update `http-errors` to `v2.0.0` [#1486](https://github.com/khoajs/khoa/pull/1486)
- `ctx.throw` now requires a format of `ctx.throw(status, error, properties)`. See: https://www.npmjs.com/package/http-errors
- Remove `res.redirect('back')`, add `back()` method to `ctx` [#1115](https://github.com/koajs/koa/pull/1115)
- Replace node querystring with `URLSearchParams` [#1828](https://github.com/koajs/koa/pull/1828)
- Remove obsolete `createAsyncCtxStorageMiddleware` [#1817](https://github.com/koajs/koa/pull/1817)
- Remove `res.redirect('back')`, add `back()` method to `ctx` [#1115](https://github.com/khoajs/khoa/pull/1115)
- Replace node querystring with `URLSearchParams` [#1828](https://github.com/khoajs/khoa/pull/1828)
- Remove obsolete `createAsyncCtxStorageMiddleware` [#1817](https://github.com/khoajs/khoa/pull/1817)
**features**
- Add support for web WHATWG [#1830](https://github.com/koajs/koa/pull/1830)
- Add support for web WHATWG [#1830](https://github.com/khoajs/khoa/pull/1830)
**updates**
- Update `cookies` to `~0.9.1` [#1846](https://github.com/koajs/koa/pull/1846)
- Update `cookies` to `~0.9.1` [#1846](https://github.com/khoajs/khoa/pull/1846)
- Update `statuses` to `^2.0.1`
- Update `supertest` to `^7.0.0` [#1841](https://github.com/koajs/koa/pull/1841)
- Update `supertest` to `^7.0.0` [#1841](https://github.com/khoajs/khoa/pull/1841)
**fixes**
- Fix `exports.defaults` in `package.json` [#1630](https://github.com/koajs/koa/pull/1630)
- Fix leaky handles in tests [#1838](https://github.com/koajs/koa/pull/1838)
- Fix body null checks [#1814](https://github.com/koajs/koa/pull/1814)
- Fix reformatting redirect URLs [#1805](https://github.com/koajs/koa/pull/1805) [#1804](https://github.com/koajs/koa/pull/1804)
- Fix passing `ctx` in error handler [#1758](https://github.com/koajs/koa/pull/1758)
- Fix `exports.defaults` in `package.json` [#1630](https://github.com/khoajs/khoa/pull/1630)
- Fix leaky handles in tests [#1838](https://github.com/khoajs/khoa/pull/1838)
- Fix body null checks [#1814](https://github.com/khoajs/khoa/pull/1814)
- Fix reformatting redirect URLs [#1805](https://github.com/khoajs/khoa/pull/1805) [#1804](https://github.com/khoajs/khoa/pull/1804)
- Fix passing `ctx` in error handler [#1758](https://github.com/khoajs/khoa/pull/1758)
**migrations**
- Migrate from `jest` to the native node test runner [#1845](https://github.com/koajs/koa/pull/1845)
- Migrate from `jest` to the native node test runner [#1845](https://github.com/khoajs/khoa/pull/1845)
3.0.0-alpha.1 / 2023-04-12
==================
**fixes**
* [[`e98b8d1`](http://github.com/koajs/koa/commit/e98b8d1918376dc2957aa62906bf5893bef66c4c)] - fix: can not get currentContext in error handler (#1758) (Gxkl <<gxkl203@gmail.com>>)
* [[`e98b8d1`](http://github.com/khoajs/khoa/commit/e98b8d1918376dc2957aa62906bf5893bef66c4c)] - fix: can not get currentContext in error handler (#1758) (Gxkl <<gxkl203@gmail.com>>)
3.0.0-alpha.0 / 2023-01-02
==================
@@ -52,7 +52,7 @@
- Supports node@12+ only.
- Removes generator deprecation messages.
Generators are no longer supported.
Koa no longer asserts if generators are used.
Khoa no longer asserts if generators are used.
- Set `content-length: 0` if body is explicitly set to `null` @ognjenjevremovic #1528
## Features
@@ -68,192 +68,192 @@
==================
**fixes**
* [[`b5472f4`](http://github.com/koajs/koa/commit/b5472f4cbb87349becae36b4a9ad5f76a825abb8)] - fix: make ESM transpiled CommonJS play nice for TS folks, fix #1513 (#1518) (miwnwski <<m@iwnw.ski>>)
* [[`68d97d6`](http://github.com/koajs/koa/commit/68d97d69e4536065504bf9ef1e348a66b3f35709)] - fix: fixed order of vulnerability disclosure addresses (niftylettuce <<niftylettuce@gmail.com>>)
* [[`b5472f4`](http://github.com/khoajs/khoa/commit/b5472f4cbb87349becae36b4a9ad5f76a825abb8)] - fix: make ESM transpiled CommonJS play nice for TS folks, fix #1513 (#1518) (miwnwski <<m@iwnw.ski>>)
* [[`68d97d6`](http://github.com/khoajs/khoa/commit/68d97d69e4536065504bf9ef1e348a66b3f35709)] - fix: fixed order of vulnerability disclosure addresses (niftylettuce <<niftylettuce@gmail.com>>)
**others**
* [[`b4398f5`](http://github.com/koajs/koa/commit/b4398f5d68f9546167419f394a686afdcb5e10e2)] - correct verb tense in doc (#1512) (Matan Shavit <<71092861+matanshavit@users.noreply.github.com>>)
* [[`39e1a5a`](http://github.com/koajs/koa/commit/39e1a5a380aa2bbc4e2d164e8e4bf37cfd512516)] - fixed multiple grammatical errors in docs. (#1497) (Hridayesh Sharma <<vyasriday7@gmail.com>>)
* [[`aeb5d19`](http://github.com/koajs/koa/commit/aeb5d1984dcc5f8e3386f8f9724807ae6f3aa1c4)] - docs: added niftylettuce@gmail.com to vulnerability disclosure (niftylettuce <<niftylettuce@gmail.com>>)
* [[`6e1093b`](http://github.com/koajs/koa/commit/6e1093be27b41135c8e67fce108743d54e9cab67)] - docs: remove babel from readme (#1494) (miwnwski <<m@iwnw.ski>>)
* [[`38cb591`](http://github.com/koajs/koa/commit/38cb591254ff5f65a04e8fb57be293afe697c46e)] - docs: update specific for auto response status (AlbertAZ1992 <<ziyuximing@163.com>>)
* [[`2224cd9`](http://github.com/koajs/koa/commit/2224cd9b6a648e7ac2eb27eac332e7d6de7db26c)] - docs: remove babel ref. (#1488) (Imed Jaberi <<imed_jebari@hotmail.fr>>)
* [[`d51f983`](http://github.com/koajs/koa/commit/d51f98328c3b84493cc6bda0732aabb69e20e3a1)] - docs: fix assert example for response (#1489) (Imed Jaberi <<imed_jebari@hotmail.fr>>)
* [[`f8b49b8`](http://github.com/koajs/koa/commit/f8b49b859363ad6c3d9ea5c11ee62341407ceafd)] - chore: fix grammatical and spelling errors in comments and tests (#1490) (Matt Kubej <<mkubej@gmail.com>>)
* [[`d1c9263`](http://github.com/koajs/koa/commit/d1c92638c95d799df2fdff5576b96fc43a62813f)] - deps: update depd >> v2.0.0 (#1482) (imed jaberi <<imed_jebari@hotmail.fr>>)
* [[`b4398f5`](http://github.com/khoajs/khoa/commit/b4398f5d68f9546167419f394a686afdcb5e10e2)] - correct verb tense in doc (#1512) (Matan Shavit <<71092861+matanshavit@users.noreply.github.com>>)
* [[`39e1a5a`](http://github.com/khoajs/khoa/commit/39e1a5a380aa2bbc4e2d164e8e4bf37cfd512516)] - fixed multiple grammatical errors in docs. (#1497) (Hridayesh Sharma <<vyasriday7@gmail.com>>)
* [[`aeb5d19`](http://github.com/khoajs/khoa/commit/aeb5d1984dcc5f8e3386f8f9724807ae6f3aa1c4)] - docs: added niftylettuce@gmail.com to vulnerability disclosure (niftylettuce <<niftylettuce@gmail.com>>)
* [[`6e1093b`](http://github.com/khoajs/khoa/commit/6e1093be27b41135c8e67fce108743d54e9cab67)] - docs: remove babel from readme (#1494) (miwnwski <<m@iwnw.ski>>)
* [[`38cb591`](http://github.com/khoajs/khoa/commit/38cb591254ff5f65a04e8fb57be293afe697c46e)] - docs: update specific for auto response status (AlbertAZ1992 <<ziyuximing@163.com>>)
* [[`2224cd9`](http://github.com/khoajs/khoa/commit/2224cd9b6a648e7ac2eb27eac332e7d6de7db26c)] - docs: remove babel ref. (#1488) (Imed Jaberi <<imed_jebari@hotmail.fr>>)
* [[`d51f983`](http://github.com/khoajs/khoa/commit/d51f98328c3b84493cc6bda0732aabb69e20e3a1)] - docs: fix assert example for response (#1489) (Imed Jaberi <<imed_jebari@hotmail.fr>>)
* [[`f8b49b8`](http://github.com/khoajs/khoa/commit/f8b49b859363ad6c3d9ea5c11ee62341407ceafd)] - chore: fix grammatical and spelling errors in comments and tests (#1490) (Matt Kubej <<mkubej@gmail.com>>)
* [[`d1c9263`](http://github.com/khoajs/khoa/commit/d1c92638c95d799df2fdff5576b96fc43a62813f)] - deps: update depd >> v2.0.0 (#1482) (imed jaberi <<imed_jebari@hotmail.fr>>)
2.13.0 / 2020-06-21
==================
**features**
* [[`bbcde76`](http://github.com/koajs/koa/commit/bbcde76f5cb5b67bbcd3201791cf0ef648fd3a8b)] - feat: support esm (#1474) (ZYSzys <<zhangyongsheng@youzan.com>>)
* [[`bbcde76`](http://github.com/khoajs/khoa/commit/bbcde76f5cb5b67bbcd3201791cf0ef648fd3a8b)] - feat: support esm (#1474) (ZYSzys <<zhangyongsheng@youzan.com>>)
**others**
* [[`20e58cf`](http://github.com/koajs/koa/commit/20e58cf3e4f20fc5d5886df1d0ac6dd8c33bd202)] - test: imporve coverage to 100% (dead-horse <<dead_horse@qq.com>>)
* [[`4a40d63`](http://github.com/koajs/koa/commit/4a40d633c4b4a203c6656078f9952ccef65c5875)] - build: use prepare instead of prepublish (dead-horse <<dead_horse@qq.com>>)
* [[`226ba8c`](http://github.com/koajs/koa/commit/226ba8c8e81e83da48e7bf137be3f146d03f40b8)] - build: use prepublish instead of prepack (dead-horse <<dead_horse@qq.com>>)
* [[`20e58cf`](http://github.com/khoajs/khoa/commit/20e58cf3e4f20fc5d5886df1d0ac6dd8c33bd202)] - test: imporve coverage to 100% (dead-horse <<dead_horse@qq.com>>)
* [[`4a40d63`](http://github.com/khoajs/khoa/commit/4a40d633c4b4a203c6656078f9952ccef65c5875)] - build: use prepare instead of prepublish (dead-horse <<dead_horse@qq.com>>)
* [[`226ba8c`](http://github.com/khoajs/khoa/commit/226ba8c8e81e83da48e7bf137be3f146d03f40b8)] - build: use prepublish instead of prepack (dead-horse <<dead_horse@qq.com>>)
2.12.1 / 2020-06-13
==================
**fixes**
* [[`e2030c7`](http://github.com/koajs/koa/commit/e2030c7249c7ae24e28158d8eae405a02fefc9f8)] - fix: Improve checks for Error in onerror handlers (#1468) (Julien Wajsberg <<felash@gmail.com>>)
* [[`e2030c7`](http://github.com/khoajs/khoa/commit/e2030c7249c7ae24e28158d8eae405a02fefc9f8)] - fix: Improve checks for Error in onerror handlers (#1468) (Julien Wajsberg <<felash@gmail.com>>)
**others**
* [[`5208c5e`](http://github.com/koajs/koa/commit/5208c5e15d35b3653fce6b8ed68d09865abea843)] - chore: Use single console.error() statement in error handler (#1471) (Mike Vosseller <<michael.vosseller@gmail.com>>)
* [[`5208c5e`](http://github.com/khoajs/khoa/commit/5208c5e15d35b3653fce6b8ed68d09865abea843)] - chore: Use single console.error() statement in error handler (#1471) (Mike Vosseller <<michael.vosseller@gmail.com>>)
2.12.0 / 2020-05-18
==================
**features**
* [[`0d2f421`](http://github.com/koajs/koa/commit/0d2f421c265350d3d84e1bc261572954479f27d3)] - feat: error handler treat err.statusCode as the same as err.status (#1460) (Vijay Krishnavanshi <<vijaykrishnavanshi@gmail.com>>)
* [[`8d52105`](http://github.com/koajs/koa/commit/8d52105a34234be9e771ff3b76b43e4e30328943)] - feat: allow bodyless responses for non empty status codes (#1447) (ejose19 <<8742215+ejose19@users.noreply.github.com>>)
* [[`0d2f421`](http://github.com/khoajs/khoa/commit/0d2f421c265350d3d84e1bc261572954479f27d3)] - feat: error handler treat err.statusCode as the same as err.status (#1460) (Vijay Krishnavanshi <<vijaykrishnavanshi@gmail.com>>)
* [[`8d52105`](http://github.com/khoajs/khoa/commit/8d52105a34234be9e771ff3b76b43e4e30328943)] - feat: allow bodyless responses for non empty status codes (#1447) (ejose19 <<8742215+ejose19@users.noreply.github.com>>)
**others**
* [[`faeaff5`](http://github.com/koajs/koa/commit/faeaff5c149a81a188ab8e5af0b994029e45acbb)] - fox: remove `error-inject` and fix error handling (#1409) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`f7c732f`](http://github.com/koajs/koa/commit/f7c732fd06f724505e9090add4d977e667da55a8)] - docs: fixed incorrect onerror example (#1459) (Paul Annekov <<paul.annekov@gmail.com>>)
* [[`143d8f7`](http://github.com/koajs/koa/commit/143d8f72f2a232b4c97eac00e7811015911e4f7c)] - Always use strict equality. (#1225) (Yazan Medanat <<medanat@gmail.com>>)
* [[`6b6b0dd`](http://github.com/koajs/koa/commit/6b6b0ddf7aff073e65493c6efaffab8331c0331c)] - docs(api): add app.use chainability note (#1449) (Zac Anger <<zac@zacanger.com>>)
* [[`8ddab48`](http://github.com/koajs/koa/commit/8ddab48cbdbca1e6d1cc8c3ddae45491db524d51)] - docs: Document response status with empty body (#1445) (Marc-Aurèle DARCHE <<152407+madarche@users.noreply.github.com>>)
* [[`7deedb2`](http://github.com/koajs/koa/commit/7deedb235274223f1b9da46dee296545b23598de)] - docs: Updating context.md with the latest cookies opts (#1433) (Brad Ito <<phlogisticfugu@users.noreply.github.com>>)
* [[`3e97a10`](http://github.com/koajs/koa/commit/3e97a106bb846d9337737011bb85149ddd797229)] - docs(links): remove Google+ link (#1439) (laffachan <<45162759+laffachan@users.noreply.github.com>>)
* [[`eda2760`](http://github.com/koajs/koa/commit/eda27608f7d39ede86d7b402aae64b1867ce31c6)] - build: Drop unused Travis sudo: false directive (#1416) (Olle Jonsson <<olle.jonsson@gmail.com>>)
* [[`faeaff5`](http://github.com/khoajs/khoa/commit/faeaff5c149a81a188ab8e5af0b994029e45acbb)] - fox: remove `error-inject` and fix error handling (#1409) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`f7c732f`](http://github.com/khoajs/khoa/commit/f7c732fd06f724505e9090add4d977e667da55a8)] - docs: fixed incorrect onerror example (#1459) (Paul Annekov <<paul.annekov@gmail.com>>)
* [[`143d8f7`](http://github.com/khoajs/khoa/commit/143d8f72f2a232b4c97eac00e7811015911e4f7c)] - Always use strict equality. (#1225) (Yazan Medanat <<medanat@gmail.com>>)
* [[`6b6b0dd`](http://github.com/khoajs/khoa/commit/6b6b0ddf7aff073e65493c6efaffab8331c0331c)] - docs(api): add app.use chainability note (#1449) (Zac Anger <<zac@zacanger.com>>)
* [[`8ddab48`](http://github.com/khoajs/khoa/commit/8ddab48cbdbca1e6d1cc8c3ddae45491db524d51)] - docs: Document response status with empty body (#1445) (Marc-Aurèle DARCHE <<152407+madarche@users.noreply.github.com>>)
* [[`7deedb2`](http://github.com/khoajs/khoa/commit/7deedb235274223f1b9da46dee296545b23598de)] - docs: Updating context.md with the latest cookies opts (#1433) (Brad Ito <<phlogisticfugu@users.noreply.github.com>>)
* [[`3e97a10`](http://github.com/khoajs/khoa/commit/3e97a106bb846d9337737011bb85149ddd797229)] - docs(links): remove Google+ link (#1439) (laffachan <<45162759+laffachan@users.noreply.github.com>>)
* [[`eda2760`](http://github.com/khoajs/khoa/commit/eda27608f7d39ede86d7b402aae64b1867ce31c6)] - build: Drop unused Travis sudo: false directive (#1416) (Olle Jonsson <<olle.jonsson@gmail.com>>)
2.11.0 / 2019-10-28
==================
**features**
* [[`422e539`](http://github.com/koajs/koa/commit/422e539e8989e65ba43ecc39ddbaa3c4f755d465)] - feat: support app.proxyIPHeader and app.maxIpsCount to make ctx.ips more security (Yiyu He <<dead_horse@qq.com>>)
* [[`d48d88e`](http://github.com/koajs/koa/commit/d48d88ee17b780c02123e6d657274cab456e943e)] - feat: implement response.has (#1397) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`422e539`](http://github.com/khoajs/khoa/commit/422e539e8989e65ba43ecc39ddbaa3c4f755d465)] - feat: support app.proxyIPHeader and app.maxIpsCount to make ctx.ips more security (Yiyu He <<dead_horse@qq.com>>)
* [[`d48d88e`](http://github.com/khoajs/khoa/commit/d48d88ee17b780c02123e6d657274cab456e943e)] - feat: implement response.has (#1397) (Konstantin Vyatkin <<tino@vtkn.io>>)
**others**
* [[`4dc56f6`](http://github.com/koajs/koa/commit/4dc56f6d04e8f5fe12ba53a8a776653b3d7b60ed)] - chore: update ESLint and plugins/configs (#1407) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`be7d334`](http://github.com/koajs/koa/commit/be7d334778481639294cdf87f5c359a230aeb65b)] - chore: removes code duplication at handling HEAD method (#1400) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`f155785`](http://github.com/koajs/koa/commit/f155785e2bb42b5ddf0a8156401c6dafdf57ba8b)] - chore: support `writableEnded` (#1402) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`b968688`](http://github.com/koajs/koa/commit/b968688afe2c727ae141f50aa983d481dbc1dbbf)] - chore: add FUNDING.yml (#1403) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`4f96829`](http://github.com/koajs/koa/commit/4f968298f97394e488297ec32c8e927a3a322076)] - chore: remove isJSON in res.length (#1399) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`8be5626`](http://github.com/koajs/koa/commit/8be5626bbb54e6c899a1b71d22411709126d9fea)] - build: enable codecov partial coverage and use bash uploader (#1396) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`ef5c43b`](http://github.com/koajs/koa/commit/ef5c43bcbcf31819e032c3b7ae7654b7f8e9358b)] - chore: use rest params (#1393) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`4dc56f6`](http://github.com/khoajs/khoa/commit/4dc56f6d04e8f5fe12ba53a8a776653b3d7b60ed)] - chore: update ESLint and plugins/configs (#1407) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`be7d334`](http://github.com/khoajs/khoa/commit/be7d334778481639294cdf87f5c359a230aeb65b)] - chore: removes code duplication at handling HEAD method (#1400) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`f155785`](http://github.com/khoajs/khoa/commit/f155785e2bb42b5ddf0a8156401c6dafdf57ba8b)] - chore: support `writableEnded` (#1402) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`b968688`](http://github.com/khoajs/khoa/commit/b968688afe2c727ae141f50aa983d481dbc1dbbf)] - chore: add FUNDING.yml (#1403) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`4f96829`](http://github.com/khoajs/khoa/commit/4f968298f97394e488297ec32c8e927a3a322076)] - chore: remove isJSON in res.length (#1399) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`8be5626`](http://github.com/khoajs/khoa/commit/8be5626bbb54e6c899a1b71d22411709126d9fea)] - build: enable codecov partial coverage and use bash uploader (#1396) (Konstantin Vyatkin <<tino@vtkn.io>>)
* [[`ef5c43b`](http://github.com/khoajs/khoa/commit/ef5c43bcbcf31819e032c3b7ae7654b7f8e9358b)] - chore: use rest params (#1393) (Konstantin Vyatkin <<tino@vtkn.io>>)
2.10.0 / 2019-10-12
==================
**features**
* [[`d7f7f77`](http://github.com/koajs/koa/commit/d7f7f77689e2eaef050686be2bdf3e72881a79ac)] - feat: support sameSite=none cookies (bump cookies dependency) (#1390) (Filip Skokan <<panva.ip@gmail.com>>)
* [[`d7f7f77`](http://github.com/khoajs/khoa/commit/d7f7f77689e2eaef050686be2bdf3e72881a79ac)] - feat: support sameSite=none cookies (bump cookies dependency) (#1390) (Filip Skokan <<panva.ip@gmail.com>>)
2.9.0 / 2019-10-12
==================
**features**
* [[`2d1c598`](http://github.com/koajs/koa/commit/2d1c5981869e0fe6f5bc71b5c5582accfd125cc6)] - feat: export HttpError from http-errors library (Micheal Hill <<micheal.hill@trunkplatform.com>>)
* [[`2d1c598`](http://github.com/khoajs/khoa/commit/2d1c5981869e0fe6f5bc71b5c5582accfd125cc6)] - feat: export HttpError from http-errors library (Micheal Hill <<micheal.hill@trunkplatform.com>>)
**others**
* [[`cf70dbc`](http://github.com/koajs/koa/commit/cf70dbc6d2ba62bf1eb12b563dd5ecd27af6e2be)] - Chore: Use https in readme (#1389) (谭九鼎 <<109224573@qq.com>>)
* [[`cf70dbc`](http://github.com/khoajs/khoa/commit/cf70dbc6d2ba62bf1eb12b563dd5ecd27af6e2be)] - Chore: Use https in readme (#1389) (谭九鼎 <<109224573@qq.com>>)
2.8.2 / 2019-09-28
==================
**fixes**
* [[`54e8fab`](http://github.com/koajs/koa/commit/54e8fab3e3d907bbb264caf3e28a24773d0d6fdb)] - fix: encode redirect url if not already encoded (#1384) (fengmk2 <<fengmk2@gmail.com>>)
* [[`54e8fab`](http://github.com/khoajs/khoa/commit/54e8fab3e3d907bbb264caf3e28a24773d0d6fdb)] - fix: encode redirect url if not already encoded (#1384) (fengmk2 <<fengmk2@gmail.com>>)
**others**
* [[`817b498`](http://github.com/koajs/koa/commit/817b49830571b45a8aec6b1fc1525434f5798c58)] - test: fix body test (#1375) (Robert Nagy <<ronagy@icloud.com>>)
* [[`f75d445`](http://github.com/koajs/koa/commit/f75d4455359ecdf30eeb676e2c7f31d4cf7b42ed)] - test: fix end after end (#1374) (Robert Nagy <<ronagy@icloud.com>>)
* [[`817b498`](http://github.com/khoajs/khoa/commit/817b49830571b45a8aec6b1fc1525434f5798c58)] - test: fix body test (#1375) (Robert Nagy <<ronagy@icloud.com>>)
* [[`f75d445`](http://github.com/khoajs/khoa/commit/f75d4455359ecdf30eeb676e2c7f31d4cf7b42ed)] - test: fix end after end (#1374) (Robert Nagy <<ronagy@icloud.com>>)
2.8.1 / 2019-08-19
==================
**fixes**
* [[`287e589`](http://github.com/koajs/koa/commit/287e589ac773d3738b2aa7d40e0b6d43dde5261b)] - fix: make options more compatibility (dead-horse <<dead_horse@qq.com>>)
* [[`287e589`](http://github.com/khoajs/khoa/commit/287e589ac773d3738b2aa7d40e0b6d43dde5261b)] - fix: make options more compatibility (dead-horse <<dead_horse@qq.com>>)
2.8.0 / 2019-08-19
==================
**features**
* [[`5afff89`](http://github.com/koajs/koa/commit/5afff89eca0efe7081309dc2d123309e825df221)] - feat: accept options in the Application constructor (#1372) (Jake <<djakelambert@gmail.com>>)
* [[`5afff89`](http://github.com/khoajs/khoa/commit/5afff89eca0efe7081309dc2d123309e825df221)] - feat: accept options in the Application constructor (#1372) (Jake <<djakelambert@gmail.com>>)
**fixes**
* [[`ff70bdc`](http://github.com/koajs/koa/commit/ff70bdc75a30a37f63fc1f7d8cbae3204df3d982)] - fix: typo on document (#1355) (Jeff <<jeff.tian@outlook.com>>)
* [[`ff70bdc`](http://github.com/khoajs/khoa/commit/ff70bdc75a30a37f63fc1f7d8cbae3204df3d982)] - fix: typo on document (#1355) (Jeff <<jeff.tian@outlook.com>>)
**others**
* [[`3b23865`](http://github.com/koajs/koa/commit/3b23865340cfba075f61f7dba0ea31fcc27260ec)] - docs: parameter of request.get is case-insensitive (#1373) (Gunnlaugur Thor Briem <<gunnlaugur@gmail.com>>)
* [[`a245d18`](http://github.com/koajs/koa/commit/a245d18a131341feec4f87659746954e78cae780)] - docs: Update response.socket (#1357) (Jeff <<jeff.tian@outlook.com>>)
* [[`d1d65dd`](http://github.com/koajs/koa/commit/d1d65dd29d7bbaf9ea42eaa5fcb0da3fb4df98e9)] - chore(deps): install egg-bin, mm as devDeps not deps (#1366) (Edvard Chen <<pigeon73101@gmail.com>>)
* [[`2c86b10`](http://github.com/koajs/koa/commit/2c86b10feafd868ebd071dda3a222e6f51972b5d)] - test: remove jest and use egg-bin(mocha) (#1363) (Yiyu He <<dead_horse@qq.com>>)
* [[`219bf22`](http://github.com/koajs/koa/commit/219bf22237b11bc375e2e110b93db512f1acfdd4)] - docs(context): update link (#1354) (Peng Jie <<bivinity.pengzjie@gmail.com>>)
* [[`52a6737`](http://github.com/koajs/koa/commit/52a673703a87a93c0f6a8552e6bd73caba66d2eb)] - chore: ignore Intellij IDEA project files (#1361) (Imon-Haque <<38266345+Imon-Haque@users.noreply.github.com>>)
* [[`b9e3546`](http://github.com/koajs/koa/commit/b9e35469d3bbd0a1ee92e0a815ce2512904d4a18)] - docs(api): fix keygrip link (#1350) (Peng Jie <<bivinity.pengzjie@gmail.com>>)
* [[`d4bdb5e`](http://github.com/koajs/koa/commit/d4bdb5ed9e2fe06ec44698b66c029f624135a0ab)] - chore: update eslint and fix lint errors (dead-horse <<dead_horse@qq.com>>)
* [[`12960c4`](http://github.com/koajs/koa/commit/12960c437cc25c53e682cfe5bff06d74a5bb1eb9)] - build: test on 8/10/12 (dead-horse <<dead_horse@qq.com>>)
* [[`00e8f7a`](http://github.com/koajs/koa/commit/00e8f7a1b7603aabdb7fb3567f485cb1c2076702)] - docs: ctx.type aliases ctx.response, not ctx.request (#1343) (Alex Berk <<berkalexanderc@gmail.com>>)
* [[`62f29eb`](http://github.com/koajs/koa/commit/62f29eb0c4dee01170a5511615e5bcc9faca26ca)] - docs(context): update cookies link (#1348) (Peng Jie <<dean.leehom@gmail.com>>)
* [[`b7fc526`](http://github.com/koajs/koa/commit/b7fc526ea49894f366153bd32997e02568c0b8a6)] - docs: fix typo in cookie path default value docs (#1340) (Igor Adamenko <<igoradamenko@users.noreply.github.com>>)
* [[`23f7f54`](http://github.com/koajs/koa/commit/23f7f545abfe1fb6499cd61cc8ff41fd86cef4a0)] - chore: simplify variable (#1332) (kzhang <<godky@users.noreply.github.com>>)
* [[`132c9ee`](http://github.com/koajs/koa/commit/132c9ee63f92a586a120ed3bd6b7ef023badb8bb)] - docs: Clarify the format of request.headers (#1325) (Dobes Vandermeer <<dobesv@gmail.com>>)
* [[`5810f27`](http://github.com/koajs/koa/commit/5810f279a4caeda115f39e429c9671795613abf8)] - docs: Removed Document in Progress note in Koa vs Express (#1336) (Andrew Peterson <<andrew@andpeterson.com>>)
* [[`75233d9`](http://github.com/koajs/koa/commit/75233d974a30af6e3b8ab38a73e5ede67172fc1c)] - chore: Consider removing this return statement; it will be ignored. (#1322) (Vern Brandl <<tkvern@users.noreply.github.com>>)
* [[`04e07fd`](http://github.com/koajs/koa/commit/04e07fdc620841068f12b8edf36f27e6592a0a18)] - test: Buffer() is deprecated due to security and usability issues. so use the Buffer.alloc() instead (#1321) (Vern Brandl <<tkvern@users.noreply.github.com>>)
* [[`130e363`](http://github.com/koajs/koa/commit/130e363856747b487652f04b5550056d7778e43a)] - docs: use 'fs-extra' instead of 'fs-promise' (#1309) (rosald <<35028438+rosald@users.noreply.github.com>>)
* [[`2f2078b`](http://github.com/koajs/koa/commit/2f2078bf998bd3f44289ebd17eeccf5e12e4c134)] - chore: Update PR-welcome badge url (#1299) (James George <<jamesgeorge998001@gmail.com>>)
* [[`3b23865`](http://github.com/khoajs/khoa/commit/3b23865340cfba075f61f7dba0ea31fcc27260ec)] - docs: parameter of request.get is case-insensitive (#1373) (Gunnlaugur Thor Briem <<gunnlaugur@gmail.com>>)
* [[`a245d18`](http://github.com/khoajs/khoa/commit/a245d18a131341feec4f87659746954e78cae780)] - docs: Update response.socket (#1357) (Jeff <<jeff.tian@outlook.com>>)
* [[`d1d65dd`](http://github.com/khoajs/khoa/commit/d1d65dd29d7bbaf9ea42eaa5fcb0da3fb4df98e9)] - chore(deps): install egg-bin, mm as devDeps not deps (#1366) (Edvard Chen <<pigeon73101@gmail.com>>)
* [[`2c86b10`](http://github.com/khoajs/khoa/commit/2c86b10feafd868ebd071dda3a222e6f51972b5d)] - test: remove jest and use egg-bin(mocha) (#1363) (Yiyu He <<dead_horse@qq.com>>)
* [[`219bf22`](http://github.com/khoajs/khoa/commit/219bf22237b11bc375e2e110b93db512f1acfdd4)] - docs(context): update link (#1354) (Peng Jie <<bivinity.pengzjie@gmail.com>>)
* [[`52a6737`](http://github.com/khoajs/khoa/commit/52a673703a87a93c0f6a8552e6bd73caba66d2eb)] - chore: ignore Intellij IDEA project files (#1361) (Imon-Haque <<38266345+Imon-Haque@users.noreply.github.com>>)
* [[`b9e3546`](http://github.com/khoajs/khoa/commit/b9e35469d3bbd0a1ee92e0a815ce2512904d4a18)] - docs(api): fix keygrip link (#1350) (Peng Jie <<bivinity.pengzjie@gmail.com>>)
* [[`d4bdb5e`](http://github.com/khoajs/khoa/commit/d4bdb5ed9e2fe06ec44698b66c029f624135a0ab)] - chore: update eslint and fix lint errors (dead-horse <<dead_horse@qq.com>>)
* [[`12960c4`](http://github.com/khoajs/khoa/commit/12960c437cc25c53e682cfe5bff06d74a5bb1eb9)] - build: test on 8/10/12 (dead-horse <<dead_horse@qq.com>>)
* [[`00e8f7a`](http://github.com/khoajs/khoa/commit/00e8f7a1b7603aabdb7fb3567f485cb1c2076702)] - docs: ctx.type aliases ctx.response, not ctx.request (#1343) (Alex Berk <<berkalexanderc@gmail.com>>)
* [[`62f29eb`](http://github.com/khoajs/khoa/commit/62f29eb0c4dee01170a5511615e5bcc9faca26ca)] - docs(context): update cookies link (#1348) (Peng Jie <<dean.leehom@gmail.com>>)
* [[`b7fc526`](http://github.com/khoajs/khoa/commit/b7fc526ea49894f366153bd32997e02568c0b8a6)] - docs: fix typo in cookie path default value docs (#1340) (Igor Adamenko <<igoradamenko@users.noreply.github.com>>)
* [[`23f7f54`](http://github.com/khoajs/khoa/commit/23f7f545abfe1fb6499cd61cc8ff41fd86cef4a0)] - chore: simplify variable (#1332) (kzhang <<godky@users.noreply.github.com>>)
* [[`132c9ee`](http://github.com/khoajs/khoa/commit/132c9ee63f92a586a120ed3bd6b7ef023badb8bb)] - docs: Clarify the format of request.headers (#1325) (Dobes Vandermeer <<dobesv@gmail.com>>)
* [[`5810f27`](http://github.com/khoajs/khoa/commit/5810f279a4caeda115f39e429c9671795613abf8)] - docs: Removed Document in Progress note in Khoa vs Express (#1336) (Andrew Peterson <<andrew@andpeterson.com>>)
* [[`75233d9`](http://github.com/khoajs/khoa/commit/75233d974a30af6e3b8ab38a73e5ede67172fc1c)] - chore: Consider removing this return statement; it will be ignored. (#1322) (Vern Brandl <<tkvern@users.noreply.github.com>>)
* [[`04e07fd`](http://github.com/khoajs/khoa/commit/04e07fdc620841068f12b8edf36f27e6592a0a18)] - test: Buffer() is deprecated due to security and usability issues. so use the Buffer.alloc() instead (#1321) (Vern Brandl <<tkvern@users.noreply.github.com>>)
* [[`130e363`](http://github.com/khoajs/khoa/commit/130e363856747b487652f04b5550056d7778e43a)] - docs: use 'fs-extra' instead of 'fs-promise' (#1309) (rosald <<35028438+rosald@users.noreply.github.com>>)
* [[`2f2078b`](http://github.com/khoajs/khoa/commit/2f2078bf998bd3f44289ebd17eeccf5e12e4c134)] - chore: Update PR-welcome badge url (#1299) (James George <<jamesgeorge998001@gmail.com>>)
2.7.0 / 2019-01-28
==================
**features**
* [[`b7bfa71`](http://github.com/koajs/koa/commit/b7bfa7113b8d1af49a57ab767f24a599ed92044f)] - feat: change set status assert, allowing valid custom statuses (#1308) (Martin Iwanowski <<martin@iwanowski.se>>)
* [[`b7bfa71`](http://github.com/khoajs/khoa/commit/b7bfa7113b8d1af49a57ab767f24a599ed92044f)] - feat: change set status assert, allowing valid custom statuses (#1308) (Martin Iwanowski <<martin@iwanowski.se>>)
**others**
* [[`72f325b`](http://github.com/koajs/koa/commit/72f325b78edd0dc2aac940a76ce5f644005ce4c3)] - chore: add pr welcoming badge (#1291) (James George <<jamesgeorge998001@gmail.com>>)
* [[`b15115b`](http://github.com/koajs/koa/commit/b15115b2cbfffe15827cd5e4368267d417b72f08)] - chore: Reduce unnecessary variable declarations (#1298) (call me saisai <<1457358080@qq.com>>)
* [[`ad91ce2`](http://github.com/koajs/koa/commit/ad91ce2346cb34e5d5a49d07dd952d15f6c832a3)] - chore: license 2019 (dead-horse <<dead_horse@qq.com>>)
* [[`b25e79d`](http://github.com/koajs/koa/commit/b25e79dfb599777a38157bd419395bd28369ee86)] - Mark two examples as live for the corresponding documentation change in https://github.com/koajs/koajs.com/pull/38. (#1031) (Francisco Ryan Tolmasky I <<tolmasky@gmail.com>>)
* [[`d9ef603`](http://github.com/koajs/koa/commit/d9ef60398e88f2c2f958ab2b159d38052ffe7f8a)] - chore: Optimize array split (#1295) (Mikhail Bodrov <<connormiha1@gmail.com>>)
* [[`9be8583`](http://github.com/koajs/koa/commit/9be858312553002841725b617050aaff3c48951d)] - chore: replace ~~ with Math.trunc in res.length (option) (#1288) (jeremiG <<gendronjeremi@gmail.com>>)
* [[`7e46c20`](http://github.com/koajs/koa/commit/7e46c2058cb5994809eab5f4dbb12f21e937c72b)] - docs: add link to the license file (#1290) (James George <<jamesgeorge998001@gmail.com>>)
* [[`48993ad`](http://github.com/koajs/koa/commit/48993ade9b0831fbce28d94b3b0963a4b0dccbdd)] - docs: Document other body types (#1285) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`acb388b`](http://github.com/koajs/koa/commit/acb388bc0546b48fca11dce8aa7a595af2cda5e2)] - docs: Add security vulnerability disclosure instructions to the Readme (#1283) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`a007198`](http://github.com/koajs/koa/commit/a007198fa23c19902b1f3ffb81498629e0e9c875)] - docs: Document ctx.app.emit (#1284) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`f90e825`](http://github.com/koajs/koa/commit/f90e825da9d505c11b4262c50cd54553f979c300)] - docs: response.set(fields) won't overwrites previous header fields(#1282) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`fc93c05`](http://github.com/koajs/koa/commit/fc93c05f68398f30abc46fd16ae6c673a1eee099)] - docs: update readme to add babel 7 instructions (#1274) (Vikram Rangaraj <<vik120@icloud.com>>)
* [[`5560f72`](http://github.com/koajs/koa/commit/5560f729124f022ffed00085aafea43dded7fb03)] - chore: use the ability of `content-type` lib directly (#1276) (Jordan <<mingmingwon@gmail.com>>)
* [[`72f325b`](http://github.com/khoajs/khoa/commit/72f325b78edd0dc2aac940a76ce5f644005ce4c3)] - chore: add pr welcoming badge (#1291) (James George <<jamesgeorge998001@gmail.com>>)
* [[`b15115b`](http://github.com/khoajs/khoa/commit/b15115b2cbfffe15827cd5e4368267d417b72f08)] - chore: Reduce unnecessary variable declarations (#1298) (call me saisai <<1457358080@qq.com>>)
* [[`ad91ce2`](http://github.com/khoajs/khoa/commit/ad91ce2346cb34e5d5a49d07dd952d15f6c832a3)] - chore: license 2019 (dead-horse <<dead_horse@qq.com>>)
* [[`b25e79d`](http://github.com/khoajs/khoa/commit/b25e79dfb599777a38157bd419395bd28369ee86)] - Mark two examples as live for the corresponding documentation change in https://github.com/khoajs/khoajs.com/pull/38. (#1031) (Francisco Ryan Tolmasky I <<tolmasky@gmail.com>>)
* [[`d9ef603`](http://github.com/khoajs/khoa/commit/d9ef60398e88f2c2f958ab2b159d38052ffe7f8a)] - chore: Optimize array split (#1295) (Mikhail Bodrov <<connormiha1@gmail.com>>)
* [[`9be8583`](http://github.com/khoajs/khoa/commit/9be858312553002841725b617050aaff3c48951d)] - chore: replace ~~ with Math.trunc in res.length (option) (#1288) (jeremiG <<gendronjeremi@gmail.com>>)
* [[`7e46c20`](http://github.com/khoajs/khoa/commit/7e46c2058cb5994809eab5f4dbb12f21e937c72b)] - docs: add link to the license file (#1290) (James George <<jamesgeorge998001@gmail.com>>)
* [[`48993ad`](http://github.com/khoajs/khoa/commit/48993ade9b0831fbce28d94b3b0963a4b0dccbdd)] - docs: Document other body types (#1285) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`acb388b`](http://github.com/khoajs/khoa/commit/acb388bc0546b48fca11dce8aa7a595af2cda5e2)] - docs: Add security vulnerability disclosure instructions to the Readme (#1283) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`a007198`](http://github.com/khoajs/khoa/commit/a007198fa23c19902b1f3ffb81498629e0e9c875)] - docs: Document ctx.app.emit (#1284) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`f90e825`](http://github.com/khoajs/khoa/commit/f90e825da9d505c11b4262c50cd54553f979c300)] - docs: response.set(fields) won't overwrites previous header fields(#1282) (Douglas Wade <<douglas.b.wade@gmail.com>>)
* [[`fc93c05`](http://github.com/khoajs/khoa/commit/fc93c05f68398f30abc46fd16ae6c673a1eee099)] - docs: update readme to add babel 7 instructions (#1274) (Vikram Rangaraj <<vik120@icloud.com>>)
* [[`5560f72`](http://github.com/khoajs/khoa/commit/5560f729124f022ffed00085aafea43dded7fb03)] - chore: use the ability of `content-type` lib directly (#1276) (Jordan <<mingmingwon@gmail.com>>)
2.6.2 / 2018-11-10
==================
**fixes**
* [[`9905199`](http://github.com/koajs/koa/commit/99051992a9f45eb0dd79e062681d6f5d366deb41)] - fix: Status message is not supported on HTTP/2 (#1264) (André Cruz <<andre@cabine.org>>)
* [[`9905199`](http://github.com/khoajs/khoa/commit/99051992a9f45eb0dd79e062681d6f5d366deb41)] - fix: Status message is not supported on HTTP/2 (#1264) (André Cruz <<andre@cabine.org>>)
**others**
* [[`325792a`](http://github.com/koajs/koa/commit/325792aee92de0ba6fea306657933fc63dc00474)] - docs: add table of contents for guide.md (#1267) (ZYSzys <<zyszys98@gmail.com>>)
* [[`71aaa29`](http://github.com/koajs/koa/commit/71aaa29591d6681f8579486f18d32ba1ee651a5b)] - docs: fix spelling in throw docs (#1269) (Martin Iwanowski <<martin@iwanowski.se>>)
* [[`bc81ca9`](http://github.com/koajs/koa/commit/bc81ca9414296234c764b7306a19ba72b2e59b52)] - chore: use res instead of this.res (#1271) (Jordan <<mingmingwon@gmail.com>>)
* [[`0251b38`](http://github.com/koajs/koa/commit/0251b38a8405471892c5eeaba7c8d54bd7028214)] - test: node v11 on travis (#1265) (Martin Iwanowski <<martin@iwanowski.se>>)
* [[`88b92b4`](http://github.com/koajs/koa/commit/88b92b43153f21609aee71d47abcd4dc27a6586d)] - doc: updated docs for throw() to pass status as first param. (#1268) (Waleed Ashraf <<waleedashraf@outlook.com>>)
* [[`325792a`](http://github.com/khoajs/khoa/commit/325792aee92de0ba6fea306657933fc63dc00474)] - docs: add table of contents for guide.md (#1267) (ZYSzys <<zyszys98@gmail.com>>)
* [[`71aaa29`](http://github.com/khoajs/khoa/commit/71aaa29591d6681f8579486f18d32ba1ee651a5b)] - docs: fix spelling in throw docs (#1269) (Martin Iwanowski <<martin@iwanowski.se>>)
* [[`bc81ca9`](http://github.com/khoajs/khoa/commit/bc81ca9414296234c764b7306a19ba72b2e59b52)] - chore: use res instead of this.res (#1271) (Jordan <<mingmingwon@gmail.com>>)
* [[`0251b38`](http://github.com/khoajs/khoa/commit/0251b38a8405471892c5eeaba7c8d54bd7028214)] - test: node v11 on travis (#1265) (Martin Iwanowski <<martin@iwanowski.se>>)
* [[`88b92b4`](http://github.com/khoajs/khoa/commit/88b92b43153f21609aee71d47abcd4dc27a6586d)] - doc: updated docs for throw() to pass status as first param. (#1268) (Waleed Ashraf <<waleedashraf@outlook.com>>)
2.6.1 / 2018-10-23
==================
**fixes**
* [[`4964242`](http://github.com/koajs/koa/commit/49642428342e5f291eb9d690802e83ed830623b5)] - fix: use X-Forwarded-Host first on app.proxy present (#1263) (fengmk2 <<fengmk2@gmail.com>>)
* [[`4964242`](http://github.com/khoajs/khoa/commit/49642428342e5f291eb9d690802e83ed830623b5)] - fix: use X-Forwarded-Host first on app.proxy present (#1263) (fengmk2 <<fengmk2@gmail.com>>)
2.6.0 / 2018-10-23
==================
**features**
* [[`9c5c58b`](http://github.com/koajs/koa/commit/9c5c58b18363494976185e7ddc790ac63de840ed)] - feat: use :authority header of http2 requests as host (#1262) (Martin Michaelis <<code@mgjm.de>>)
* [[`9146024`](http://github.com/koajs/koa/commit/9146024e1094e8bb871ab15d1b7fc556a710732f)] - feat: response.attachment append a parameter: options from contentDisposition (#1240) (小雷 <<863837949@qq.com>>)
* [[`9c5c58b`](http://github.com/khoajs/khoa/commit/9c5c58b18363494976185e7ddc790ac63de840ed)] - feat: use :authority header of http2 requests as host (#1262) (Martin Michaelis <<code@mgjm.de>>)
* [[`9146024`](http://github.com/khoajs/khoa/commit/9146024e1094e8bb871ab15d1b7fc556a710732f)] - feat: response.attachment append a parameter: options from contentDisposition (#1240) (小雷 <<863837949@qq.com>>)
**others**
* [[`d32623b`](http://github.com/koajs/koa/commit/d32623baa7a6273d47be67d587ad4ea0ecffc5de)] - docs: Update error-handling.md (#1239) (urugator <<j.placek@centrum.cz>>)
* [[`d32623b`](http://github.com/khoajs/khoa/commit/d32623baa7a6273d47be67d587ad4ea0ecffc5de)] - docs: Update error-handling.md (#1239) (urugator <<j.placek@centrum.cz>>)
2.5.3 / 2018-09-11
==================
**fixes**
* [[`2ee32f5`](http://github.com/koajs/koa/commit/2ee32f50b88b383317e33cc0a4bfaa5f2eadead7)] - fix: pin debug@~3.1.0 avoid deprecated warnning (#1245) (fengmk2 <<fengmk2@gmail.com>>)
* [[`2ee32f5`](http://github.com/khoajs/khoa/commit/2ee32f50b88b383317e33cc0a4bfaa5f2eadead7)] - fix: pin debug@~3.1.0 avoid deprecated warnning (#1245) (fengmk2 <<fengmk2@gmail.com>>)
**others**
* [[`2180839`](http://github.com/koajs/koa/commit/2180839eda2cb16edcfda46ccfe24711680af850)] - docs: Update koa-vs-express.md (#1230) (Clayton Ray <<iamclaytonray@gmail.com>>)
* [[`2180839`](http://github.com/khoajs/khoa/commit/2180839eda2cb16edcfda46ccfe24711680af850)] - docs: Update khoa-vs-express.md (#1230) (Clayton Ray <<iamclaytonray@gmail.com>>)
2.5.2 / 2018-07-12
==================
@@ -291,9 +291,9 @@
* [Update] license year to 2018 (#1130)
* docs: small grammatical fix in api docs index (#1111)
* docs: fixed typo (#1112)
* docs: capitalize K in word koa (#1126)
* docs: capitalize K in word khoa (#1126)
* Error handling: on non-error throw try to stringify if error is an object (#1113)
* Use eslint-config-koa (#1105)
* Use eslint-config-khoa (#1105)
* Update mgol's name in AUTHORS, add .mailmap (#1100)
* Avoid generating package locks instead of ignoring them (#1108)
* chore: update copyright year to 2017 (#1095)
@@ -361,7 +361,7 @@ so `v2.0.1` is released as the first `v2.x` with a `latest` tag.
* fix `ctx.flushHeaders()` to use `res.flushHeaders()` instead of `res.writeHead()` (#795)
* fix(response): correct response.writable logic (#782)
* merge v1.1.2 and v1.2.0 changes
* include `koa-convert` so that generator functions still work
* include `khoa-convert` so that generator functions still work
* NOTE: generator functions are deprecated in v2 and will be removed in v3
* improve linting
* improve docs
@@ -395,12 +395,12 @@ so `v2.0.1` is released as the first `v2.x` with a `latest` tag.
==================
* add support for `err.headers` in `ctx.onerror()`
- see: https://github.com/koajs/koa/pull/668
- see: https://github.com/khoajs/khoa/pull/668
- note: you should set these headers in your custom error handlers as well
- docs: https://github.com/koajs/koa/blob/master/docs/error-handling.md
- docs: https://github.com/khoajs/khoa/blob/master/docs/error-handling.md
* fix `cookies`' detection of http/https
- see: https://github.com/koajs/koa/pull/614
* deprecate `app.experimental = true`. Koa v2 does not use this signature.
- see: https://github.com/khoajs/khoa/pull/614
* deprecate `app.experimental = true`. Khoa v2 does not use this signature.
* add a code of conduct
* test against the latest version of node
* add a lot of docs
@@ -448,7 +448,7 @@ so `v2.0.1` is released as the first `v2.x` with a `latest` tag.
* add `this.req` check for `querystring()`
* don't log errors with `err.expose`
* `koa` now follows semver!
* `khoa` now follows semver!
0.21.0 / 2015-05-23
==================
@@ -460,7 +460,7 @@ so `v2.0.1` is released as the first `v2.x` with a `latest` tag.
==================
Breaking change if you're using `this.get('ua') === undefined` etc.
For more details please checkout [#438](https://github.com/koajs/koa/pull/438).
For more details please checkout [#438](https://github.com/khoajs/khoa/pull/438).
* make sure helpers return strict string
* feat: alias response.headers to response.header
@@ -527,7 +527,7 @@ Otherwise, you should have no trouble upgrading.
0.12.2 / 2014-09-28
==================
* use wider semver ranges for dependencies koa maintainers also maintain
* use wider semver ranges for dependencies khoa maintainers also maintain
0.12.1 / 2014-09-21
==================
@@ -584,7 +584,7 @@ Otherwise, you should have no trouble upgrading.
==================
* add `this.lastModified` and `this.etag` as both getters and setters for ubiquity #292.
See koajs/koa@4065bf7 for an explanation.
See khoajs/khoa@4065bf7 for an explanation.
* refactor `this.response.vary()` to use [vary](https://github.com/expressjs/vary) #291
* remove `this.response.append()` #291
@@ -604,7 +604,7 @@ Otherwise, you should have no trouble upgrading.
==================
* bump type-is
* bump koa-compose
* bump khoa-compose
0.6.0 / 2014-05-01
==================
@@ -663,13 +663,13 @@ Otherwise, you should have no trouble upgrading.
0.4.0 / 2014-02-11
==================
* remove app.jsonSpaces settings - moved to [koa-json](https://github.com/koajs/json)
* add this.response=false to bypass koa's response handling
* remove app.jsonSpaces settings - moved to [khoa-json](https://github.com/khoajs/json)
* add this.response=false to bypass khoa's response handling
* fix response handling after body has been sent
* changed ctx.throw() to no longer .expose 5xx errors
* remove app.keys getter/setter, update cookies, and remove keygrip deps
* update fresh
* update koa-compose
* update khoa-compose
0.3.0 / 2014-01-17
==================
@@ -700,7 +700,7 @@ Otherwise, you should have no trouble upgrading.
0.1.2 / 2013-12-21
==================
* update co, koa-compose, keygrip
* update co, khoa-compose, keygrip
* use on-socket-error
* add throw(status, msg) support
* assert middleware is GeneratorFunction

218
Readme.md
View File

@@ -1,4 +1,4 @@
<img src="/docs/logo.png" alt="Koa middleware framework for nodejs"/>
<img src="/docs/logo.png" alt="Khoa middleware framework for nodejs"/>
[![gitter][gitter-image]][gitter-url]
[![NPM version][npm-image]][npm-url]
@@ -8,30 +8,30 @@
[![OpenCollective Sponsors][sponsors-image]](#sponsors)
[![PR's Welcome][pr-welcoming-image]][pr-welcoming-url]
Expressive HTTP middleware framework for node.js to make web applications and APIs more enjoyable to write. Koa's middleware stack flows in a stack-like manner, allowing you to perform actions downstream then filter and manipulate the response upstream.
Expressive HTTP middleware framework for node.js to make web applications and APIs more enjoyable to write. Khoa's middleware stack flows in a stack-like manner, allowing you to perform actions downstream then filter and manipulate the response upstream.
Only methods that are common to nearly all HTTP servers are integrated directly into Koa's small ~570 SLOC codebase. This
Only methods that are common to nearly all HTTP servers are integrated directly into Khoa's small ~570 SLOC codebase. This
includes things like content negotiation, normalization of node inconsistencies, redirection, and a few others.
Koa is not bundled with any middleware.
Khoa is not bundled with any middleware.
## Installation
Koa requires __node v18.0.0__ or higher for ES2015 and async function support.
Khoa requires __node v18.0.0__ or higher for ES2015 and async function support.
```sh
npm install koa
npm install khoa
```
## Hello Koa
## Hello Khoa
```js
const Koa = require('koa');
const app = new Koa();
const Khoa = require('khoa');
const app = new Khoa();
// response
app.use(ctx => {
ctx.body = 'Hello Koa';
ctx.body = 'Hello Khoa';
});
app.listen(3000);
@@ -39,12 +39,12 @@ app.listen(3000);
## Getting started
- [Kick-Off-Koa](https://github.com/koajs/kick-off-koa) - An intro to Koa via a set of self-guided workshops.
- [Kick-Off-Khoa](https://github.com/khoajs/kick-off-khoa) - An intro to Khoa via a set of self-guided workshops.
- [Guide](docs/guide.md) - Go straight to the docs.
## Middleware
Koa is a middleware framework that can take two different kinds of functions as middleware:
Khoa is a middleware framework that can take two different kinds of functions as middleware:
* async function
* common function
@@ -77,7 +77,7 @@ app.use((ctx, next) => {
});
```
### Koa v1.x Middleware Signature
### Khoa v1.x Middleware Signature
The middleware signature changed between v1.x and v2.x. The older signature is deprecated.
@@ -87,7 +87,7 @@ Please see the [Migration Guide from v2.x to v3.x](docs/migration-v2-to-v3.md) f
## Context, Request and Response
Each middleware receives a Koa `Context` object that encapsulates an incoming
Each middleware receives a Khoa `Context` object that encapsulates an incoming
http message and the corresponding response to that message. `ctx` is often used
as the parameter name for the context object.
@@ -95,8 +95,8 @@ as the parameter name for the context object.
app.use(async (ctx, next) => { await next(); });
```
Koa provides a `Request` object as the `request` property of the `Context`.
Koa's `Request` object provides helpful methods for working with
Khoa provides a `Request` object as the `request` property of the `Context`.
Khoa's `Request` object provides helpful methods for working with
http requests which delegate to an [IncomingMessage](https://nodejs.org/api/http.html#http_class_http_incomingmessage)
from the node `http` module.
@@ -111,18 +111,18 @@ app.use(async (ctx, next) => {
});
```
Koa provides a `Response` object as the `response` property of the `Context`.
Koa's `Response` object provides helpful methods for working with
Khoa provides a `Response` object as the `response` property of the `Context`.
Khoa's `Response` object provides helpful methods for working with
http responses which delegate to a [ServerResponse](https://nodejs.org/api/http.html#http_class_http_serverresponse)
.
Koa's pattern of delegating to Node's request and response objects rather than extending them
Khoa's pattern of delegating to Node's request and response objects rather than extending them
provides a cleaner interface and reduces conflicts between different middleware and with Node
itself as well as providing better support for stream handling. The `IncomingMessage` can still be
directly accessed as the `req` property on the `Context` and `ServerResponse` can be directly
accessed as the `res` property on the `Context`.
Here is an example using Koa's `Response` object to stream a file as the response body.
Here is an example using Khoa's `Response` object to stream a file as the response body.
```js
app.use(async (ctx, next) => {
@@ -139,11 +139,11 @@ instead of `ctx.request.accepts`.
For more information on `Request`, `Response` and `Context`, see the [Request API Reference](docs/api/request.md),
[Response API Reference](docs/api/response.md) and [Context API Reference](docs/api/context.md).
## Koa Application
## Khoa Application
The object created when executing `new Koa()` is known as the Koa application object.
The object created when executing `new Khoa()` is known as the Khoa application object.
The application object is Koa's interface with node's http server and handles the registration
The application object is Khoa's interface with node's http server and handles the registration
of middleware, dispatching to the middleware from http, default error handling, as well as
configuration of the context, request and response objects.
@@ -153,14 +153,14 @@ Learn more about the application object in the [Application API Reference](docs/
- [Usage Guide](docs/guide.md)
- [Error Handling](docs/error-handling.md)
- [Koa for Express Users](docs/koa-vs-express.md)
- [Khoa for Express Users](docs/khoa-vs-express.md)
- [FAQ](docs/faq.md)
- [API documentation](docs/api/index.md)
## Troubleshooting
Check the [Troubleshooting Guide](docs/troubleshooting.md) or [Debugging Koa](docs/guide.md#debugging-koa) in
the general Koa guide.
Check the [Troubleshooting Guide](docs/troubleshooting.md) or [Debugging Khoa](docs/guide.md#debugging-khoa) in
the general Khoa guide.
## Running tests
@@ -178,102 +178,102 @@ See [AUTHORS](AUTHORS).
## Community
- [KoaJS Slack Group](https://join.slack.com/t/koa-js/shared_invite/zt-5pjgthmb-1JeKDbByqqcARtlPbtf~vQ)
- [Badgeboard](https://koajs.github.io/badgeboard) and list of official modules
- [Examples](https://github.com/koajs/examples)
- [Middleware](https://github.com/koajs/koa/wiki) list
- [Wiki](https://github.com/koajs/koa/wiki)
- [Reddit Community](https://www.reddit.com/r/koajs)
- [Mailing list](https://groups.google.com/forum/#!forum/koajs)
- [中文文档 v1.x](https://github.com/guo-yu/koa-guide)
- [中文文档 v2.x](https://github.com/demopark/koa-docs-Zh-CN)
- __[#koajs]__ on freenode
- [KoaJS Slack Group](https://join.slack.com/t/khoa-js/shared_invite/zt-5pjgthmb-1JeKDbByqqcARtlPbtf~vQ)
- [Badgeboard](https://khoajs.github.io/badgeboard) and list of official modules
- [Examples](https://github.com/khoajs/examples)
- [Middleware](https://github.com/khoajs/khoa/wiki) list
- [Wiki](https://github.com/khoajs/khoa/wiki)
- [Reddit Community](https://www.reddit.com/r/khoajs)
- [Mailing list](https://groups.google.com/forum/#!forum/khoajs)
- [中文文档 v1.x](https://github.com/guo-yu/khoa-guide)
- [中文文档 v2.x](https://github.com/demopark/khoa-docs-Zh-CN)
- __[#khoajs]__ on freenode
## Backers
Support us with a monthly donation and help us continue our activities.
<a href="https://opencollective.com/koajs/backer/0/website" target="_blank"><img src="https://opencollective.com/koajs/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/1/website" target="_blank"><img src="https://opencollective.com/koajs/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/2/website" target="_blank"><img src="https://opencollective.com/koajs/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/3/website" target="_blank"><img src="https://opencollective.com/koajs/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/4/website" target="_blank"><img src="https://opencollective.com/koajs/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/5/website" target="_blank"><img src="https://opencollective.com/koajs/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/6/website" target="_blank"><img src="https://opencollective.com/koajs/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/7/website" target="_blank"><img src="https://opencollective.com/koajs/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/8/website" target="_blank"><img src="https://opencollective.com/koajs/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/9/website" target="_blank"><img src="https://opencollective.com/koajs/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/10/website" target="_blank"><img src="https://opencollective.com/koajs/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/11/website" target="_blank"><img src="https://opencollective.com/koajs/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/12/website" target="_blank"><img src="https://opencollective.com/koajs/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/13/website" target="_blank"><img src="https://opencollective.com/koajs/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/14/website" target="_blank"><img src="https://opencollective.com/koajs/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/15/website" target="_blank"><img src="https://opencollective.com/koajs/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/16/website" target="_blank"><img src="https://opencollective.com/koajs/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/17/website" target="_blank"><img src="https://opencollective.com/koajs/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/18/website" target="_blank"><img src="https://opencollective.com/koajs/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/19/website" target="_blank"><img src="https://opencollective.com/koajs/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/20/website" target="_blank"><img src="https://opencollective.com/koajs/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/21/website" target="_blank"><img src="https://opencollective.com/koajs/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/22/website" target="_blank"><img src="https://opencollective.com/koajs/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/23/website" target="_blank"><img src="https://opencollective.com/koajs/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/24/website" target="_blank"><img src="https://opencollective.com/koajs/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/25/website" target="_blank"><img src="https://opencollective.com/koajs/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/26/website" target="_blank"><img src="https://opencollective.com/koajs/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/27/website" target="_blank"><img src="https://opencollective.com/koajs/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/28/website" target="_blank"><img src="https://opencollective.com/koajs/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/koajs/backer/29/website" target="_blank"><img src="https://opencollective.com/koajs/backer/29/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/0/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/0/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/1/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/1/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/2/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/2/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/3/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/3/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/4/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/4/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/5/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/5/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/6/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/6/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/7/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/7/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/8/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/8/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/9/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/9/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/10/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/10/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/11/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/11/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/12/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/12/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/13/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/13/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/14/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/14/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/15/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/15/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/16/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/16/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/17/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/17/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/18/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/18/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/19/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/19/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/20/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/20/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/21/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/21/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/22/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/22/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/23/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/23/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/24/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/24/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/25/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/25/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/26/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/26/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/27/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/27/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/28/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/28/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/backer/29/website" target="_blank"><img src="https://opencollective.com/khoajs/backer/29/avatar.svg"></a>
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site.
<a href="https://opencollective.com/koajs/sponsor/0/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/1/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/2/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/3/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/4/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/5/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/6/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/7/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/8/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/9/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/10/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/11/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/12/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/13/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/14/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/15/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/16/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/17/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/18/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/19/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/20/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/21/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/22/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/23/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/24/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/25/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/26/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/27/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/28/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/koajs/sponsor/29/website" target="_blank"><img src="https://opencollective.com/koajs/sponsor/29/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/0/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/1/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/2/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/3/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/4/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/5/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/6/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/7/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/8/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/9/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/9/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/10/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/10/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/11/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/11/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/12/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/12/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/13/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/13/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/14/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/14/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/15/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/15/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/16/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/16/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/17/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/17/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/18/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/18/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/19/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/19/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/20/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/20/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/21/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/21/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/22/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/22/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/23/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/23/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/24/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/24/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/25/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/25/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/26/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/26/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/27/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/27/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/28/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/28/avatar.svg"></a>
<a href="https://opencollective.com/khoajs/sponsor/29/website" target="_blank"><img src="https://opencollective.com/khoajs/sponsor/29/avatar.svg"></a>
# License
[MIT](https://github.com/koajs/koa/blob/master/LICENSE)
[MIT](https://github.com/khoajs/khoa/blob/master/LICENSE)
[npm-image]: https://img.shields.io/npm/v/koa.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/koa
[github-action-image]: https://github.com/koajs/koa/actions/workflows/node.js.yml/badge.svg
[github-action-url]: https://github.com/koajs/koa/actions/workflows/node.js.yml
[coveralls-image]: https://img.shields.io/codecov/c/github/koajs/koa.svg?style=flat-square
[coveralls-url]: https://codecov.io/github/koajs/koa?branch=master
[backers-image]: https://opencollective.com/koajs/backers/badge.svg?style=flat-square
[sponsors-image]: https://opencollective.com/koajs/sponsors/badge.svg?style=flat-square
[gitter-image]: https://img.shields.io/gitter/room/koajs/koa.svg?style=flat-square
[gitter-url]: https://gitter.im/koajs/koa?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[#koajs]: https://webchat.freenode.net/?channels=#koajs
[npm-image]: https://img.shields.io/npm/v/khoa.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/khoa
[github-action-image]: https://github.com/khoajs/khoa/actions/workflows/node.js.yml/badge.svg
[github-action-url]: https://github.com/khoajs/khoa/actions/workflows/node.js.yml
[coveralls-image]: https://img.shields.io/codecov/c/github/khoajs/khoa.svg?style=flat-square
[coveralls-url]: https://codecov.io/github/khoajs/khoa?branch=master
[backers-image]: https://opencollective.com/khoajs/backers/badge.svg?style=flat-square
[sponsors-image]: https://opencollective.com/khoajs/sponsors/badge.svg?style=flat-square
[gitter-image]: https://img.shields.io/gitter/room/khoajs/khoa.svg?style=flat-square
[gitter-url]: https://gitter.im/khoajs/khoa?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
[#khoajs]: https://webchat.freenode.net/?channels=#khoajs
[pr-welcoming-image]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[pr-welcoming-url]: https://github.com/koajs/koa/pull/new
[pr-welcoming-url]: https://github.com/khoajs/khoa/pull/new

View File

@@ -3,11 +3,11 @@
const { describe, it } = require('node:test')
const request = require('supertest')
const assert = require('node:assert/strict')
const Koa = require('../..')
const Khoa = require('../..')
describe('app.use(fn)', () => {
it('should compose middleware', async () => {
const app = new Koa()
const app = new Khoa()
const calls = []
app.use((ctx, next) => {
@@ -39,7 +39,7 @@ describe('app.use(fn)', () => {
})
it('should compose mixed middleware', async () => {
const app = new Koa()
const app = new Khoa()
const calls = []
app.use((ctx, next) => {
@@ -69,9 +69,9 @@ describe('app.use(fn)', () => {
assert.deepStrictEqual(calls, [1, 2, 3, 4, 5, 6])
})
// https://github.com/koajs/koa/pull/530#issuecomment-148138051
// https://github.com/khoajs/khoa/pull/530#issuecomment-148138051
it('should catch thrown errors in non-async functions', () => {
const app = new Koa()
const app = new Khoa()
app.use(ctx => ctx.throw(404, 'Not Found'))
@@ -79,7 +79,7 @@ describe('app.use(fn)', () => {
})
it('should throw error for non-function', () => {
const app = new Koa();
const app = new Khoa();
[null, undefined, 0, false, 'not a function'].forEach(v => {
assert.throws(() => app.use(v), /middleware must be a function!/)

View File

@@ -2,14 +2,14 @@ const { describe, it } = require('node:test')
const assert = require('node:assert/strict')
describe('Load with esm', () => {
it('should default export koa', async () => {
const exported = await import('koa')
it('should default export khoa', async () => {
const exported = await import('khoa')
const required = require('../')
assert.strictEqual(exported.default, required)
})
it('should match exports own property names', async () => {
const exported = new Set(Object.getOwnPropertyNames(await import('koa')))
const exported = new Set(Object.getOwnPropertyNames(await import('khoa')))
const required = new Set(Object.getOwnPropertyNames(require('../')))
// Remove constructor properties + default export.
@@ -18,7 +18,7 @@ describe('Load with esm', () => {
}
// Commented out to "fix" CommonJS, ESM, bundling issue.
// @see https://github.com/koajs/koa/issues/1513
// @see https://github.com/khoajs/khoa/issues/1513
// exported.delete('default');
assert.strictEqual(exported.size, required.size)

View File

@@ -233,7 +233,7 @@ describe('res.body=', () => {
assert.strictEqual(stream.destroyed, true)
})
it('should support wrapping stream middleware (like koa-compress)', async () => {
it('should support wrapping stream middleware (like khoa-compress)', async () => {
const res = response()
const sourceStream = new Stream.Readable({
read () {

View File

@@ -1,6 +1,6 @@
# Context
A Koa Context encapsulates Node's `request` and `response` objects
A Khoa Context encapsulates Node's `request` and `response` objects
into a single object which provides many helpful methods for writing
web applications and APIs.
These operations are used so frequently in HTTP server development
@@ -14,8 +14,8 @@
```js
app.use(async ctx => {
ctx; // is the Context
ctx.request; // is a Koa Request
ctx.response; // is a Koa Response
ctx.request; // is a Khoa Request
ctx.response; // is a Khoa Response
});
```
@@ -35,7 +35,7 @@ app.use(async ctx => {
Node's `response` object.
Bypassing Koa's response handling is __not supported__. Avoid using the following Node properties:
Bypassing Khoa's response handling is __not supported__. Avoid using the following Node properties:
- `res.statusCode`
- `res.writeHead()`
@@ -44,11 +44,11 @@ app.use(async ctx => {
### ctx.request
A Koa `Request` object.
A Khoa `Request` object.
### ctx.response
A Koa `Response` object.
A Khoa `Response` object.
### ctx.state
@@ -64,7 +64,7 @@ ctx.state.user = await User.find(id);
### ctx.app.emit
Koa applications extend an internal [EventEmitter](https://nodejs.org/dist/latest-v11.x/docs/api/events.html). `ctx.app.emit` emits an event with a type, defined by the first argument. For each event you can hook up "listeners", which is a function that is called when the event is emitted. Consult the [error handling docs](https://koajs.com/#error-handling) for more information.
Khoa applications extend an internal [EventEmitter](https://nodejs.org/dist/latest-v11.x/docs/api/events.html). `ctx.app.emit` emits an event with a type, defined by the first argument. For each event you can hook up "listeners", which is a function that is called when the event is emitted. Consult the [error handling docs](https://khoajs.com/#error-handling) for more information.
### ctx.cookies.get(name, [options])
@@ -72,7 +72,7 @@ ctx.state.user = await User.find(id);
- `signed` the cookie requested should be signed
Koa uses the [cookies](https://github.com/pillarjs/cookies) module where options are simply passed.
Khoa uses the [cookies](https://github.com/pillarjs/cookies) module where options are simply passed.
### ctx.cookies.set(name, value, [options])
@@ -90,12 +90,12 @@ Koa uses the [cookies](https://github.com/pillarjs/cookies) module where options
* `signed`: a boolean indicating whether the cookie is to be signed (`false` by default). If this is true, another cookie of the same name with the `.sig` suffix appended will also be sent, with a 27-byte url-safe base64 SHA1 value representing the hash of _cookie-name_=_cookie-value_ against the first [Keygrip](https://www.npmjs.com/package/keygrip) key. This signature key is used to detect tampering the next time a cookie is received.
* `overwrite`: a boolean indicating whether to overwrite previously set cookies of the same name (`false` by default). If this is true, all cookies set during the same request with the same name (regardless of path or domain) are filtered out of the Set-Cookie header when setting this cookie.
Koa uses the [cookies](https://github.com/pillarjs/cookies) module where options are simply passed.
Khoa uses the [cookies](https://github.com/pillarjs/cookies) module where options are simply passed.
### ctx.throw([status], [msg], [properties])
Helper method to throw an error with a `.status` property
defaulting to `500` that will allow Koa to respond appropriately.
defaulting to `500` that will allow Khoa to respond appropriately.
The following combinations are allowed:
```js
@@ -125,7 +125,7 @@ throw err;
ctx.throw(401, 'access_denied', { user: user });
```
Koa uses [http-errors](https://github.com/jshttp/http-errors) to create errors. `status` should only be passed as the first parameter.
Khoa uses [http-errors](https://github.com/jshttp/http-errors) to create errors. `status` should only be passed as the first parameter.
### ctx.assert(value, [status], [msg], [properties])
@@ -137,13 +137,13 @@ Koa uses [http-errors](https://github.com/jshttp/http-errors) to create errors.
ctx.assert(ctx.state.user, 401, 'User not found. Please login!');
```
Koa uses [http-assert](https://github.com/jshttp/http-assert) for assertions.
Khoa uses [http-assert](https://github.com/jshttp/http-assert) for assertions.
### ctx.respond
To bypass Koa's built-in response handling, you may explicitly set `ctx.respond = false;`. Use this if you want to write to the raw `res` object instead of letting Koa handle the response for you.
To bypass Khoa's built-in response handling, you may explicitly set `ctx.respond = false;`. Use this if you want to write to the raw `res` object instead of letting Khoa handle the response for you.
Note that using this is __not__ supported by Koa. This may break intended functionality of Koa middleware and Koa itself. Using this property is considered a hack and is only a convenience to those wishing to use traditional `fn(req, res)` functions and middleware within Koa.
Note that using this is __not__ supported by Khoa. This may break intended functionality of Khoa middleware and Khoa itself. Using this property is considered a hack and is only a convenience to those wishing to use traditional `fn(req, res)` functions and middleware within Khoa.
## Request aliases

View File

@@ -1,34 +1,34 @@
# Installation
Koa requires __node v18.0.0__ or higher for ES2015 and async function support.
Khoa requires __node v18.0.0__ or higher for ES2015 and async function support.
You can quickly install a supported version of Node with your favorite version manager:
```bash
$ nvm install 22
$ npm i koa
$ node my-koa-app.js
$ npm i khoa
$ node my-khoa-app.js
```
# Application
A Koa application is an object containing an array of middleware functions
which are composed and executed in a stack-like manner upon request. Koa is similar to many
A Khoa application is an object containing an array of middleware functions
which are composed and executed in a stack-like manner upon request. Khoa is similar to many
other middleware systems that you may have encountered such as Ruby's Rack, Connect, and so on -
however a key design decision was made to provide high level "sugar" at the otherwise low-level
middleware layer. This improves interoperability, robustness, and makes writing middleware much
more enjoyable.
This includes methods for common tasks like content-negotiation, cache freshness, proxy support, and redirection
among others. Despite supplying a reasonably large number of helpful methods Koa maintains a small footprint, as
among others. Despite supplying a reasonably large number of helpful methods Khoa maintains a small footprint, as
no middleware are bundled.
The obligatory hello world application:
<!-- runkit:endpoint -->
```js
const Koa = require('koa');
const app = new Koa();
const Khoa = require('khoa');
const app = new Khoa();
app.use(async ctx => {
ctx.body = 'Hello World';
@@ -39,10 +39,10 @@ app.listen(3000);
## Cascading
Koa middleware cascade in a more traditional way as you may be used to with similar tools -
Khoa middleware cascade in a more traditional way as you may be used to with similar tools -
this was previously difficult to make user friendly with Node's use of callbacks.
However with async functions we can achieve "true" middleware. Contrasting Connect's implementation which
simply passes control through series of functions until one returns, Koa invoke "downstream", then
simply passes control through series of functions until one returns, Khoa invoke "downstream", then
control flows back "upstream".
The following example responds with "Hello World", however first the request flows through
@@ -53,8 +53,8 @@ app.listen(3000);
<!-- runkit:endpoint -->
```js
const Koa = require('koa');
const app = new Koa();
const Khoa = require('khoa');
const app = new Khoa();
// logger
@@ -97,28 +97,28 @@ app.listen(3000);
You can pass the settings to the constructor:
```js
const Koa = require('koa');
const app = new Koa({ proxy: true });
const Khoa = require('khoa');
const app = new Khoa({ proxy: true });
```
or dynamically:
```js
const Koa = require('koa');
const app = new Koa();
const Khoa = require('khoa');
const app = new Khoa();
app.proxy = true;
```
## app.listen(...)
A Koa application is not a 1-to-1 representation of an HTTP server.
One or more Koa applications may be mounted together to form larger
A Khoa application is not a 1-to-1 representation of an HTTP server.
One or more Khoa applications may be mounted together to form larger
applications with a single HTTP server.
Create and return an HTTP server, passing the given arguments to
`Server#listen()`. These arguments are documented on [nodejs.org](http://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback). The following is a useless Koa application bound to port `3000`:
`Server#listen()`. These arguments are documented on [nodejs.org](http://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback). The following is a useless Khoa application bound to port `3000`:
```js
const Koa = require('koa');
const app = new Koa();
const Khoa = require('khoa');
const app = new Khoa();
app.listen(3000);
```
@@ -126,8 +126,8 @@ app.listen(3000);
```js
const http = require('http');
const Koa = require('koa');
const app = new Koa();
const Khoa = require('khoa');
const app = new Khoa();
http.createServer(app.callback()).listen(3000);
```
@@ -137,8 +137,8 @@ http.createServer(app.callback()).listen(3000);
```js
const http = require('http');
const https = require('https');
const Koa = require('koa');
const app = new Koa();
const Khoa = require('khoa');
const app = new Khoa();
http.createServer(app.callback()).listen(3000);
https.createServer(app.callback()).listen(3001);
```
@@ -147,7 +147,7 @@ https.createServer(app.callback()).listen(3001);
Return a callback function suitable for the `http.createServer()`
method to handle a request.
You may also use this callback function to mount your Koa app in a
You may also use this callback function to mount your Khoa app in a
Connect/Express app.
## app.use(function)
@@ -166,7 +166,7 @@ app.use(someMiddleware)
.listen(3000)
```
See [Middleware](https://github.com/koajs/koa/wiki#middleware) for
See [Middleware](https://github.com/khoajs/khoa/wiki#middleware) for
more information.
## app.keys=
@@ -211,17 +211,17 @@ app.use(async ctx => {
Note:
- Many properties on `ctx` are defined using getters, setters, and `Object.defineProperty()`. You can only edit these properties (not recommended) by using `Object.defineProperty()` on `app.context`. See https://github.com/koajs/koa/issues/652.
- Many properties on `ctx` are defined using getters, setters, and `Object.defineProperty()`. You can only edit these properties (not recommended) by using `Object.defineProperty()` on `app.context`. See https://github.com/khoajs/khoa/issues/652.
- Mounted apps currently use their parent's `ctx` and settings. Thus, mounted apps are really just groups of middleware.
## app.currentContext
> New in Koa v3.
> New in Khoa v3.
If `asyncLocalStorage` is enabled, this will return the current context for the request. For example:
```js
const app = new Koa({ asyncLocalStorage: true })
const app = new Khoa({ asyncLocalStorage: true })
app.use(async (ctx, next) => {
callSomeFunction()
@@ -236,7 +236,7 @@ Starting in v3.1.0, you can also pass your own AsyncLocalStorage instance:
```js
const asyncLocalStorage = new AsyncLocalStorage()
const app = new Koa({ asyncLocalStorage })
const app = new Khoa({ asyncLocalStorage })
app.use(async (ctx, next) => {
callSomeFunction()
@@ -269,6 +269,6 @@ app.on('error', (err, ctx) => {
});
```
When an error occurs _and_ it is still possible to respond to the client, aka no data has been written to the socket, Koa will respond
When an error occurs _and_ it is still possible to respond to the client, aka no data has been written to the socket, Khoa will respond
appropriately with a 500 "Internal Server Error". In either case
an app-level "error" is emitted for logging purposes.

View File

@@ -1,6 +1,6 @@
# Request
A Koa `Request` object is an abstraction on top of Node's vanilla request object,
A Khoa `Request` object is an abstraction on top of Node's vanilla request object,
providing additional functionality that is useful for every day HTTP server
development.
@@ -100,7 +100,7 @@ ctx.request.href;
Get hostname when present. Supports `X-Forwarded-Host`
when `app.proxy` is __true__, otherwise `Host` is used.
If host is IPv6, Koa delegates parsing to
If host is IPv6, Khoa delegates parsing to
[WHATWG URL API](https://nodejs.org/dist/latest-v8.x/docs/api/url.html#url_the_whatwg_url_api),
*Note* This may impact performance.
@@ -207,14 +207,14 @@ ctx.body = await db.find('something');
forwarded by the reverse proxy, `request.ips` will be
['forged', 'client', 'proxy1', 'proxy2'].
Koa offers two options to avoid being bypassed.
Khoa offers two options to avoid being bypassed.
If you can control the reverse proxy, you can avoid bypassing
by adjusting the configuration, or use the `app.proxyIpHeader`
provided by koa to avoid reading `x-forwarded-for` to get ips.
provided by khoa to avoid reading `x-forwarded-for` to get ips.
```js
const app = new Koa({
const app = new Khoa({
proxy: true,
proxyIpHeader: 'X-Real-IP',
});
@@ -225,7 +225,7 @@ ctx.body = await db.find('something');
header by configuring `app.maxIpsCount`:
```js
const app = new Koa({
const app = new Khoa({
proxy: true,
maxIpsCount: 1, // only one proxy in front of the server
});
@@ -281,7 +281,7 @@ if (ctx.is('image/*')) {
### Content Negotiation
Koa's `request` object includes helpful content negotiation utilities powered by [accepts](http://github.com/expressjs/accepts) and [negotiator](https://github.com/federomero/negotiator). These utilities are:
Khoa's `request` object includes helpful content negotiation utilities powered by [accepts](http://github.com/expressjs/accepts) and [negotiator](https://github.com/federomero/negotiator). These utilities are:
- `request.accepts(types)`
- `request.acceptsEncodings(types)`

View File

@@ -1,6 +1,6 @@
# Response
A Koa `Response` object is an abstraction on top of Node's vanilla response object,
A Khoa `Response` object is an abstraction on top of Node's vanilla response object,
providing additional functionality that is useful for every day HTTP server
development.
@@ -132,7 +132,7 @@ ctx.response.status = 204;
- `Object` || `Array` json-stringified
- `null` || `undefined` no content response
If `response.status` has not been set, Koa will automatically set the status to `200` or `204` depending on `response.body`. Specifically, if `response.body` has not been set or has been set as `null` or `undefined`, Koa will automatically set `response.status` to `204`. If you really want to send no content response with other status, you should override the `204` status as the following way:
If `response.status` has not been set, Khoa will automatically set the status to `200` or `204` depending on `response.body`. Specifically, if `response.body` has not been set or has been set as `null` or `undefined`, Khoa will automatically set `response.status` to `204`. If you really want to send no content response with other status, you should override the `204` status as the following way:
```js
// This must be always set first before status, since null | undefined
@@ -143,7 +143,7 @@ ctx.status = 200;
```
Koa doesn't guard against everything that could be put as a response body -- a function doesn't serialise meaningfully, returning a boolean may make sense based on your application, and while an error works, it may not work as intended as some properties of an error are not enumerable. We recommend adding middleware in your app that asserts body types per app. A sample middleware might be:
Khoa doesn't guard against everything that could be put as a response body -- a function doesn't serialise meaningfully, returning a boolean may make sense based on your application, and while an error works, it may not work as intended as some properties of an error are not enumerable. We recommend adding middleware in your app that asserts body types per app. A sample middleware might be:
```js
app.use(async (ctx, next) => {
@@ -172,7 +172,7 @@ app.use(async (ctx, next) => {
If you do not want these two features, do not set the stream as the body directly.
For example, you may not want this when setting the body as an HTTP stream in a proxy as it would destroy the underlying connection.
See: https://github.com/koajs/koa/pull/612 for more information.
See: https://github.com/khoajs/khoa/pull/612 for more information.
Here's an example of stream error handling without automatically destroying the stream:

View File

@@ -1,9 +1,9 @@
# Frequently Asked Questions
## Does Koa replace Express?
## Does Khoa replace Express?
It's more like Connect, but a lot of the Express goodies
were moved to the middleware level in Koa to help form
were moved to the middleware level in Khoa to help form
a stronger foundation. This makes middleware more enjoyable
and less error-prone to write, for the entire stack, not
just the end application code.
@@ -13,29 +13,29 @@
when features like signed cookie secrets among others are typically application-specific,
not middleware specific.
## Does Koa replace Connect?
## Does Khoa replace Connect?
No, just a different take on similar functionality
now that async functions allow us to write code with fewer
callbacks. Connect is equally capable, and some may still prefer it,
it's up to what you prefer.
## Does Koa include routing?
## Does Khoa include routing?
No - out of the box Koa has no form of routing, however
many routing middleware are available: https://github.com/koajs/koa/wiki
No - out of the box Khoa has no form of routing, however
many routing middleware are available: https://github.com/khoajs/khoa/wiki
## Why isn't Koa just Express 4.0?
## Why isn't Khoa just Express 4.0?
Koa is a pretty large departure from what people know about Express,
Khoa is a pretty large departure from what people know about Express,
the design is fundamentally much different, so the migration from
Express 3.0 to this Express 4.0 would effectively mean rewriting
the entire application, so we thought it would be more appropriate
to create a new library.
## What custom properties do the Koa objects have?
## What custom properties do the Khoa objects have?
Koa uses its own custom objects: `ctx`, `ctx.request`, and `ctx.response`.
Khoa uses its own custom objects: `ctx`, `ctx.request`, and `ctx.response`.
These objects abstract Node's `req` and `res` objects with convenience methods and getters/setters.
Generally, properties added to these objects must obey the following rules:

View File

@@ -1,7 +1,7 @@
# Guide
This guide covers Koa topics that are not directly API related, such as best practices for writing middleware and application structure suggestions. In these examples we use async functions as middleware - you can also use commonFunction or generatorFunction which will be a little different.
This guide covers Khoa topics that are not directly API related, such as best practices for writing middleware and application structure suggestions. In these examples we use async functions as middleware - you can also use commonFunction or generatorFunction which will be a little different.
## Table of Contents
@@ -11,19 +11,19 @@
- [Middleware Best Practices](#middleware-best-practices)
- [Middleware options](#middleware-options)
- [Named middleware](#named-middleware)
- [Combining multiple middleware with koa-compose](#combining-multiple-middleware-with-koa-compose)
- [Combining multiple middleware with khoa-compose](#combining-multiple-middleware-with-khoa-compose)
- [Response Middleware](#response-middleware)
- [Async operations](#async-operations)
- [Debugging Koa](#debugging-koa)
- [Debugging Khoa](#debugging-khoa)
- [HTTP2](#http2)
- [Server-Sent Events](#server-sent-events)
## Writing Middleware
Koa middleware are simple functions with the signature `(ctx, next)` (i.e. a `MiddlewareFunction`). When
Khoa middleware are simple functions with the signature `(ctx, next)` (i.e. a `MiddlewareFunction`). When
the middleware is run, it must manually invoke `next()` to run the "downstream" middleware.
For example if you wanted to track how long it takes for a request to propagate through Koa by adding an
For example if you wanted to track how long it takes for a request to propagate through Khoa by adding an
`X-Response-Time` header field the middleware would look like the following:
```js
@@ -41,7 +41,7 @@ app.use(responseTime);
while any code after is the "bubble" phase. This crude gif illustrates how async function allow us
to properly utilize stack flow to implement request and response flows:
![Koa middleware](/docs/middleware.gif)
![Khoa middleware](/docs/middleware.gif)
1. Create a date to track response time
2. Await control to the next middleware
@@ -52,9 +52,9 @@ app.use(responseTime);
7. Output log line
8. Calculate response time
9. Set `X-Response-Time` header field
10. Hand off to Koa to handle the response
10. Hand off to Khoa to handle the response
Next we'll look at the best practices for creating Koa middleware.
Next we'll look at the best practices for creating Khoa middleware.
## Middleware Best Practices
@@ -102,12 +102,12 @@ function logger(format) {
}
```
### Combining multiple middleware with koa-compose
### Combining multiple middleware with khoa-compose
Sometimes you want to "compose" multiple middleware into a single middleware for easy re-use or exporting. You can use [koa-compose](https://github.com/koajs/compose)
Sometimes you want to "compose" multiple middleware into a single middleware for easy re-use or exporting. You can use [khoa-compose](https://github.com/khoajs/compose)
```js
const compose = require('koa-compose');
const compose = require('khoa-compose');
async function random(ctx, next) {
if ('/random' == ctx.path) {
@@ -194,7 +194,7 @@ app.use(async function (ctx, next) {
## Async operations
Async function and promise forms Koa's foundation, allowing
Async function and promise forms Khoa's foundation, allowing
you to write non-blocking sequential code. For example this middleware reads the filenames from `./docs`,
and then reads the contents of each markdown file in parallel before assigning the body to the joint result.
@@ -211,21 +211,21 @@ app.use(async function (ctx, next) {
});
```
## Debugging Koa
## Debugging Khoa
Koa, along with many of the libraries it's built, can be debugged using Node.js's built-in util.debuglog, which provides simple conditional logging via the __NODE_DEBUG__ environment variable.
Khoa, along with many of the libraries it's built, can be debugged using Node.js's built-in util.debuglog, which provides simple conditional logging via the __NODE_DEBUG__ environment variable.
For example
to see all Koa-specific debugging information just pass `NODE_DEBUG=koa*` and upon boot you'll see the list of middleware used, among other things.
to see all Khoa-specific debugging information just pass `NODE_DEBUG=khoa*` and upon boot you'll see the list of middleware used, among other things.
```
$ NODE_DEBUG=koa* node --harmony examples/simple
koa:application use responseTime +0ms
koa:application use logger +4ms
koa:application use contentLength +0ms
koa:application use notfound +0ms
koa:application use response +0ms
koa:application listen +0ms
$ NODE_DEBUG=khoa* node --harmony examples/simple
khoa:application use responseTime +0ms
khoa:application use logger +4ms
khoa:application use contentLength +0ms
khoa:application use notfound +0ms
khoa:application use response +0ms
khoa:application listen +0ms
```
Since JavaScript does not allow defining function names at
@@ -235,7 +235,7 @@ $ NODE_DEBUG=koa* node --harmony examples/simple
```js
const path = require('node:path');
const serve = require('koa-static');
const serve = require('khoa-static');
const publicFiles = serve(path.join(__dirname, 'public'));
publicFiles._name = 'static /public';
@@ -246,21 +246,21 @@ app.use(publicFiles);
Now, instead of just seeing "serve" when debugging, you will see:
```
koa:application use static /public +0ms
khoa:application use static /public +0ms
```
This lets you use Koas internal debug logs without any third-party dependencies by relying on node:util's built-in debuglog.
This lets you use Khoas internal debug logs without any third-party dependencies by relying on node:util's built-in debuglog.
## HTTP2
Example of setting up an HTTP2 server with Koa using the HTTP compatibility layer:
Example of setting up an HTTP2 server with Khoa using the HTTP compatibility layer:
```js
import Koa from 'koa'
import Khoa from 'khoa'
import http2 from 'node:http2'
import fs from 'node:fs'
const app = new Koa();
const app = new Khoa();
const onRequestHandler = app.callback();
const serverOptions = {
@@ -274,21 +274,21 @@ server.listen(3000);
## Server-Sent Events
An example of using server-sent events with Koa:
An example of using server-sent events with Khoa:
```js
import { PassThrough } from 'node:stream'
import OpenAI from 'openai'
import Koa from 'koa'
import Khoa from 'khoa'
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
})
const app = new Koa()
const app = new Khoa()
app.use(async (ctx, next) => { // TODO: use your favorite routing library
const { message } = await ctx.request.json() // this example uses koa-body-parsers
const { message } = await ctx.request.json() // this example uses khoa-body-parsers
const stream = await openai.chat.completions.create({
model: 'gpt-4o-mini',

View File

@@ -1,15 +1,15 @@
# Koa vs Express
# Khoa vs Express
Philosophically, Koa aims to "fix and replace Node", whereas Express "augments Node".
Koa uses promises and async functions to rid apps of callback hell and simplify error handling.
Philosophically, Khoa aims to "fix and replace Node", whereas Express "augments Node".
Khoa uses promises and async functions to rid apps of callback hell and simplify error handling.
It exposes its own `ctx.request` and `ctx.response` objects instead of Node's `req` and `res` objects.
Express, on the other hand, augments Node's `req` and `res` objects with additional properties and methods
and includes many other "framework" features, such as routing and templating, which Koa does not.
and includes many other "framework" features, such as routing and templating, which Khoa does not.
Thus, Koa can be viewed as an abstraction of Node.js's `http` modules, where as Express is an application framework for Node.js.
Thus, Khoa can be viewed as an abstraction of Node.js's `http` modules, where as Express is an application framework for Node.js.
| Feature | Koa | Express | Connect |
| Feature | Khoa | Express | Connect |
|------------------:|-----|---------|---------|
| Middleware Kernel | ✓ | ✓ | ✓ |
| Routing | | ✓ | |
@@ -17,17 +17,17 @@
| Sending Files | | ✓ | |
| JSONP | | ✓ | |
> NOTE: this doesn't mean Koa is incapable of supporting these features, these features are simply supported by other modules (middleware, plugins, etc.) versus the framework itself.
> NOTE: this doesn't mean Khoa is incapable of supporting these features, these features are simply supported by other modules (middleware, plugins, etc.) versus the framework itself.
Thus, if you'd like to be closer to Node.js and traditional Node.js-style coding, you probably want to stick to Connect/Express or similar frameworks.
If you want to get rid of callbacks, use Koa.
If you want to get rid of callbacks, use Khoa.
As result of this different philosophy is that traditional Node.js "middleware", i.e. functions of the form `(req, res, next)`, are incompatible with Koa. Your application will essentially have to be rewritten from the ground, up.
As result of this different philosophy is that traditional Node.js "middleware", i.e. functions of the form `(req, res, next)`, are incompatible with Khoa. Your application will essentially have to be rewritten from the ground, up.
## Does Koa replace Express?
## Does Khoa replace Express?
It's more like Connect, but a lot of the Express goodies
were moved to the middleware level in Koa to help form
were moved to the middleware level in Khoa to help form
a stronger foundation. This makes middleware more enjoyable
and less error-prone to write, for the entire stack, not
just the end application code.
@@ -37,22 +37,22 @@
when features like signed cookie secrets among others are typically application-specific,
not middleware-specific.
## Does Koa replace Connect?
## Does Khoa replace Connect?
No, just a different take on similar functionality
now that generators allow us to write code with fewer
callbacks. Connect is equally capable, and some may still prefer it,
it's up to what you prefer.
## Why isn't Koa just Express 4.0?
## Why isn't Khoa just Express 4.0?
Koa is a pretty large departure from what people know about Express,
Khoa is a pretty large departure from what people know about Express,
the design is fundamentally much different, so the migration from
Express 3.0 to this Express 4.0 would effectively mean rewriting
the entire application, so we thought it would be more appropriate
to create a new library.
## How is Koa different from Connect/Express?
## How is Khoa different from Connect/Express?
### Promises-based control flow
@@ -62,21 +62,21 @@
No need for domains.
### Koa is barebones
### Khoa is barebones
Unlike both Connect and Express, Koa does not include any middleware.
Unlike both Connect and Express, Khoa does not include any middleware.
Unlike Express, routing is not provided.
Unlike Express, many convenience utilities are not provided. For example, sending files.
Koa is more modular.
Khoa is more modular.
### Koa relies less on middleware
### Khoa relies less on middleware
For example, instead of a "body parsing" middleware, you would instead use a body parsing function.
### Koa abstracts Node's request/response
### Khoa abstracts Node's request/response
Less hackery.
@@ -84,11 +84,11 @@
Proper stream handling.
### Koa routing (third party libraries support)
### Khoa routing (third party libraries support)
Since Express comes with its own routing, but Koa does not have
Since Express comes with its own routing, but Khoa does not have
any built-in routing, there are third party libraries available such as
koa-router and koa-route.
Similarly, just like we have helmet for security in Express, for Koa
we have koa-helmet available and the list goes on for Koa available third
khoa-router and khoa-route.
Similarly, just like we have helmet for security in Express, for Khoa
we have khoa-helmet available and the list goes on for Khoa available third
party libraries.

View File

@@ -1,8 +1,8 @@
# Migrating from Koa v1.x to v2.x
# Migrating from Khoa v1.x to v2.x
## New middleware signature
Koa v2 introduces a new signature for middleware.
Khoa v2 introduces a new signature for middleware.
**Old signature middleware (v1.x) support will be removed in v3**
@@ -29,15 +29,15 @@ You don't have to use asynchronous functions - you just have to pass a function
A regular function that returns a promise works too!
The signature has changed to pass `Context` via an explicit parameter, `ctx` above, instead of via
`this`. The context passing change makes Koa more compatible with es6 arrow functions, which capture `this`.
`this`. The context passing change makes Khoa more compatible with es6 arrow functions, which capture `this`.
## Using v1.x Middleware in v2.x
Koa v2.x will try to convert legacy signature, generator middleware on `app.use`, using [koa-convert](https://github.com/koajs/convert).
Khoa v2.x will try to convert legacy signature, generator middleware on `app.use`, using [khoa-convert](https://github.com/khoajs/convert).
It is however recommended that you choose to migrate all v1.x middleware as soon as possible.
```js
// Koa will convert
// Khoa will convert
app.use(function *(next) {
const start = Date.now();
yield next;
@@ -46,10 +46,10 @@ app.use(function *(next) {
});
```
You could do it manually as well, in which case Koa will not convert.
You could do it manually as well, in which case Khoa will not convert.
```js
const convert = require('koa-convert');
const convert = require('khoa-convert');
app.use(convert(function *(next) {
const start = Date.now();
@@ -73,17 +73,17 @@ app.use(async (ctx, next) => {
Upgrading your middleware may require some work. One migration path is to update them one-by-one.
1. Wrap all your current middleware in `koa-convert`
1. Wrap all your current middleware in `khoa-convert`
2. Test
3. `npm outdated` to see which Koa middleware is outdated
4. Update one outdated middleware, remove using `koa-convert`
3. `npm outdated` to see which Khoa middleware is outdated
4. Update one outdated middleware, remove using `khoa-convert`
5. Test
6. Repeat steps 3-5 until you're done
## Updating your code
You should start refactoring your code now to ease migrating to Koa v2:
You should start refactoring your code now to ease migrating to Khoa v2:
- Return promises everywhere!
- Do not use `yield*`
@@ -91,7 +91,7 @@ You should start refactoring your code now to ease migrating to Koa v2:
- Convert `yield []` into `yield Promise.all([])`
- Convert `yield {}` into `yield Bluebird.props({})`
You could also refactor your logic outside of Koa middleware functions. Create functions like
You could also refactor your logic outside of Khoa middleware functions. Create functions like
`function* someLogic(ctx) {}` and call it in your middleware as
`const result = yield someLogic(this)`.
Not using `this` will help migrations to the new middleware signature, which does not use `this`.
@@ -102,15 +102,15 @@ In v1.x, the Application constructor function could be called directly, without
instantiate an instance of an application. For example:
```js
var koa = require('koa');
var app = module.exports = koa();
var khoa = require('khoa');
var app = module.exports = khoa();
```
v2.x uses es6 classes which require the `new` keyword to be used.
```js
var koa = require('koa');
var app = module.exports = new koa();
var khoa = require('khoa');
var app = module.exports = new khoa();
```
## ENV specific logging behavior removed
@@ -119,7 +119,7 @@ An explicit check for the `test` environment was removed from error handling.
## Dependency changes
- [co](https://github.com/tj/co) is no longer bundled with Koa. Require or import it directly.
- [co](https://github.com/tj/co) is no longer bundled with Khoa. Require or import it directly.
- [composition](https://github.com/thenables/composition) is no longer used and deprecated.
## v1.x support

View File

@@ -1,20 +1,20 @@
# Migrating from Koa v2.x to v3.x
# Migrating from Khoa v2.x to v3.x
## Breaking Changes
### Node.js Version Requirement
Koa v3 requires **Node.js v18.0.0** or higher.
Khoa v3 requires **Node.js v18.0.0** or higher.
### Removal of v1.x Middleware Support
As announced in Koa v2.x, support for the old middleware signature (generator functions) has been removed in v3.
As announced in Khoa v2.x, support for the old middleware signature (generator functions) has been removed in v3.
If you were still using generator middleware with `koa-convert`, you'll need to update all middleware to use async functions or functions that return promises.
If you were still using generator middleware with `khoa-convert`, you'll need to update all middleware to use async functions or functions that return promises.
```js
// Old way (using koa-convert with generator middleware)
const convert = require('koa-convert');
// Old way (using khoa-convert with generator middleware)
const convert = require('khoa-convert');
app.use(convert(function* (next) {
const data = yield fetchData();
@@ -32,13 +32,13 @@ app.use(async (ctx, next) => {
### HTTP Errors Update
Koa v3 updates `http-errors` to v2.0.0, which changes the signature of `ctx.throw()`:
Khoa v3 updates `http-errors` to v2.0.0, which changes the signature of `ctx.throw()`:
```js
// Old format in Koa v2.x
// Old format in Khoa v2.x
ctx.throw(status, message, properties)
// New format in Koa v3.x
// New format in Khoa v3.x
ctx.throw(status, error, properties)
```
@@ -49,10 +49,10 @@ See the [http-errors documentation](https://www.npmjs.com/package/http-errors) f
The `res.redirect('back')` method has been removed. Instead, use the new `ctx.back()` method:
```js
// Old way in Koa v2.x
// Old way in Khoa v2.x
ctx.response.redirect('back')
// New way in Koa v3.x
// New way in Khoa v3.x
ctx.back()
```
@@ -61,7 +61,7 @@ ctx.back()
Node's querystring module has been replaced with `URLSearchParams`. This should be mostly transparent to users, but might cause subtle differences in query string parsing.
```js
// Old way (Koa v2.x using querystring)
// Old way (Khoa v2.x using querystring)
const qs = require('querystring');
app.use(async (ctx, next) => {
const query = qs.parse(ctx.querystring);
@@ -70,7 +70,7 @@ app.use(async (ctx, next) => {
await next();
});
// New way (Koa v3.x using URLSearchParams)
// New way (Khoa v3.x using URLSearchParams)
app.use(async (ctx, next) => {
const query = new URLSearchParams(ctx.querystring);
// query.getAll('user') => ['john', 'jane']
@@ -83,11 +83,11 @@ app.use(async (ctx, next) => {
### AsyncLocalStorage Support
Koa v3 adds support for [AsyncLocalStorage](https://nodejs.org/api/async_context.html#class-asynclocalstorage), which allows you to access the current context from anywhere in your application:
Khoa v3 adds support for [AsyncLocalStorage](https://nodejs.org/api/async_context.html#class-asynclocalstorage), which allows you to access the current context from anywhere in your application:
```js
// Enable AsyncLocalStorage
const app = new Koa({ asyncLocalStorage: true })
const app = new Khoa({ asyncLocalStorage: true })
app.use(async (ctx, next) => {
callSomeFunction()
@@ -106,7 +106,7 @@ You can also pass your own AsyncLocalStorage instance:
```js
const { AsyncLocalStorage } = require('async_hooks')
const asyncLocalStorage = new AsyncLocalStorage()
const app = new Koa({ asyncLocalStorage })
const app = new Khoa({ asyncLocalStorage })
app.use(async (ctx, next) => {
callSomeFunction()
@@ -122,7 +122,7 @@ function callSomeFunction() {
### Web WHATWG Support
Koa v3 adds support for [Web WHATWG standards](https://spec.whatwg.org/), including:
Khoa v3 adds support for [Web WHATWG standards](https://spec.whatwg.org/), including:
- Support for `Blob` objects as response bodies
- Support for `ReadableStream` objects as response bodies
@@ -173,10 +173,10 @@ app.use(async ctx => {
3. Update any calls to `ctx.throw()` to use the new signature:
```js
// Old way (Koa v2.x)
// Old way (Khoa v2.x)
ctx.throw(404, 'User not found', { user: 'john' });
// New way (Koa v3.x)
// New way (Khoa v3.x)
const error = new Error('User not found');
ctx.throw(404, error, { user: 'john' });

View File

@@ -1,17 +1,17 @@
# Troubleshooting Koa
# Troubleshooting Khoa
- [Whenever I try to access my route, it sends back a 404](#whenever-i-try-to-access-my-route-it-sends-back-a-404)
- [My response or context changes have no effect](#my-response-or-context-changes-have-no-effect)
- [My middleware is not called](#my-middleware-is-not-called)
See also [debugging Koa](guide.md#debugging-koa).
See also [debugging Khoa](guide.md#debugging-khoa).
If you encounter a problem and later learn how to fix it, and think others might also encounter that problem, please
consider contributing to this documentation.
## Whenever I try to access my route, it sends back a 404
This is a common but troublesome problem when working with Koa middleware. First, it is critical to understand when Koa generates a 404. Koa does not care which or how much middleware was run, in many cases a 200 and 404 trigger the same number of middleware. Instead, the default status for any response is 404. The most obvious way this is changed is through `ctx.status`. However, if `ctx.body` is set when the status has not been explicitly defined (through `ctx.status`), the status is set to 200. This explains why simply setting the body results in a 200. Once the middleware is done (when the middleware and any returned promises are complete), Koa sends out the response. After that, nothing can alter the response. If it was a 404 at the time, it will be a 404 at the end, even if `ctx.status` or `ctx.body` are set afterward.
This is a common but troublesome problem when working with Khoa middleware. First, it is critical to understand when Khoa generates a 404. Khoa does not care which or how much middleware was run, in many cases a 200 and 404 trigger the same number of middleware. Instead, the default status for any response is 404. The most obvious way this is changed is through `ctx.status`. However, if `ctx.body` is set when the status has not been explicitly defined (through `ctx.status`), the status is set to 200. This explains why simply setting the body results in a 200. Once the middleware is done (when the middleware and any returned promises are complete), Khoa sends out the response. After that, nothing can alter the response. If it was a 404 at the time, it will be a 404 at the end, even if `ctx.status` or `ctx.body` are set afterward.
Even though we now understand the basis of a 404, it might not be as clear why a 404 is generated in a specific case. This can be especially troublesome when it seems that `ctx.status` or `ctx.body` are set.
@@ -50,7 +50,7 @@ router.get('/fetch', async (ctx, next) => {
### Cause
`ctx.body` is not set until *after* the response has been sent. The code doesn't tell Koa to wait for the database to return the record. Koa sends the response after the middleware has been run, but not after the callback inside the middleware has been run. In the gap there, `ctx.body` has not yet been set, so Koa responds with a 404.
`ctx.body` is not set until *after* the response has been sent. The code doesn't tell Khoa to wait for the database to return the record. Khoa sends the response after the middleware has been run, but not after the callback inside the middleware has been run. In the gap there, `ctx.body` has not yet been set, so Khoa responds with a 404.
### Identifying this as the issue
@@ -90,7 +90,7 @@ router.get('/fetch', function (ctx, next) {
});
```
Returning the promise given by the database interface tells Koa to wait for the promise to finish before responding. At that time, the body will have been set. This results in Koa sending back a 200 with a proper response.
Returning the promise given by the database interface tells Khoa to wait for the promise to finish before responding. At that time, the body will have been set. This results in Khoa sending back a 200 with a proper response.
The fix in the `async` version is to add an `await` statement:

View File

@@ -5,14 +5,14 @@
*/
const util = require('node:util')
const v8 = require('node:v8')
const debug = util.debuglog('koa:application')
const debug = util.debuglog('khoa:application')
const Emitter = require('node:events')
const Stream = require('node:stream')
const http = require('node:http')
const { AsyncLocalStorage } = require('node:async_hooks')
const onFinished = require('on-finished')
const compose = require('koa-compose')
const compose = require('khoa-compose')
const statuses = require('statuses')
const { HttpError } = require('http-errors')
@@ -237,7 +237,7 @@ module.exports = class Application extends Emitter {
onerror (err) {
// When dealing with cross-globals a normal `instanceof` check doesn't work properly.
// See https://github.com/koajs/koa/issues/1466
// See https://github.com/khoajs/khoa/issues/1466
// We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
const isNativeError =
Object.prototype.toString.call(err) === '[object Error]' ||
@@ -253,7 +253,7 @@ module.exports = class Application extends Emitter {
/**
* Help TS users comply to CommonJS, ESM, bundler mismatch.
* @see https://github.com/koajs/koa/issues/1513
* @see https://github.com/khoajs/khoa/issues/1513
*/
static get default () {
@@ -266,7 +266,7 @@ module.exports = class Application extends Emitter {
*/
function respond (ctx) {
// allow bypassing koa
// allow bypassing khoa
if (ctx.respond === false) return
const res = ctx.res

View File

@@ -110,7 +110,7 @@ const proto = module.exports = {
if (err == null) return
// When dealing with cross-globals a normal `instanceof` check doesn't work properly.
// See https://github.com/koajs/koa/issues/1466
// See https://github.com/khoajs/khoa/issues/1466
// We can probably remove it once jest fixes https://github.com/facebook/jest/issues/2549.
const isNativeError =
Object.prototype.toString.call(err) === '[object Error]' ||

10
package-lock.json generated
View File

@@ -1,11 +1,11 @@
{
"name": "koa",
"name": "khoa",
"version": "3.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "koa",
"name": "khoa",
"version": "3.2.0",
"license": "MIT",
"dependencies": {
@@ -20,7 +20,7 @@
"fresh": "~0.5.2",
"http-assert": "^1.5.0",
"http-errors": "^2.0.0",
"koa-compose": "^4.1.0",
"khoa-compose": "^4.1.0",
"mime-types": "^3.0.1",
"on-finished": "^2.4.1",
"parseurl": "^1.3.3",
@@ -3222,9 +3222,9 @@
"json-buffer": "3.0.1"
}
},
"node_modules/koa-compose": {
"node_modules/khoa-compose": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/koa-compose/-/koa-compose-4.1.0.tgz",
"resolved": "https://registry.npmjs.org/khoa-compose/-/khoa-compose-4.1.0.tgz",
"integrity": "sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw==",
"license": "MIT"
},

View File

@@ -1,13 +1,13 @@
{
"name": "koa",
"name": "khoa",
"version": "3.2.0",
"description": "Koa web app framework",
"description": "Khoa web app framework",
"main": "lib/application.js",
"exports": {
".": {
"require": "./lib/application.js",
"import": "./dist/koa.mjs",
"default": "./dist/koa.mjs"
"import": "./dist/khoa.mjs",
"default": "./dist/khoa.mjs"
},
"./*": "./*.js",
"./*.js": "./*.js",
@@ -21,10 +21,10 @@
"lint:fix": "standard --fix",
"lint:pretty": "standard | snazzy",
"authors": "git log --format='%aN <%aE>' | sort -u > AUTHORS",
"build": "gen-esm-wrapper . ./dist/koa.mjs",
"build": "gen-esm-wrapper . ./dist/khoa.mjs",
"prepare": "npm run build"
},
"repository": "koajs/koa",
"repository": "khoajs/khoa",
"keywords": [
"web",
"app",
@@ -47,7 +47,7 @@
"fresh": "~0.5.2",
"http-assert": "^1.5.0",
"http-errors": "^2.0.0",
"koa-compose": "^4.1.0",
"khoa-compose": "^4.1.0",
"mime-types": "^3.0.1",
"on-finished": "^2.4.1",
"parseurl": "^1.3.3",
@@ -69,5 +69,5 @@
"dist",
"lib"
],
"homepage": "https://koajs.com"
"homepage": "https://khoajs.com"
}