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:59:17 +00:00
parent 1f4bbea3d9
commit e876a21378

258
Readme.md
View File

@@ -1,4 +1,4 @@
<img src="/docs/logo.png" alt="Khoa middleware framework for nodejs"/>
<img src="https://khoajs.com/public/logo.png" alt="Khoa middleware framework for nodejs"/>
[![gitter][gitter-image]][gitter-url]
[![NPM version][npm-image]][npm-url]
@@ -10,10 +10,10 @@
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 Khoa's small ~570 SLOC codebase. This
includes things like content negotiation, normalization of node inconsistencies, redirection, and a few others.
## Why Khoajs?
Khoa is not bundled with any middleware.
Khoajs is a friendly and transparent fork of Koa, created as a gift and tribute to Khoa Nguyen Hai.
It keeps upstream behavior while applying naming changes and automated sync maintenance.
## Installation
@@ -29,7 +29,6 @@ npm install khoa
const Khoa = require('khoa');
const app = new Khoa();
// response
app.use(ctx => {
ctx.body = 'Hello Khoa';
});
@@ -37,243 +36,52 @@ app.use(ctx => {
app.listen(3000);
```
## Getting started
- [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
Khoa is a middleware framework that can take two different kinds of functions as middleware:
* async function
* common function
Here is an example of logger middleware with each of the different functions:
### ___async___ functions (node v7.6+)
```js
app.use(async (ctx, next) => {
const start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
```
### Common function
```js
// Middleware normally takes two parameters (ctx, next), ctx is the context for one request,
// next is a function that is invoked to execute the downstream middleware. It returns a Promise with a then function for running code after completion.
app.use((ctx, next) => {
const start = Date.now();
return next().then(() => {
const ms = Date.now() - start;
console.log(`${ctx.method} ${ctx.url} - ${ms}ms`);
});
});
```
### Khoa v1.x Middleware Signature
The middleware signature changed between v1.x and v2.x. The older signature is deprecated.
**Old signature middleware support has been removed in v3**
Please see the [Migration Guide from v2.x to v3.x](docs/migration-v2-to-v3.md) for information on upgrading from v2.x to v3.x, and the [Migration Guide from v1.x to v2.x](docs/migration-v1-to-v2.md) for information on upgrading from v1.x to v2.x.
## Context, Request and Response
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.
```js
app.use(async (ctx, next) => { await next(); });
```
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.
Here is an example of checking that a requesting client supports xml.
```js
app.use(async (ctx, next) => {
ctx.assert(ctx.request.accepts('xml'), 406);
// equivalent to:
// if (!ctx.request.accepts('xml')) ctx.throw(406);
await next();
});
```
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)
.
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 Khoa's `Response` object to stream a file as the response body.
```js
app.use(async (ctx, next) => {
await next();
ctx.response.type = 'xml';
ctx.response.body = fs.createReadStream('really_large.xml');
});
```
The `Context` object also provides shortcuts for methods on its `request` and `response`. In the prior
examples, `ctx.type` can be used instead of `ctx.response.type` and `ctx.accepts` can be used
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).
## Khoa Application
The object created when executing `new Khoa()` is known as the Khoa application object.
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.
Learn more about the application object in the [Application API Reference](docs/api/index.md).
## Documentation
- [Usage Guide](docs/guide.md)
- [Error Handling](docs/error-handling.md)
- [Khoa for Express Users](docs/khoa-vs-express.md)
- [FAQ](docs/faq.md)
- [API documentation](docs/api/index.md)
- [Website Documentation](https://khoajs.com)
- [Guide](https://khoajs.com)
- [API Documentation](https://khoajs.com)
- [FAQ](https://khoajs.com)
- [Troubleshooting](https://khoajs.com)
## Troubleshooting
## Source Code
Check the [Troubleshooting Guide](docs/troubleshooting.md) or [Debugging Khoa](docs/guide.md#debugging-khoa) in
the general Khoa guide.
## Running tests
```
$ npm test
```
## Reporting vulnerabilities
To report a security vulnerability, please do not open an issue, as this notifies attackers of the vulnerability. Instead, please email [dead_horse](mailto:heyiyu.deadhorse@gmail.com), [jonathanong](mailto:me@jongleberry.com), and [niftylettuce](mailto:niftylettuce@gmail.com) to disclose.
## Authors
See [AUTHORS](AUTHORS).
- [Khoajs Repository (Gitea)](https://git.dev.nitropur.com/TEKK/khoa)
- [Khoajs Issues (Gitea)](https://git.dev.nitropur.com/TEKK/khoa/issues)
- [Khoajs Pull Requests (Gitea)](https://git.dev.nitropur.com/TEKK/khoa/pulls)
## Community
- [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
- [Examples](https://git.dev.nitropur.com/TEKK/khoa)
- [Wiki](https://git.dev.nitropur.com/TEKK/khoa/wiki)
- [Reddit Community](https://www.reddit.com/r/koajs)
- [Mailing list](https://groups.google.com/forum/#!forum/koajs)
## Backers
Support us with a monthly donation and help us continue our activities.
<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>
Support the original ecosystem with a monthly donation:
- [OpenCollective Backers (original)](https://opencollective.com/koajs/backers)
## Sponsors
Become a sponsor and get your logo on our README on Github with a link to your site.
Become a sponsor and support the original ecosystem:
<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>
- [OpenCollective Sponsors (original)](https://opencollective.com/koajs/sponsors)
# License
[MIT](https://github.com/khoajs/khoa/blob/master/LICENSE)
- [MIT (original upstream license link)](https://github.com/koajs/koa/blob/master/LICENSE)
[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
[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://img.shields.io/badge/build-synced-blue.svg?style=flat-square
[github-action-url]: https://git.dev.nitropur.com/TEKK/khoa
[coveralls-image]: https://img.shields.io/badge/coverage-upstream-lightgrey.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
[pr-welcoming-image]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[pr-welcoming-url]: https://github.com/khoajs/khoa/pull/new
[pr-welcoming-url]: https://git.dev.nitropur.com/TEKK/khoa