first commit

This commit is contained in:
2026-09-08 20:28:54 +08:00
commit 2ada8d3d5a
37380 changed files with 4886169 additions and 0 deletions
+127
View File
@@ -0,0 +1,127 @@
# koa-mount
Mount other Koa applications as middleware. The `path` passed to `mount()` is stripped
from the URL temporarily until the stack unwinds. This is useful for creating entire
apps or middleware that will function correctly regardless of which path segment(s)
they should operate on.
## Installation
```js
$ npm install koa-mount
```
## Examples
View the [./examples](examples) directory for working examples.
### Mounting Applications
Entire applications mounted at specific paths. For example you could mount
a blog application at "/blog", with a router that matches paths such as
"GET /", "GET /posts", and will behave properly for "GET /blog/posts" etc
when mounted.
```js
const mount = require('koa-mount');
const Koa = require('koa');
// hello
const a = new Koa();
a.use(async function (ctx, next){
await next();
ctx.body = 'Hello';
});
// world
const b = new Koa();
b.use(async function (ctx, next){
await next();
ctx.body = 'World';
});
// app
const app = new Koa();
app.use(mount('/hello', a));
app.use(mount('/world', b));
app.listen(3000);
console.log('listening on port 3000');
```
Try the following requests:
```
$ GET /
Not Found
$ GET /hello
Hello
$ GET /world
World
```
### Mounting Middleware
Mount middleware at specific paths, allowing them to operate independently
of the prefix, as they're not aware of it.
```js
const mount = require('koa-mount');
const Koa = require('koa');
async function hello(ctx, next){
await next();
ctx.body = 'Hello';
}
async function world(ctx, next){
await next();
ctx.body = 'World';
}
const app = new Koa();
app.use(mount('/hello', hello));
app.use(mount('/world', world));
app.listen(3000);
console.log('listening on port 3000');
```
### Optional Paths
The path argument is optional, defaulting to "/":
```js
app.use(mount(a));
app.use(mount(b));
```
## Debugging
Use the __DEBUG__ environement variable to whitelist
koa-mount debug output:
```
$ DEBUG=koa-mount node myapp.js &
$ GET /foo/bar/baz
koa-mount enter /foo/bar/baz -> /bar/baz +2s
koa-mount enter /bar/baz -> /baz +0ms
koa-mount enter /baz -> / +0ms
koa-mount leave /baz -> / +1ms
koa-mount leave /bar/baz -> /baz +0ms
koa-mount leave /foo/bar/baz -> /bar/baz +0ms
```
## License
MIT
+99
View File
@@ -0,0 +1,99 @@
/**
* Module dependencies.
*/
const debug = require('debug')('koa-mount')
const compose = require('koa-compose')
const assert = require('assert')
/**
* Expose `mount()`.
*/
module.exports = mount
/**
* Mount `app` with `prefix`, `app`
* may be a Koa application or
* middleware function.
*
* @param {String|Application|Function} prefix, app, or function
* @param {Application|Function} [app or function]
* @return {Function}
* @api public
*/
function mount (prefix, app) {
if (typeof prefix !== 'string') {
app = prefix
prefix = '/'
}
assert.equal(prefix[0], '/', 'mount path must begin with "/"')
// compose
let downstream = app
if (Array.isArray(app)) {
downstream = compose(app)
} else if (app.middleware) {
downstream = compose(app.middleware)
}
// don't need to do mounting here
if (prefix === '/') return downstream
const trailingSlash = prefix.slice(-1) === '/'
const name = app.name || 'unnamed'
debug('mount %s %s', prefix, name)
return async function (ctx, upstream) {
const prev = ctx.path
const newPath = match(prev)
debug('mount %s %s -> %s', prefix, name, newPath)
if (!newPath) return await upstream()
ctx.mountPath = prefix
ctx.path = newPath
debug('enter %s -> %s', prev, ctx.path)
try {
await downstream(ctx, async () => {
ctx.path = prev
await upstream()
ctx.path = newPath
})
} finally {
debug('leave %s -> %s', prev, ctx.path)
ctx.path = prev
}
}
/**
* Check if `prefix` satisfies a `path`.
* Returns the new path.
*
* match('/images/', '/lkajsldkjf') => false
* match('/images', '/images') => /
* match('/images/', '/images') => false
* match('/images/', '/images/asdf') => /asdf
*
* @param {String} prefix
* @param {String} path
* @return {String|Boolean}
* @api private
*/
function match (path) {
// does not match prefix at all
if (path.indexOf(prefix) !== 0) return false
const newPath = path.replace(prefix, '') || '/'
if (trailingSlash) return newPath
// `/mount` does not match `/mountlkjalskjdf`
if (newPath[0] !== '/') return false
return newPath
}
}
+41
View File
@@ -0,0 +1,41 @@
{
"name": "koa-mount",
"description": "Mounting middleware for koa",
"repository": "koajs/mount",
"version": "4.2.0",
"keywords": [
"koa",
"middleware",
"mount",
"mounting"
],
"files": [
"index.js"
],
"devDependencies": {
"eslint": "^7.32.0",
"eslint-config-standard": "^7.1.0",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^5.0.0",
"istanbul": "^0.4.5",
"koa": "^2.0.1",
"koa-static": "^5.0.0",
"mocha": "^9.1.1",
"should": "^11.2.0",
"supertest": "^6.1.6"
},
"license": "MIT",
"dependencies": {
"debug": "^4.0.1",
"koa-compose": "^4.1.0"
},
"scripts": {
"lint": "eslint --fix .",
"test": "NODE_ENV=test mocha --reporter spec",
"test-cov": "NODE_ENV=test istanbul cover ./node_modules/.bin/_mocha",
"test-travis": "NODE_ENV=test istanbul cover ./node_modules/.bin/_mocha --report lcovonly"
},
"engines": {
"node": ">= 7.6.0"
}
}