@eggjs/router
Version:
Router middleware for egg/koa. Provides RESTful resource routing.
495 lines (494 loc) • 20.9 kB
TypeScript
/**
* RESTful resource routing middleware for eggjs.
*/
import methods from 'methods';
import { Layer, LayerURLOptions } from './Layer.js';
import { MiddlewareFunc, MiddlewareFuncWithRouter, ParamMiddlewareFunc, ResourcesController } from './types.js';
export type RouterMethod = typeof methods[0];
export interface RouterOptions {
methods?: string[];
prefix?: string;
sensitive?: boolean;
strict?: boolean;
routerPath?: string;
}
export interface RegisterOptions {
name?: string;
prefix?: string;
sensitive?: boolean;
strict?: boolean;
ignoreCaptures?: boolean;
end?: boolean;
}
export interface AllowedMethodsOptions {
throw?: boolean;
notImplemented?: () => Error;
methodNotAllowed?: () => Error;
}
export interface MatchedResult {
path: Layer[];
pathAndMethod: Layer[];
route: boolean;
}
export declare class Router {
#private;
readonly opts: RouterOptions;
readonly methods: string[];
/** Layer stack */
readonly stack: Layer[];
readonly params: Record<string, ParamMiddlewareFunc>;
/**
* Create a new router.
*
* @example
*
* Basic usage:
*
* ```javascript
* var Koa = require('koa');
* var Router = require('koa-router');
*
* var app = new Koa();
* var router = new Router();
*
* router.get('/', (ctx, next) => {
* // ctx.router available
* });
*
* app
* .use(router.routes())
* .use(router.allowedMethods());
* ```
*
* @alias module:koa-router
* @param {Object=} opts optional
* @param {String=} opts.prefix prefix router paths
* @class
*/
constructor(opts?: RouterOptions);
/**
* Use given middleware.
*
* Middleware run in the order they are defined by `.use()`. They are invoked
* sequentially, requests start at the first middleware and work their way
* "down" the middleware stack.
*
* @example
*
* ```javascript
* // session middleware will run before authorize
* router
* .use(session())
* .use(authorize());
*
* // use middleware only with given path
* router.use('/users', userAuth());
*
* // or with an array of paths
* router.use(['/users', '/admin'], userAuth());
*
* app.use(router.routes());
* ```
*
* @param {String=} path path string
* @param {Function} middleware middleware function
* @return {Router} router instance
*/
use(...middlewares: MiddlewareFunc[]): Router;
use(path: string | string[], ...middlewares: MiddlewareFunc[]): Router;
/**
* Set the path prefix for a Router instance that was already initialized.
*
* @example
*
* ```javascript
* router.prefix('/things/:thing_id')
* ```
*
* @param {String} prefix prefix string
* @return {Router} router instance
*/
prefix(prefix: string): Router;
/**
* Returns router middleware which dispatches a route matching the request.
*
* @return {Function} middleware function
*/
routes(): MiddlewareFuncWithRouter<Router>;
/**
* @alias to routes()
*/
middleware(): MiddlewareFuncWithRouter<Router>;
/**
* Returns separate middleware for responding to `OPTIONS` requests with
* an `Allow` header containing the allowed methods, as well as responding
* with `405 Method Not Allowed` and `501 Not Implemented` as appropriate.
*
* @example
*
* ```javascript
* var Koa = require('koa');
* var Router = require('koa-router');
*
* var app = new Koa();
* var router = new Router();
*
* app.use(router.routes());
* app.use(router.allowedMethods());
* ```
*
* **Example with [Boom](https://github.com/hapijs/boom)**
*
* ```javascript
* var Koa = require('koa');
* var Router = require('koa-router');
* var Boom = require('boom');
*
* var app = new Koa();
* var router = new Router();
*
* app.use(router.routes());
* app.use(router.allowedMethods({
* throw: true,
* notImplemented: () => new Boom.notImplemented(),
* methodNotAllowed: () => new Boom.methodNotAllowed()
* }));
* ```
*
* @param {Object=} options optional params
* @param {Boolean=} options.throw throw error instead of setting status and header
* @param {Function=} options.notImplemented throw the returned value in place of the default NotImplemented error
* @param {Function=} options.methodNotAllowed throw the returned value in place of the default MethodNotAllowed error
* @return {Function} middleware function
*/
allowedMethods(options?: AllowedMethodsOptions): MiddlewareFunc;
/**
* Redirect `source` to `destination` URL with optional 30x status `code`.
*
* Both `source` and `destination` can be route names.
*
* ```javascript
* router.redirect('/login', 'sign-in');
* ```
*
* This is equivalent to:
*
* ```javascript
* router.all('/login', ctx => {
* ctx.redirect('/sign-in');
* ctx.status = 301;
* });
* ```
*
* @param {String} source URL or route name.
* @param {String} destination URL or route name.
* @param {Number=} status HTTP status code (default: 301).
* @return {Router} router instance
*/
redirect(source: string, destination: string, status?: number): Router;
/**
* Create and register a route.
*
* @param {String|RegExp|(String|RegExp)[]} path Path string.
* @param {String[]} methods Array of HTTP verbs.
* @param {Function|Function[]} middleware Multiple middleware also accepted.
* @param {Object} [opts] optional params
* @private
*/
register(path: string | RegExp | (string | RegExp)[], methods: string[], middleware: MiddlewareFunc | MiddlewareFunc[], opts?: RegisterOptions): Layer | Layer[];
/**
* Lookup route with given `name`.
*
* @param {String} name route name
* @return {Layer|false} layer instance of false
*/
route(name: string): Layer | false;
/**
* Generate URL for route. Takes a route name and map of named `params`.
*
* @example
*
* ```javascript
* router.get('user', '/users/:id', (ctx, next) => {
* // ...
* });
*
* router.url('user', 3);
* // => "/users/3"
*
* router.url('user', { id: 3 });
* // => "/users/3"
*
* router.use((ctx, next) => {
* // redirect to named route
* ctx.redirect(ctx.router.url('sign-in'));
* })
*
* router.url('user', { id: 3 }, { query: { limit: 1 } });
* // => "/users/3?limit=1"
*
* router.url('user', { id: 3 }, { query: "limit=1" });
* // => "/users/3?limit=1"
* ```
*/
url(name: string, params?: string | number | object, ...paramsOrOptions: (string | number | object | LayerURLOptions)[]): string | Error;
/**
* Generate URL from url pattern and given `params`.
*
* @example
*
* ```javascript
* var url = Router.url('/users/:id', { id: 1 });
* // => "/users/1"
* ```
*
* @param {String} path url pattern
* @param {Object} params url parameters
* @return {String} url string
*/
static url(path: string, params?: string | number | object, ...paramsOrOptions: (string | number | object | LayerURLOptions)[]): string;
/**
* Match given `path` and return corresponding routes.
*
* @param {String} path path string
* @param {String} method method name
* @return {Object.<path, pathAndMethod>} returns layers that matched path and
* path and method.
* @private
*/
match(path: string, method: string): MatchedResult;
/**
* Run middleware for named route parameters. Useful for auto-loading or
* validation.
*
* @example
*
* ```javascript
* router
* .param('user', (id, ctx, next) => {
* ctx.user = users[id];
* if (!ctx.user) return ctx.status = 404;
* return next();
* })
* .get('/users/:user', ctx => {
* ctx.body = ctx.user;
* })
* .get('/users/:user/friends', ctx => {
* return ctx.user.getFriends().then(function(friends) {
* ctx.body = friends;
* });
* })
* // /users/3 => {"id": 3, "name": "Alex"}
* // /users/3/friends => [{"id": 4, "name": "TJ"}]
* ```
*
* @param {String} param param
* @param {Function} middleware route middleware
* @return {Router} instance
*/
param(param: string, middleware: ParamMiddlewareFunc): Router;
protected _formatRouteParams(nameOrPath: string | RegExp | (string | RegExp)[], pathOrMiddleware: string | RegExp | (string | RegExp)[] | MiddlewareFunc | ResourcesController, middlewares: (MiddlewareFunc | string | ResourcesController)[]): {
path: string | RegExp | (string | RegExp)[];
middlewares: (string | MiddlewareFunc | ResourcesController)[];
options: RegisterOptions;
};
/**
* Create `router.verb()` methods, where *verb* is one of the HTTP verbs such
* as `router.get()` or `router.post()`.
*
* Match URL patterns to callback functions or controller actions using `router.verb()`,
* where **verb** is one of the HTTP verbs such as `router.get()` or `router.post()`.
*
* Additionally, `router.all()` can be used to match against all methods.
*
* ```javascript
* router
* .get('/', (ctx, next) => {
* ctx.body = 'Hello World!';
* })
* .post('/users', (ctx, next) => {
* // ...
* })
* .put('/users/:id', (ctx, next) => {
* // ...
* })
* .del('/users/:id', (ctx, next) => {
* // ...
* })
* .all('/users/:id', (ctx, next) => {
* // ...
* });
* ```
*
* When a route is matched, its path is available at `ctx._matchedRoute` and if named,
* the name is available at `ctx._matchedRouteName`
*
* Route paths will be translated to regular expressions using
* [path-to-regexp](https://github.com/pillarjs/path-to-regexp).
*
* Query strings will not be considered when matching requests.
*
* #### Named routes
*
* Routes can optionally have names. This allows generation of URLs and easy
* renaming of URLs during development.
*
* ```javascript
* router.get('user', '/users/:id', (ctx, next) => {
* // ...
* });
*
* router.url('user', 3);
* // => "/users/3"
* ```
*
* #### Multiple middleware
*
* Multiple middleware may be given:
*
* ```javascript
* router.get(
* '/users/:id',
* (ctx, next) => {
* return User.findOne(ctx.params.id).then(function(user) {
* ctx.user = user;
* next();
* });
* },
* ctx => {
* console.log(ctx.user);
* // => { id: 17, name: "Alex" }
* }
* );
* ```
*
* ### Nested routers
*
* Nesting routers is supported:
*
* ```javascript
* var forums = new Router();
* var posts = new Router();
*
* posts.get('/', (ctx, next) => {...});
* posts.get('/:pid', (ctx, next) => {...});
* forums.use('/forums/:fid/posts', posts.routes(), posts.allowedMethods());
*
* // responds to "/forums/123/posts" and "/forums/123/posts/123"
* app.use(forums.routes());
* ```
*
* #### Router prefixes
*
* Route paths can be prefixed at the router level:
*
* ```javascript
* var router = new Router({
* prefix: '/users'
* });
*
* router.get('/', ...); // responds to "/users"
* router.get('/:id', ...); // responds to "/users/:id"
* ```
*
* #### URL parameters
*
* Named route parameters are captured and added to `ctx.params`.
*
* ```javascript
* router.get('/:category/:title', (ctx, next) => {
* console.log(ctx.params);
* // => { category: 'programming', title: 'how-to-node' }
* });
* ```
*
* The [path-to-regexp](https://github.com/pillarjs/path-to-regexp) module is
* used to convert paths to regular expressions.
*
*/
verb(method: string | string[], nameOrPath: string | RegExp | (string | RegExp)[], pathOrMiddleware: string | RegExp | (string | RegExp)[] | MiddlewareFunc, ...middleware: MiddlewareFunc[]): Router;
/**
* Register route with all methods.
*
* @param {String} name Optional.
* @param {String} path path string
* @param {Function=} middleware You may also pass multiple middleware.
* @return {Router} router instance
* @private
*/
all(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
all(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
acl(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
acl(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
bind(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
bind(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
checkout(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
checkout(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
connect(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
connect(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
copy(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
copy(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
delete(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
delete(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
/** Alias for `router.delete()` because delete is a reserved word */
del(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
del(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
get(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
get(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
query(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
query(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
head(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
head(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
link(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
link(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
lock(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
lock(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
['m-search'](path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
['m-search'](name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
merge(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
merge(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
mkactivity(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
mkactivity(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
mkcalendar(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
mkcalendar(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
mkcol(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
mkcol(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
move(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
move(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
notify(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
notify(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
options(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
options(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
patch(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
patch(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
post(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
post(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
propfind(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
propfind(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
proppatch(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
proppatch(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
purge(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
purge(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
put(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
put(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
rebind(path: string | RegExp, ...middlewares: MiddlewareFunc[]): Router;
rebind(name: string, path: string | RegExp, ...middlewares: MiddlewareFunc[]): Router;
report(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
report(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
search(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
search(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
source(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
source(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
subscribe(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
subscribe(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
trace(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
trace(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
unbind(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
unbind(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
unlink(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
unlink(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
unlock(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
unlock(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
unsubscribe(path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
unsubscribe(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: MiddlewareFunc[]): Router;
}