@eggjs/router
Advanced tools
+104
-101
@@ -1,105 +0,108 @@ | ||
| import { Layer } from './Layer.ts'; | ||
| import { type RegisterOptions, Router, type RouterMethod, type RouterOptions } from './Router.ts'; | ||
| import { type MiddlewareFunc, type ResourcesController } from './types.ts'; | ||
| import { MiddlewareFunc, ResourcesController } from "./types.js"; | ||
| import { Layer } from "./Layer.js"; | ||
| import { RegisterOptions, Router, RouterMethod, RouterOptions } from "./Router.js"; | ||
| //#region src/EggRouter.d.ts | ||
| interface Application { | ||
| controller: Record<string, any>; | ||
| controller: Record<string, any>; | ||
| } | ||
| /** | ||
| * FIXME: move these patch into @eggjs/router | ||
| */ | ||
| export declare class EggRouter extends Router { | ||
| readonly app: Application; | ||
| /** | ||
| * @class | ||
| * @param {Object} opts - Router options. | ||
| * @param {Application} app - Application object. | ||
| */ | ||
| constructor(opts: RouterOptions, app: Application); | ||
| verb(method: RouterMethod | RouterMethod[], nameOrPath: string | RegExp | (string | RegExp)[], pathOrMiddleware: string | RegExp | (string | RegExp)[] | MiddlewareFunc, ...middleware: (MiddlewareFunc | string)[]): Router; | ||
| head(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| head(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| options(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| options(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| get(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| get(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| put(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| put(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| patch(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| patch(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| post(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| post(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| delete(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| delete(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| all(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| all(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| register(path: string | RegExp | (string | RegExp)[], methods: string[], middleware: MiddlewareFunc | string | (MiddlewareFunc | string | ResourcesController)[], opts?: RegisterOptions): Layer | Layer[]; | ||
| /** | ||
| * restful router api | ||
| * @param {String} name - Router name | ||
| * @param {String} prefix - url prefix | ||
| * @param {Function} middleware - middleware or controller | ||
| * @example | ||
| * ```js | ||
| * app.resources('/posts', 'posts') | ||
| * app.resources('posts', '/posts', 'posts') | ||
| * app.resources('posts', '/posts', app.role.can('user'), app.controller.posts) | ||
| * app.resources('posts', '/posts', middleware1, middleware2, app.controller.posts) | ||
| * ``` | ||
| * | ||
| * Examples: | ||
| * | ||
| * ```js | ||
| * app.resources('/posts', 'posts') | ||
| * ``` | ||
| * | ||
| * yield router mapping | ||
| * | ||
| * Method | Path | Route Name | Controller.Action | ||
| * -------|-----------------|----------------|----------------------------- | ||
| * GET | /posts | posts | app.controller.posts.index | ||
| * GET | /posts/new | new_post | app.controller.posts.new | ||
| * GET | /posts/:id | post | app.controller.posts.show | ||
| * GET | /posts/:id/edit | edit_post | app.controller.posts.edit | ||
| * POST | /posts | posts | app.controller.posts.create | ||
| * PATCH | /posts/:id | post | app.controller.posts.update | ||
| * DELETE | /posts/:id | post | app.controller.posts.destroy | ||
| * | ||
| * app.router.url can generate url based on arguments | ||
| * ```js | ||
| * app.router.url('posts') | ||
| * => /posts | ||
| * app.router.url('post', { id: 1 }) | ||
| * => /posts/1 | ||
| * app.router.url('new_post') | ||
| * => /posts/new | ||
| * app.router.url('edit_post', { id: 1 }) | ||
| * => /posts/1/edit | ||
| * ``` | ||
| * @return {Router} return route object. | ||
| * @since 1.0.0 | ||
| */ | ||
| resources(prefix: string, controller: string | ResourcesController): Router; | ||
| resources(prefix: string, middleware: MiddlewareFunc, controller: string | ResourcesController): Router; | ||
| resources(name: string, prefix: string, controller: string | ResourcesController): Router; | ||
| resources(name: string, prefix: string, middleware: MiddlewareFunc, controller: string | ResourcesController): Router; | ||
| resources(nameOrPath: string | RegExp, ...middleware: (MiddlewareFunc | string | ResourcesController)[]): Router; | ||
| /** | ||
| * @param {String} name - Router name | ||
| * @param {Object} params - more parameters | ||
| * @example | ||
| * ```js | ||
| * router.url('edit_post', { id: 1, name: 'foo', page: 2 }) | ||
| * => /posts/1/edit?name=foo&page=2 | ||
| * router.url('posts', { name: 'foo&1', page: 2 }) | ||
| * => /posts?name=foo%261&page=2 | ||
| * ``` | ||
| * @return {String} url by path name and query params. | ||
| * @since 1.0.0 | ||
| */ | ||
| url(name: string, params?: Record<string, string | number | (string | number)[]>): string; | ||
| /** | ||
| * @alias to url() | ||
| */ | ||
| pathFor(name: string, params?: Record<string, string | number | (string | number)[]>): string; | ||
| * FIXME: move these patch into @eggjs/router | ||
| */ | ||
| declare class EggRouter extends Router { | ||
| readonly app: Application; | ||
| /** | ||
| * @class | ||
| * @param {Object} opts - Router options. | ||
| * @param {Application} app - Application object. | ||
| */ | ||
| constructor(opts: RouterOptions, app: Application); | ||
| verb(method: RouterMethod | RouterMethod[], nameOrPath: string | RegExp | (string | RegExp)[], pathOrMiddleware: string | RegExp | (string | RegExp)[] | MiddlewareFunc, ...middleware: (MiddlewareFunc | string)[]): Router; | ||
| head(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| head(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| options(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| options(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| get(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| get(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| put(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| put(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| patch(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| patch(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| post(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| post(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| delete(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| delete(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| all(path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| all(name: string, path: string | RegExp | (string | RegExp)[], ...middlewares: (MiddlewareFunc | string)[]): Router; | ||
| register(path: string | RegExp | (string | RegExp)[], methods: string[], middleware: MiddlewareFunc | string | (MiddlewareFunc | string | ResourcesController)[], opts?: RegisterOptions): Layer | Layer[]; | ||
| /** | ||
| * restful router api | ||
| * @param {String} name - Router name | ||
| * @param {String} prefix - url prefix | ||
| * @param {Function} middleware - middleware or controller | ||
| * @example | ||
| * ```js | ||
| * app.resources('/posts', 'posts') | ||
| * app.resources('posts', '/posts', 'posts') | ||
| * app.resources('posts', '/posts', app.role.can('user'), app.controller.posts) | ||
| * app.resources('posts', '/posts', middleware1, middleware2, app.controller.posts) | ||
| * ``` | ||
| * | ||
| * Examples: | ||
| * | ||
| * ```js | ||
| * app.resources('/posts', 'posts') | ||
| * ``` | ||
| * | ||
| * yield router mapping | ||
| * | ||
| * Method | Path | Route Name | Controller.Action | ||
| * -------|-----------------|----------------|----------------------------- | ||
| * GET | /posts | posts | app.controller.posts.index | ||
| * GET | /posts/new | new_post | app.controller.posts.new | ||
| * GET | /posts/:id | post | app.controller.posts.show | ||
| * GET | /posts/:id/edit | edit_post | app.controller.posts.edit | ||
| * POST | /posts | posts | app.controller.posts.create | ||
| * PATCH | /posts/:id | post | app.controller.posts.update | ||
| * DELETE | /posts/:id | post | app.controller.posts.destroy | ||
| * | ||
| * app.router.url can generate url based on arguments | ||
| * ```js | ||
| * app.router.url('posts') | ||
| * => /posts | ||
| * app.router.url('post', { id: 1 }) | ||
| * => /posts/1 | ||
| * app.router.url('new_post') | ||
| * => /posts/new | ||
| * app.router.url('edit_post', { id: 1 }) | ||
| * => /posts/1/edit | ||
| * ``` | ||
| * @return {Router} return route object. | ||
| * @since 1.0.0 | ||
| */ | ||
| resources(prefix: string, controller: string | ResourcesController): Router; | ||
| resources(prefix: string, middleware: MiddlewareFunc, controller: string | ResourcesController): Router; | ||
| resources(name: string, prefix: string, controller: string | ResourcesController): Router; | ||
| resources(name: string, prefix: string, middleware: MiddlewareFunc, controller: string | ResourcesController): Router; | ||
| resources(nameOrPath: string | RegExp, ...middleware: (MiddlewareFunc | string | ResourcesController)[]): Router; | ||
| /** | ||
| * @param {String} name - Router name | ||
| * @param {Object} params - more parameters | ||
| * @example | ||
| * ```js | ||
| * router.url('edit_post', { id: 1, name: 'foo', page: 2 }) | ||
| * => /posts/1/edit?name=foo&page=2 | ||
| * router.url('posts', { name: 'foo&1', page: 2 }) | ||
| * => /posts?name=foo%261&page=2 | ||
| * ``` | ||
| * @return {String} url by path name and query params. | ||
| * @since 1.0.0 | ||
| */ | ||
| url(name: string, params?: Record<string, string | number | (string | number)[]>): string; | ||
| /** | ||
| * @alias to url() | ||
| */ | ||
| pathFor(name: string, params?: Record<string, string | number | (string | number)[]>): string; | ||
| } | ||
| export {}; | ||
| //#endregion | ||
| export { EggRouter }; |
+199
-231
@@ -1,241 +0,209 @@ | ||
| import assert from 'node:assert'; | ||
| import { singularize, pluralize } from 'inflection'; | ||
| import { isGeneratorFunction } from 'is-type-of'; | ||
| import methods from 'methods'; | ||
| import { encodeURIComponent as safeEncodeURIComponent } from 'utility'; | ||
| import { Layer } from "./Layer.js"; | ||
| import "./Layer.js"; | ||
| import { Router } from "./Router.js"; | ||
| import {} from "./types.js"; | ||
| import assert from "node:assert"; | ||
| import methods from "methods"; | ||
| import { isGeneratorFunction } from "is-type-of"; | ||
| import { encodeURIComponent } from "utility"; | ||
| import { pluralize, singularize } from "inflection"; | ||
| //#region src/EggRouter.ts | ||
| const REST_MAP = { | ||
| index: { | ||
| suffix: '', | ||
| method: 'GET', | ||
| }, | ||
| new: { | ||
| namePrefix: 'new_', | ||
| member: true, | ||
| suffix: 'new', | ||
| method: 'GET', | ||
| }, | ||
| create: { | ||
| suffix: '', | ||
| method: 'POST', | ||
| }, | ||
| show: { | ||
| member: true, | ||
| suffix: ':id', | ||
| method: 'GET', | ||
| }, | ||
| edit: { | ||
| member: true, | ||
| namePrefix: 'edit_', | ||
| suffix: ':id/edit', | ||
| method: 'GET', | ||
| }, | ||
| update: { | ||
| member: true, | ||
| namePrefix: '', | ||
| suffix: ':id', | ||
| method: ['PATCH', 'PUT'], | ||
| }, | ||
| destroy: { | ||
| member: true, | ||
| namePrefix: 'destroy_', | ||
| suffix: ':id', | ||
| method: 'DELETE', | ||
| }, | ||
| index: { | ||
| suffix: "", | ||
| method: "GET" | ||
| }, | ||
| new: { | ||
| namePrefix: "new_", | ||
| member: true, | ||
| suffix: "new", | ||
| method: "GET" | ||
| }, | ||
| create: { | ||
| suffix: "", | ||
| method: "POST" | ||
| }, | ||
| show: { | ||
| member: true, | ||
| suffix: ":id", | ||
| method: "GET" | ||
| }, | ||
| edit: { | ||
| member: true, | ||
| namePrefix: "edit_", | ||
| suffix: ":id/edit", | ||
| method: "GET" | ||
| }, | ||
| update: { | ||
| member: true, | ||
| namePrefix: "", | ||
| suffix: ":id", | ||
| method: ["PATCH", "PUT"] | ||
| }, | ||
| destroy: { | ||
| member: true, | ||
| namePrefix: "destroy_", | ||
| suffix: ":id", | ||
| method: "DELETE" | ||
| } | ||
| }; | ||
| /** | ||
| * FIXME: move these patch into @eggjs/router | ||
| */ | ||
| export class EggRouter extends Router { | ||
| app; | ||
| /** | ||
| * @class | ||
| * @param {Object} opts - Router options. | ||
| * @param {Application} app - Application object. | ||
| */ | ||
| constructor(opts, app) { | ||
| super(opts); | ||
| this.app = app; | ||
| } | ||
| verb(method, nameOrPath, pathOrMiddleware, ...middleware) { | ||
| const { path, middlewares, options } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware); | ||
| if (typeof method === 'string') { | ||
| method = [method]; | ||
| } | ||
| this.register(path, method, middlewares, options); | ||
| return this; | ||
| } | ||
| head(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('head', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| options(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('options', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| get(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('get', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| put(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('put', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| patch(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('patch', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| post(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('post', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| delete(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('delete', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| all(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb(methods, nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| register(path, methods, middleware, opts) { | ||
| // patch register to support bind ctx function middleware and string controller | ||
| middleware = Array.isArray(middleware) ? middleware : [middleware]; | ||
| for (const mw of middleware) { | ||
| if (isGeneratorFunction(mw)) { | ||
| throw new TypeError(methods.toString() + ' `' + path + '`: Please use async function instead of generator function'); | ||
| } | ||
| } | ||
| const middlewares = convertMiddlewares(middleware, this.app); | ||
| return super.register(path, methods, middlewares, opts); | ||
| } | ||
| resources(nameOrPath, pathOrMiddleware, ...middleware) { | ||
| const { path, middlewares, options } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware); | ||
| // last argument is Controller object | ||
| const controller = resolveController(middlewares.pop(), this.app); | ||
| for (const key in REST_MAP) { | ||
| const action = controller[key]; | ||
| if (!action) | ||
| continue; | ||
| const opts = REST_MAP[key]; | ||
| let routeName; | ||
| if (opts.member) { | ||
| routeName = singularize(options.name ?? ''); | ||
| } | ||
| else { | ||
| routeName = pluralize(options.name ?? ''); | ||
| } | ||
| if (opts.namePrefix) { | ||
| routeName = opts.namePrefix + routeName; | ||
| } | ||
| const prefix = path.replace(/\/$/, ''); | ||
| const urlPath = opts.suffix ? `${prefix}/${opts.suffix}` : prefix; | ||
| const method = Array.isArray(opts.method) ? opts.method : [opts.method]; | ||
| this.register(urlPath, method, middlewares.concat(action), { | ||
| name: routeName, | ||
| }); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * @param {String} name - Router name | ||
| * @param {Object} params - more parameters | ||
| * @example | ||
| * ```js | ||
| * router.url('edit_post', { id: 1, name: 'foo', page: 2 }) | ||
| * => /posts/1/edit?name=foo&page=2 | ||
| * router.url('posts', { name: 'foo&1', page: 2 }) | ||
| * => /posts?name=foo%261&page=2 | ||
| * ``` | ||
| * @return {String} url by path name and query params. | ||
| * @since 1.0.0 | ||
| */ | ||
| url(name, params) { | ||
| const route = this.route(name); | ||
| if (!route) | ||
| return ''; | ||
| const args = params; | ||
| let url = route.path; | ||
| assert(!(url instanceof RegExp), `Can't get the url for regExp ${url} for by name '${name}'`); | ||
| const queries = []; | ||
| if (typeof args === 'object' && args !== null) { | ||
| const replacedParams = []; | ||
| url = url.replace(/:([a-zA-Z_]\w*)/g, ($0, key) => { | ||
| if (key in args) { | ||
| const values = args[key]; | ||
| replacedParams.push(key); | ||
| return safeEncodeURIComponent(Array.isArray(values) ? String(values[0]) : String(values)); | ||
| } | ||
| return $0; | ||
| }); | ||
| for (const key in args) { | ||
| if (replacedParams.includes(key)) { | ||
| continue; | ||
| } | ||
| const values = args[key]; | ||
| const encodedKey = safeEncodeURIComponent(key); | ||
| if (Array.isArray(values)) { | ||
| for (const val of values) { | ||
| queries.push(`${encodedKey}=${safeEncodeURIComponent(String(val))}`); | ||
| } | ||
| } | ||
| else { | ||
| queries.push(`${encodedKey}=${safeEncodeURIComponent(String(values))}`); | ||
| } | ||
| } | ||
| } | ||
| if (queries.length > 0) { | ||
| const queryStr = queries.join('&'); | ||
| if (!url.includes('?')) { | ||
| url = `${url}?${queryStr}`; | ||
| } | ||
| else { | ||
| url = `${url}&${queryStr}`; | ||
| } | ||
| } | ||
| return url; | ||
| } | ||
| /** | ||
| * @alias to url() | ||
| */ | ||
| pathFor(name, params) { | ||
| return this.url(name, params); | ||
| } | ||
| } | ||
| * FIXME: move these patch into @eggjs/router | ||
| */ | ||
| var EggRouter = class extends Router { | ||
| app; | ||
| /** | ||
| * @class | ||
| * @param {Object} opts - Router options. | ||
| * @param {Application} app - Application object. | ||
| */ | ||
| constructor(opts, app) { | ||
| super(opts); | ||
| this.app = app; | ||
| } | ||
| verb(method, nameOrPath, pathOrMiddleware, ...middleware) { | ||
| const { path, middlewares, options } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware); | ||
| if (typeof method === "string") method = [method]; | ||
| this.register(path, method, middlewares, options); | ||
| return this; | ||
| } | ||
| head(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("head", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| options(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("options", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| get(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("get", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| put(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("put", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| patch(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("patch", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| post(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("post", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| delete(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("delete", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| all(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb(methods, nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| register(path, methods$1, middleware, opts) { | ||
| middleware = Array.isArray(middleware) ? middleware : [middleware]; | ||
| for (const mw of middleware) if (isGeneratorFunction(mw)) throw new TypeError(methods$1.toString() + " `" + path + "`: Please use async function instead of generator function"); | ||
| const middlewares = convertMiddlewares(middleware, this.app); | ||
| return super.register(path, methods$1, middlewares, opts); | ||
| } | ||
| resources(nameOrPath, pathOrMiddleware, ...middleware) { | ||
| const { path, middlewares, options } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware); | ||
| const controller = resolveController(middlewares.pop(), this.app); | ||
| for (const key in REST_MAP) { | ||
| const action = controller[key]; | ||
| if (!action) continue; | ||
| const opts = REST_MAP[key]; | ||
| let routeName; | ||
| if (opts.member) routeName = singularize(options.name ?? ""); | ||
| else routeName = pluralize(options.name ?? ""); | ||
| if (opts.namePrefix) routeName = opts.namePrefix + routeName; | ||
| const prefix = path.replace(/\/$/, ""); | ||
| const urlPath = opts.suffix ? `${prefix}/${opts.suffix}` : prefix; | ||
| const method = Array.isArray(opts.method) ? opts.method : [opts.method]; | ||
| this.register(urlPath, method, middlewares.concat(action), { name: routeName }); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * @param {String} name - Router name | ||
| * @param {Object} params - more parameters | ||
| * @example | ||
| * ```js | ||
| * router.url('edit_post', { id: 1, name: 'foo', page: 2 }) | ||
| * => /posts/1/edit?name=foo&page=2 | ||
| * router.url('posts', { name: 'foo&1', page: 2 }) | ||
| * => /posts?name=foo%261&page=2 | ||
| * ``` | ||
| * @return {String} url by path name and query params. | ||
| * @since 1.0.0 | ||
| */ | ||
| url(name, params) { | ||
| const route = this.route(name); | ||
| if (!route) return ""; | ||
| const args = params; | ||
| let url = route.path; | ||
| assert(!(url instanceof RegExp), `Can't get the url for regExp ${url} for by name '${name}'`); | ||
| const queries = []; | ||
| if (typeof args === "object" && args !== null) { | ||
| const replacedParams = []; | ||
| url = url.replace(/:([a-zA-Z_]\w*)/g, ($0, key) => { | ||
| if (key in args) { | ||
| const values = args[key]; | ||
| replacedParams.push(key); | ||
| return encodeURIComponent(Array.isArray(values) ? String(values[0]) : String(values)); | ||
| } | ||
| return $0; | ||
| }); | ||
| for (const key in args) { | ||
| if (replacedParams.includes(key)) continue; | ||
| const values = args[key]; | ||
| const encodedKey = encodeURIComponent(key); | ||
| if (Array.isArray(values)) for (const val of values) queries.push(`${encodedKey}=${encodeURIComponent(String(val))}`); | ||
| else queries.push(`${encodedKey}=${encodeURIComponent(String(values))}`); | ||
| } | ||
| } | ||
| if (queries.length > 0) { | ||
| const queryStr = queries.join("&"); | ||
| if (!url.includes("?")) url = `${url}?${queryStr}`; | ||
| else url = `${url}&${queryStr}`; | ||
| } | ||
| return url; | ||
| } | ||
| /** | ||
| * @alias to url() | ||
| */ | ||
| pathFor(name, params) { | ||
| return this.url(name, params); | ||
| } | ||
| }; | ||
| /** | ||
| * resolve controller from string to function | ||
| * @param {String|Function} controller input controller | ||
| * @param {Application} app egg application instance | ||
| */ | ||
| * resolve controller from string to function | ||
| * @param {String|Function} controller input controller | ||
| * @param {Application} app egg application instance | ||
| */ | ||
| function resolveController(controller, app) { | ||
| if (typeof controller === 'string') { | ||
| // resolveController('foo.bar.Home', app) | ||
| const actions = controller.split('.'); | ||
| let obj = app.controller; | ||
| actions.forEach((key) => { | ||
| obj = obj[key]; | ||
| if (!obj) | ||
| throw new Error(`app.controller.${controller} not exists`); | ||
| }); | ||
| controller = obj; | ||
| } | ||
| // ensure controller is exists | ||
| if (!controller) | ||
| throw new Error('controller not exists'); | ||
| return controller; | ||
| if (typeof controller === "string") { | ||
| const actions = controller.split("."); | ||
| let obj = app.controller; | ||
| actions.forEach((key) => { | ||
| obj = obj[key]; | ||
| if (!obj) throw new Error(`app.controller.${controller} not exists`); | ||
| }); | ||
| controller = obj; | ||
| } | ||
| if (!controller) throw new Error("controller not exists"); | ||
| return controller; | ||
| } | ||
| /** | ||
| * 1. ensure controller(last argument) support string | ||
| * - [url, controller]: app.get('/home', 'home'); | ||
| * - [name, url, controller(string)]: app.get('posts', '/posts', 'posts.list'); | ||
| * - [name, url, controller]: app.get('posts', '/posts', app.controller.posts.list); | ||
| * - [name, url(regexp), controller]: app.get('regRouter', /\/home\/index/, 'home.index'); | ||
| * - [name, url, middleware, [...], controller]: `app.get(/user/:id', hasLogin, canGetUser, 'user.show');` | ||
| * | ||
| * 2. bind ctx to controller `this` | ||
| * | ||
| * @param {Array} middlewares middlewares and controller(last middleware) | ||
| * @param {Application} app egg application instance | ||
| */ | ||
| * 1. ensure controller(last argument) support string | ||
| * - [url, controller]: app.get('/home', 'home'); | ||
| * - [name, url, controller(string)]: app.get('posts', '/posts', 'posts.list'); | ||
| * - [name, url, controller]: app.get('posts', '/posts', app.controller.posts.list); | ||
| * - [name, url(regexp), controller]: app.get('regRouter', /\/home\/index/, 'home.index'); | ||
| * - [name, url, middleware, [...], controller]: `app.get(/user/:id', hasLogin, canGetUser, 'user.show');` | ||
| * | ||
| * 2. bind ctx to controller `this` | ||
| * | ||
| * @param {Array} middlewares middlewares and controller(last middleware) | ||
| * @param {Application} app egg application instance | ||
| */ | ||
| function convertMiddlewares(middlewares, app) { | ||
| // ensure controller is resolved | ||
| const controller = resolveController(middlewares.pop(), app); | ||
| function wrappedController(ctx, next) { | ||
| return controller.apply(ctx, [ctx, next]); | ||
| } | ||
| return [...middlewares, wrappedController]; | ||
| const controller = resolveController(middlewares.pop(), app); | ||
| function wrappedController(ctx, next) { | ||
| return controller.apply(ctx, [ctx, next]); | ||
| } | ||
| return [...middlewares, wrappedController]; | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRWdnUm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0VnZ1JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFFakMsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDcEQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2pELE9BQU8sT0FBTyxNQUFNLFNBQVMsQ0FBQztBQUM5QixPQUFPLEVBQUUsa0JBQWtCLElBQUksc0JBQXNCLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFFdkUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNuQyxPQUFPLEVBQXdCLE1BQU0sRUFBeUMsTUFBTSxhQUFhLENBQUM7QUFDbEcsT0FBTyxFQUE0RCxNQUFNLFlBQVksQ0FBQztBQVN0RixNQUFNLFFBQVEsR0FBbUM7SUFDL0MsS0FBSyxFQUFFO1FBQ0wsTUFBTSxFQUFFLEVBQUU7UUFDVixNQUFNLEVBQUUsS0FBSztLQUNkO0lBQ0QsR0FBRyxFQUFFO1FBQ0gsVUFBVSxFQUFFLE1BQU07UUFDbEIsTUFBTSxFQUFFLElBQUk7UUFDWixNQUFNLEVBQUUsS0FBSztRQUNiLE1BQU0sRUFBRSxLQUFLO0tBQ2Q7SUFDRCxNQUFNLEVBQUU7UUFDTixNQUFNLEVBQUUsRUFBRTtRQUNWLE1BQU0sRUFBRSxNQUFNO0tBQ2Y7SUFDRCxJQUFJLEVBQUU7UUFDSixNQUFNLEVBQUUsSUFBSTtRQUNaLE1BQU0sRUFBRSxLQUFLO1FBQ2IsTUFBTSxFQUFFLEtBQUs7S0FDZDtJQUNELElBQUksRUFBRTtRQUNKLE1BQU0sRUFBRSxJQUFJO1FBQ1osVUFBVSxFQUFFLE9BQU87UUFDbkIsTUFBTSxFQUFFLFVBQVU7UUFDbEIsTUFBTSxFQUFFLEtBQUs7S0FDZDtJQUNELE1BQU0sRUFBRTtRQUNOLE1BQU0sRUFBRSxJQUFJO1FBQ1os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 | ||
| //#endregion | ||
| export { EggRouter }; |
+9
-7
@@ -1,7 +0,9 @@ | ||
| import { Router } from './Router.ts'; | ||
| export type * from './types.ts'; | ||
| export * from './Layer.ts'; | ||
| export * from './Router.ts'; | ||
| export * from './EggRouter.ts'; | ||
| export declare const KoaRouter: typeof Router; | ||
| export default Router; | ||
| import { MiddlewareFunc, MiddlewareFuncWithParamProperty, MiddlewareFuncWithRouter, Next, ParamMiddlewareFunc, ResourcesController } from "./types.js"; | ||
| import { Layer, LayerOptions, LayerURLOptions } from "./Layer.js"; | ||
| import { AllowedMethodsOptions, MatchedResult, RegisterOptions, Router, RouterMethod, RouterOptions } from "./Router.js"; | ||
| import { EggRouter } from "./EggRouter.js"; | ||
| //#region src/index.d.ts | ||
| declare const KoaRouter: typeof Router; | ||
| //#endregion | ||
| export { AllowedMethodsOptions, EggRouter, KoaRouter, Layer, LayerOptions, LayerURLOptions, MatchedResult, MiddlewareFunc, MiddlewareFuncWithParamProperty, MiddlewareFuncWithRouter, Next, ParamMiddlewareFunc, RegisterOptions, ResourcesController, Router, RouterMethod, RouterOptions, Router as default }; |
+9
-6
@@ -0,7 +1,10 @@ | ||
| import { Layer } from "./Layer.js"; | ||
| import { Router } from "./Router.js"; | ||
| export * from "./Layer.js"; | ||
| export * from "./Router.js"; | ||
| export * from "./EggRouter.js"; | ||
| export const KoaRouter = Router; | ||
| export default Router; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUdyQyxjQUFjLFlBQVksQ0FBQztBQUMzQixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGdCQUFnQixDQUFDO0FBRS9CLE1BQU0sQ0FBQyxNQUFNLFNBQVMsR0FBa0IsTUFBTSxDQUFDO0FBQy9DLGVBQWUsTUFBTSxDQUFDIn0= | ||
| import { EggRouter } from "./EggRouter.js"; | ||
| //#region src/index.ts | ||
| const KoaRouter = Router; | ||
| var src_default = Router; | ||
| //#endregion | ||
| export { EggRouter, KoaRouter, Layer, Router, src_default as default }; |
+115
-111
@@ -1,114 +0,118 @@ | ||
| import { type Key } from 'path-to-regexp'; | ||
| import type { MiddlewareFunc, MiddlewareFuncWithParamProperty, ParamMiddlewareFunc } from './types.ts'; | ||
| export interface LayerOptions { | ||
| prefix?: string; | ||
| /** route name */ | ||
| name?: string; | ||
| /** case sensitive (default: false) */ | ||
| sensitive?: boolean; | ||
| /** require the trailing slash (default: false) */ | ||
| strict?: boolean; | ||
| ignoreCaptures?: boolean; | ||
| end?: boolean; | ||
| import { MiddlewareFunc, MiddlewareFuncWithParamProperty, ParamMiddlewareFunc } from "./types.js"; | ||
| import { Key } from "path-to-regexp"; | ||
| //#region src/Layer.d.ts | ||
| interface LayerOptions { | ||
| prefix?: string; | ||
| /** route name */ | ||
| name?: string; | ||
| /** case sensitive (default: false) */ | ||
| sensitive?: boolean; | ||
| /** require the trailing slash (default: false) */ | ||
| strict?: boolean; | ||
| ignoreCaptures?: boolean; | ||
| end?: boolean; | ||
| } | ||
| export interface LayerURLOptions { | ||
| query?: string | object; | ||
| interface LayerURLOptions { | ||
| query?: string | object; | ||
| } | ||
| export declare class Layer { | ||
| readonly opts: LayerOptions; | ||
| readonly name?: string; | ||
| readonly methods: string[]; | ||
| readonly stack: MiddlewareFuncWithParamProperty[]; | ||
| path: string | RegExp; | ||
| regexp: RegExp; | ||
| paramNames: Key[]; | ||
| /** | ||
| * Initialize a new routing Layer with given `method`, `path`, and `middleware`. | ||
| * | ||
| * @param {String|RegExp} path Path string or regular expression. | ||
| * @param {Array} methods Array of HTTP verbs. | ||
| * @param {Array|Function} middlewares Layer callback/middleware or series of. | ||
| * @param {Object=} opts optional params | ||
| * @param {String=} opts.name route name | ||
| * @param {String=} opts.sensitive case sensitive (default: false) | ||
| * @param {String=} opts.strict require the trailing slash (default: false) | ||
| * @private | ||
| */ | ||
| constructor(path: string | RegExp, methods: string[], middlewares: MiddlewareFunc | MiddlewareFunc[], opts?: LayerOptions | string); | ||
| /** | ||
| * Returns whether request `path` matches route. | ||
| * | ||
| * @param {String} path path string | ||
| * @return {Boolean} matched or not | ||
| * @private | ||
| */ | ||
| match(path: string): boolean; | ||
| /** | ||
| * Returns map of URL parameters for given `path` and `paramNames`. | ||
| * | ||
| * @param {String} _path path string | ||
| * @param {Array.<String>} captures captures strings | ||
| * @param {Object=} [existingParams] existing params | ||
| * @return {Object} params object | ||
| * @private | ||
| */ | ||
| params(_path: string, captures: Array<string>, existingParams?: Record<string, string>): Record<string, string>; | ||
| /** | ||
| * Returns array of regexp url path captures. | ||
| * | ||
| * @param {String} path path string | ||
| * @return {Array.<String>} captures strings | ||
| * @private | ||
| */ | ||
| captures(path: string): Array<string>; | ||
| /** | ||
| * Generate URL for route using given `params`. | ||
| * | ||
| * @example | ||
| * | ||
| * ```javascript | ||
| * var route = new Layer(['GET'], '/users/:id', fn); | ||
| * | ||
| * route.url(123); // => "/users/123" | ||
| * route.url('123'); // => "/users/123" | ||
| * route.url({ id: 123 }); // => "/users/123" | ||
| * ``` | ||
| * | ||
| * @param {Object} params url parameters | ||
| * @param {Object} paramsOrOptions optional parameters | ||
| * @return {String} url string | ||
| * @private | ||
| */ | ||
| url(params?: string | number | object, ...paramsOrOptions: (string | number | object | LayerURLOptions)[]): string; | ||
| /** | ||
| * Run validations on route named parameters. | ||
| * | ||
| * @example | ||
| * | ||
| * ```javascript | ||
| * router | ||
| * .param('user', function (id, ctx, next) { | ||
| * ctx.user = users[id]; | ||
| * if (!user) return ctx.status = 404; | ||
| * next(); | ||
| * }) | ||
| * .get('/users/:user', function (ctx, next) { | ||
| * ctx.body = ctx.user; | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @param {String} param param string | ||
| * @param {Function} fn middleware function | ||
| * @return {Layer} layer instance | ||
| * @private | ||
| */ | ||
| param(param: string, fn: ParamMiddlewareFunc): Layer; | ||
| /** | ||
| * Prefix route path. | ||
| * | ||
| * @param {String} prefix prefix string | ||
| * @return {Layer} layer instance | ||
| * @private | ||
| */ | ||
| setPrefix(prefix: string): Layer; | ||
| declare class Layer { | ||
| readonly opts: LayerOptions; | ||
| readonly name?: string; | ||
| readonly methods: string[]; | ||
| readonly stack: MiddlewareFuncWithParamProperty[]; | ||
| path: string | RegExp; | ||
| regexp: RegExp; | ||
| paramNames: Key[]; | ||
| /** | ||
| * Initialize a new routing Layer with given `method`, `path`, and `middleware`. | ||
| * | ||
| * @param {String|RegExp} path Path string or regular expression. | ||
| * @param {Array} methods Array of HTTP verbs. | ||
| * @param {Array|Function} middlewares Layer callback/middleware or series of. | ||
| * @param {Object=} opts optional params | ||
| * @param {String=} opts.name route name | ||
| * @param {String=} opts.sensitive case sensitive (default: false) | ||
| * @param {String=} opts.strict require the trailing slash (default: false) | ||
| * @private | ||
| */ | ||
| constructor(path: string | RegExp, methods: string[], middlewares: MiddlewareFunc | MiddlewareFunc[], opts?: LayerOptions | string); | ||
| /** | ||
| * Returns whether request `path` matches route. | ||
| * | ||
| * @param {String} path path string | ||
| * @return {Boolean} matched or not | ||
| * @private | ||
| */ | ||
| match(path: string): boolean; | ||
| /** | ||
| * Returns map of URL parameters for given `path` and `paramNames`. | ||
| * | ||
| * @param {String} _path path string | ||
| * @param {Array.<String>} captures captures strings | ||
| * @param {Object=} [existingParams] existing params | ||
| * @return {Object} params object | ||
| * @private | ||
| */ | ||
| params(_path: string, captures: Array<string>, existingParams?: Record<string, string>): Record<string, string>; | ||
| /** | ||
| * Returns array of regexp url path captures. | ||
| * | ||
| * @param {String} path path string | ||
| * @return {Array.<String>} captures strings | ||
| * @private | ||
| */ | ||
| captures(path: string): Array<string>; | ||
| /** | ||
| * Generate URL for route using given `params`. | ||
| * | ||
| * @example | ||
| * | ||
| * ```javascript | ||
| * var route = new Layer(['GET'], '/users/:id', fn); | ||
| * | ||
| * route.url(123); // => "/users/123" | ||
| * route.url('123'); // => "/users/123" | ||
| * route.url({ id: 123 }); // => "/users/123" | ||
| * ``` | ||
| * | ||
| * @param {Object} params url parameters | ||
| * @param {Object} paramsOrOptions optional parameters | ||
| * @return {String} url string | ||
| * @private | ||
| */ | ||
| url(params?: string | number | object, ...paramsOrOptions: (string | number | object | LayerURLOptions)[]): string; | ||
| /** | ||
| * Run validations on route named parameters. | ||
| * | ||
| * @example | ||
| * | ||
| * ```javascript | ||
| * router | ||
| * .param('user', function (id, ctx, next) { | ||
| * ctx.user = users[id]; | ||
| * if (!user) return ctx.status = 404; | ||
| * next(); | ||
| * }) | ||
| * .get('/users/:user', function (ctx, next) { | ||
| * ctx.body = ctx.user; | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @param {String} param param string | ||
| * @param {Function} fn middleware function | ||
| * @return {Layer} layer instance | ||
| * @private | ||
| */ | ||
| param(param: string, fn: ParamMiddlewareFunc): Layer; | ||
| /** | ||
| * Prefix route path. | ||
| * | ||
| * @param {String} prefix prefix string | ||
| * @return {Layer} layer instance | ||
| * @private | ||
| */ | ||
| setPrefix(prefix: string): Layer; | ||
| } | ||
| //#endregion | ||
| export { Layer, LayerOptions, LayerURLOptions }; |
+201
-238
@@ -1,238 +0,201 @@ | ||
| import { debuglog } from 'node:util'; | ||
| import { isGeneratorFunction } from 'is-type-of'; | ||
| import pathToRegExp, {} from 'path-to-regexp'; | ||
| import URI from 'urijs'; | ||
| import { decodeURIComponent as safeDecodeURIComponent } from 'utility'; | ||
| const debug = debuglog('egg/router:Layer'); | ||
| export class Layer { | ||
| opts; | ||
| name; | ||
| methods = []; | ||
| stack; | ||
| path; | ||
| regexp; | ||
| paramNames = []; | ||
| /** | ||
| * Initialize a new routing Layer with given `method`, `path`, and `middleware`. | ||
| * | ||
| * @param {String|RegExp} path Path string or regular expression. | ||
| * @param {Array} methods Array of HTTP verbs. | ||
| * @param {Array|Function} middlewares Layer callback/middleware or series of. | ||
| * @param {Object=} opts optional params | ||
| * @param {String=} opts.name route name | ||
| * @param {String=} opts.sensitive case sensitive (default: false) | ||
| * @param {String=} opts.strict require the trailing slash (default: false) | ||
| * @private | ||
| */ | ||
| constructor(path, methods, middlewares, opts) { | ||
| if (typeof opts === 'string') { | ||
| // new Layer(path, methods, middlewares, name); | ||
| opts = { name: opts }; | ||
| } | ||
| this.opts = opts ?? {}; | ||
| this.opts.prefix = this.opts.prefix ?? ''; | ||
| this.name = this.opts.name; | ||
| this.stack = Array.isArray(middlewares) ? middlewares : [middlewares]; | ||
| for (const method of methods) { | ||
| const l = this.methods.push(method.toUpperCase()); | ||
| if (this.methods[l - 1] === 'GET') { | ||
| this.methods.unshift('HEAD'); | ||
| } | ||
| } | ||
| // ensure middleware is a function | ||
| this.stack.forEach((fn) => { | ||
| const type = typeof fn; | ||
| if (type !== 'function') { | ||
| throw new TypeError(methods.toString() + | ||
| ' `' + | ||
| (this.opts.name || path) + | ||
| '`: `middleware` ' + | ||
| 'must be a function, not `' + | ||
| type + | ||
| '`'); | ||
| } | ||
| if (isGeneratorFunction(fn)) { | ||
| throw new TypeError(methods.toString() + | ||
| ' `' + | ||
| (this.opts.name || path) + | ||
| '`: Please use async function instead of generator function'); | ||
| } | ||
| }); | ||
| this.path = path; | ||
| this.regexp = pathToRegExp(path, this.paramNames, this.opts); | ||
| debug('defined route %s %s', this.methods, this.opts.prefix + this.path); | ||
| } | ||
| /** | ||
| * Returns whether request `path` matches route. | ||
| * | ||
| * @param {String} path path string | ||
| * @return {Boolean} matched or not | ||
| * @private | ||
| */ | ||
| match(path) { | ||
| return this.regexp.test(path); | ||
| } | ||
| /** | ||
| * Returns map of URL parameters for given `path` and `paramNames`. | ||
| * | ||
| * @param {String} _path path string | ||
| * @param {Array.<String>} captures captures strings | ||
| * @param {Object=} [existingParams] existing params | ||
| * @return {Object} params object | ||
| * @private | ||
| */ | ||
| params(_path, captures, existingParams) { | ||
| const params = existingParams ?? {}; | ||
| for (let len = captures.length, i = 0; i < len; i++) { | ||
| const paramName = this.paramNames[i]; | ||
| if (paramName) { | ||
| const c = captures[i]; | ||
| params[paramName.name] = c ? safeDecodeURIComponent(c) : c; | ||
| } | ||
| } | ||
| return params; | ||
| } | ||
| /** | ||
| * Returns array of regexp url path captures. | ||
| * | ||
| * @param {String} path path string | ||
| * @return {Array.<String>} captures strings | ||
| * @private | ||
| */ | ||
| captures(path) { | ||
| if (this.opts.ignoreCaptures) | ||
| return []; | ||
| const m = path.match(this.regexp); | ||
| return m ? m.slice(1) : []; | ||
| } | ||
| /** | ||
| * Generate URL for route using given `params`. | ||
| * | ||
| * @example | ||
| * | ||
| * ```javascript | ||
| * var route = new Layer(['GET'], '/users/:id', fn); | ||
| * | ||
| * route.url(123); // => "/users/123" | ||
| * route.url('123'); // => "/users/123" | ||
| * route.url({ id: 123 }); // => "/users/123" | ||
| * ``` | ||
| * | ||
| * @param {Object} params url parameters | ||
| * @param {Object} paramsOrOptions optional parameters | ||
| * @return {String} url string | ||
| * @private | ||
| */ | ||
| url(params, ...paramsOrOptions) { | ||
| let args = params; | ||
| const url = this.path.replace(/\(\.\*\)/g, ''); | ||
| const toPath = pathToRegExp.compile(url); | ||
| let options; | ||
| if (params !== undefined && typeof params !== 'object') { | ||
| args = [params, ...paramsOrOptions]; | ||
| // route.url(stringOrNumber, params1, ..., options); | ||
| if (Array.isArray(args)) { | ||
| const lastIndex = args.length - 1; | ||
| if (typeof args[lastIndex] === 'object') { | ||
| options = args[lastIndex]; | ||
| args = args.slice(0, lastIndex); | ||
| } | ||
| } | ||
| } | ||
| else if (typeof params === 'object') { | ||
| if (typeof paramsOrOptions[0] === 'object' && 'query' in paramsOrOptions[0]) { | ||
| // route.url(param, options); | ||
| options = paramsOrOptions[0]; | ||
| } | ||
| } | ||
| const tokens = pathToRegExp.parse(url); | ||
| let replace = {}; | ||
| if (Array.isArray(args)) { | ||
| for (let len = tokens.length, i = 0, j = 0; i < len; i++) { | ||
| const token = tokens[i]; | ||
| if (typeof token === 'object' && token.name) { | ||
| replace[token.name] = args[j++]; | ||
| } | ||
| } | ||
| } | ||
| else if (tokens.some((token) => typeof token === 'object' && token.name)) { | ||
| // route.url(params); | ||
| replace = params; | ||
| } | ||
| else { | ||
| // route.url(options); | ||
| options = params; | ||
| } | ||
| const replaced = toPath(replace); | ||
| if (options?.query) { | ||
| const urlObject = new URI(replaced); | ||
| urlObject.search(options.query); | ||
| return urlObject.toString(); | ||
| } | ||
| return replaced; | ||
| } | ||
| /** | ||
| * Run validations on route named parameters. | ||
| * | ||
| * @example | ||
| * | ||
| * ```javascript | ||
| * router | ||
| * .param('user', function (id, ctx, next) { | ||
| * ctx.user = users[id]; | ||
| * if (!user) return ctx.status = 404; | ||
| * next(); | ||
| * }) | ||
| * .get('/users/:user', function (ctx, next) { | ||
| * ctx.body = ctx.user; | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @param {String} param param string | ||
| * @param {Function} fn middleware function | ||
| * @return {Layer} layer instance | ||
| * @private | ||
| */ | ||
| param(param, fn) { | ||
| const stack = this.stack; | ||
| const params = this.paramNames; | ||
| const middleware = function (ctx, next) { | ||
| return fn.call(this, ctx.params[param], ctx, next); | ||
| }; | ||
| middleware.param = param; | ||
| const names = params.map((p) => { | ||
| return p.name; | ||
| }); | ||
| const x = names.indexOf(param); | ||
| if (x > -1) { | ||
| // iterate through the stack, to figure out where to place the handler fn | ||
| stack.some(function (fn, i) { | ||
| // param handlers are always first, so when we find an fn w/o a param property, stop here | ||
| // if the param handler at this part of the stack comes after the one we are adding, stop here | ||
| if (!fn.param || names.indexOf(fn.param) > x) { | ||
| // inject this param handler right before the current item | ||
| stack.splice(i, 0, middleware); | ||
| return true; // then break the loop | ||
| } | ||
| return false; | ||
| }); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Prefix route path. | ||
| * | ||
| * @param {String} prefix prefix string | ||
| * @return {Layer} layer instance | ||
| * @private | ||
| */ | ||
| setPrefix(prefix) { | ||
| if (this.path) { | ||
| this.path = prefix + this.path; | ||
| this.paramNames = []; | ||
| this.regexp = pathToRegExp(this.path, this.paramNames, this.opts); | ||
| } | ||
| return this; | ||
| } | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTGF5ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvTGF5ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUVyQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDakQsT0FBTyxZQUFZLEVBQUUsRUFBWSxNQUFNLGdCQUFnQixDQUFDO0FBQ3hELE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQztBQUN4QixPQUFPLEVBQUUsa0JBQWtCLElBQUksc0JBQXNCLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFJdkUsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLGtCQUFrQixDQUFDLENBQUM7QUFrQjNDLE1BQU0sT0FBTyxLQUFLO0lBQ1AsSUFBSSxDQUFlO0lBQ25CLElBQUksQ0FBVTtJQUNkLE9BQU8sR0FBYSxFQUFFLENBQUM7SUFDdkIsS0FBSyxDQUFvQztJQUNsRCxJQUFJLENBQWtCO0lBQ3RCLE1BQU0sQ0FBUztJQUNmLFVBQVUsR0FBVSxFQUFFLENBQUM7SUFFdkI7Ozs7Ozs7Ozs7O09BV0c7SUFDSCxZQUNFLElBQXFCLEVBQ3JCLE9BQWlCLEVBQ2pCLFdBQThDLEVBQzlDLElBQTRCO1FBRTVCLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDN0IsK0NBQStDO1lBQy9DLElBQUksR0FBRyxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUN4QixDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBQztRQUMxQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQzNCLElBQUksQ0FBQyxLQUFLLEdBQUcs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 | ||
| import { debuglog } from "node:util"; | ||
| import { isGeneratorFunction } from "is-type-of"; | ||
| import pathToRegExp from "path-to-regexp"; | ||
| import URI from "urijs"; | ||
| import { decodeURIComponent } from "utility"; | ||
| //#region src/Layer.ts | ||
| const debug = debuglog("egg/router:Layer"); | ||
| var Layer = class { | ||
| opts; | ||
| name; | ||
| methods = []; | ||
| stack; | ||
| path; | ||
| regexp; | ||
| paramNames = []; | ||
| /** | ||
| * Initialize a new routing Layer with given `method`, `path`, and `middleware`. | ||
| * | ||
| * @param {String|RegExp} path Path string or regular expression. | ||
| * @param {Array} methods Array of HTTP verbs. | ||
| * @param {Array|Function} middlewares Layer callback/middleware or series of. | ||
| * @param {Object=} opts optional params | ||
| * @param {String=} opts.name route name | ||
| * @param {String=} opts.sensitive case sensitive (default: false) | ||
| * @param {String=} opts.strict require the trailing slash (default: false) | ||
| * @private | ||
| */ | ||
| constructor(path, methods, middlewares, opts) { | ||
| if (typeof opts === "string") opts = { name: opts }; | ||
| this.opts = opts ?? {}; | ||
| this.opts.prefix = this.opts.prefix ?? ""; | ||
| this.name = this.opts.name; | ||
| this.stack = Array.isArray(middlewares) ? middlewares : [middlewares]; | ||
| for (const method of methods) { | ||
| const l = this.methods.push(method.toUpperCase()); | ||
| if (this.methods[l - 1] === "GET") this.methods.unshift("HEAD"); | ||
| } | ||
| this.stack.forEach((fn) => { | ||
| const type = typeof fn; | ||
| if (type !== "function") throw new TypeError(methods.toString() + " `" + (this.opts.name || path) + "`: `middleware` must be a function, not `" + type + "`"); | ||
| if (isGeneratorFunction(fn)) throw new TypeError(methods.toString() + " `" + (this.opts.name || path) + "`: Please use async function instead of generator function"); | ||
| }); | ||
| this.path = path; | ||
| this.regexp = pathToRegExp(path, this.paramNames, this.opts); | ||
| debug("defined route %s %s", this.methods, this.opts.prefix + this.path); | ||
| } | ||
| /** | ||
| * Returns whether request `path` matches route. | ||
| * | ||
| * @param {String} path path string | ||
| * @return {Boolean} matched or not | ||
| * @private | ||
| */ | ||
| match(path) { | ||
| return this.regexp.test(path); | ||
| } | ||
| /** | ||
| * Returns map of URL parameters for given `path` and `paramNames`. | ||
| * | ||
| * @param {String} _path path string | ||
| * @param {Array.<String>} captures captures strings | ||
| * @param {Object=} [existingParams] existing params | ||
| * @return {Object} params object | ||
| * @private | ||
| */ | ||
| params(_path, captures, existingParams) { | ||
| const params = existingParams ?? {}; | ||
| for (let len = captures.length, i = 0; i < len; i++) { | ||
| const paramName = this.paramNames[i]; | ||
| if (paramName) { | ||
| const c = captures[i]; | ||
| params[paramName.name] = c ? decodeURIComponent(c) : c; | ||
| } | ||
| } | ||
| return params; | ||
| } | ||
| /** | ||
| * Returns array of regexp url path captures. | ||
| * | ||
| * @param {String} path path string | ||
| * @return {Array.<String>} captures strings | ||
| * @private | ||
| */ | ||
| captures(path) { | ||
| if (this.opts.ignoreCaptures) return []; | ||
| const m = path.match(this.regexp); | ||
| return m ? m.slice(1) : []; | ||
| } | ||
| /** | ||
| * Generate URL for route using given `params`. | ||
| * | ||
| * @example | ||
| * | ||
| * ```javascript | ||
| * var route = new Layer(['GET'], '/users/:id', fn); | ||
| * | ||
| * route.url(123); // => "/users/123" | ||
| * route.url('123'); // => "/users/123" | ||
| * route.url({ id: 123 }); // => "/users/123" | ||
| * ``` | ||
| * | ||
| * @param {Object} params url parameters | ||
| * @param {Object} paramsOrOptions optional parameters | ||
| * @return {String} url string | ||
| * @private | ||
| */ | ||
| url(params, ...paramsOrOptions) { | ||
| let args = params; | ||
| const url = this.path.replace(/\(\.\*\)/g, ""); | ||
| const toPath = pathToRegExp.compile(url); | ||
| let options; | ||
| if (params !== void 0 && typeof params !== "object") { | ||
| args = [params, ...paramsOrOptions]; | ||
| if (Array.isArray(args)) { | ||
| const lastIndex = args.length - 1; | ||
| if (typeof args[lastIndex] === "object") { | ||
| options = args[lastIndex]; | ||
| args = args.slice(0, lastIndex); | ||
| } | ||
| } | ||
| } else if (typeof params === "object") { | ||
| if (typeof paramsOrOptions[0] === "object" && "query" in paramsOrOptions[0]) options = paramsOrOptions[0]; | ||
| } | ||
| const tokens = pathToRegExp.parse(url); | ||
| let replace = {}; | ||
| if (Array.isArray(args)) for (let len = tokens.length, i = 0, j = 0; i < len; i++) { | ||
| const token = tokens[i]; | ||
| if (typeof token === "object" && token.name) replace[token.name] = args[j++]; | ||
| } | ||
| else if (tokens.some((token) => typeof token === "object" && token.name)) replace = params; | ||
| else options = params; | ||
| const replaced = toPath(replace); | ||
| if (options?.query) { | ||
| const urlObject = new URI(replaced); | ||
| urlObject.search(options.query); | ||
| return urlObject.toString(); | ||
| } | ||
| return replaced; | ||
| } | ||
| /** | ||
| * Run validations on route named parameters. | ||
| * | ||
| * @example | ||
| * | ||
| * ```javascript | ||
| * router | ||
| * .param('user', function (id, ctx, next) { | ||
| * ctx.user = users[id]; | ||
| * if (!user) return ctx.status = 404; | ||
| * next(); | ||
| * }) | ||
| * .get('/users/:user', function (ctx, next) { | ||
| * ctx.body = ctx.user; | ||
| * }); | ||
| * ``` | ||
| * | ||
| * @param {String} param param string | ||
| * @param {Function} fn middleware function | ||
| * @return {Layer} layer instance | ||
| * @private | ||
| */ | ||
| param(param, fn) { | ||
| const stack = this.stack; | ||
| const params = this.paramNames; | ||
| const middleware = function(ctx, next) { | ||
| return fn.call(this, ctx.params[param], ctx, next); | ||
| }; | ||
| middleware.param = param; | ||
| const names = params.map((p) => { | ||
| return p.name; | ||
| }); | ||
| const x = names.indexOf(param); | ||
| if (x > -1) stack.some(function(fn$1, i) { | ||
| if (!fn$1.param || names.indexOf(fn$1.param) > x) { | ||
| stack.splice(i, 0, middleware); | ||
| return true; | ||
| } | ||
| return false; | ||
| }); | ||
| return this; | ||
| } | ||
| /** | ||
| * Prefix route path. | ||
| * | ||
| * @param {String} prefix prefix string | ||
| * @return {Layer} layer instance | ||
| * @private | ||
| */ | ||
| setPrefix(prefix) { | ||
| if (this.path) { | ||
| this.path = prefix + this.path; | ||
| this.paramNames = []; | ||
| this.regexp = pathToRegExp(this.path, this.paramNames, this.opts); | ||
| } | ||
| return this; | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { Layer }; |
+490
-489
@@ -1,494 +0,495 @@ | ||
| /** | ||
| * RESTful resource routing middleware for eggjs. | ||
| */ | ||
| import methods from 'methods'; | ||
| import { Layer, type LayerURLOptions } from './Layer.ts'; | ||
| import { type MiddlewareFunc, type MiddlewareFuncWithRouter, type ParamMiddlewareFunc, type ResourcesController } from './types.ts'; | ||
| export type RouterMethod = (typeof methods)[0]; | ||
| export interface RouterOptions { | ||
| methods?: string[]; | ||
| prefix?: string; | ||
| sensitive?: boolean; | ||
| strict?: boolean; | ||
| routerPath?: string; | ||
| import { MiddlewareFunc, MiddlewareFuncWithRouter, ParamMiddlewareFunc, ResourcesController } from "./types.js"; | ||
| import { Layer, LayerURLOptions } from "./Layer.js"; | ||
| import methods from "methods"; | ||
| //#region src/Router.d.ts | ||
| type RouterMethod = (typeof methods)[0]; | ||
| 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; | ||
| interface RegisterOptions { | ||
| name?: string; | ||
| prefix?: string; | ||
| sensitive?: boolean; | ||
| strict?: boolean; | ||
| ignoreCaptures?: boolean; | ||
| end?: boolean; | ||
| } | ||
| export interface AllowedMethodsOptions { | ||
| throw?: boolean; | ||
| notImplemented?: () => Error; | ||
| methodNotAllowed?: () => Error; | ||
| interface AllowedMethodsOptions { | ||
| throw?: boolean; | ||
| notImplemented?: () => Error; | ||
| methodNotAllowed?: () => Error; | ||
| } | ||
| export interface MatchedResult { | ||
| path: Layer[]; | ||
| pathAndMethod: Layer[]; | ||
| route: boolean; | ||
| 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: (MiddlewareFunc | string | 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; | ||
| 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: (MiddlewareFunc | string | 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; | ||
| } | ||
| //#endregion | ||
| export { AllowedMethodsOptions, MatchedResult, RegisterOptions, Router, RouterMethod, RouterOptions }; |
+677
-778
@@ -0,779 +1,678 @@ | ||
| import { Layer } from "./Layer.js"; | ||
| import assert from "node:assert"; | ||
| import { debuglog } from "node:util"; | ||
| import HttpError from "http-errors"; | ||
| import compose from "koa-compose"; | ||
| import methods from "methods"; | ||
| //#region src/Router.ts | ||
| /** | ||
| * RESTful resource routing middleware for eggjs. | ||
| */ | ||
| import assert from 'node:assert'; | ||
| import { debuglog } from 'node:util'; | ||
| import HttpError from 'http-errors'; | ||
| import compose from 'koa-compose'; | ||
| import methods from 'methods'; | ||
| import { Layer } from "./Layer.js"; | ||
| import {} from "./types.js"; | ||
| const debug = debuglog('egg/router:Router'); | ||
| export class Router { | ||
| opts; | ||
| methods; | ||
| /** Layer stack */ | ||
| stack = []; | ||
| params = {}; | ||
| /** | ||
| * 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) { | ||
| this.opts = opts ?? {}; | ||
| this.methods = this.opts.methods ?? ['HEAD', 'OPTIONS', 'GET', 'PUT', 'PATCH', 'POST', 'DELETE']; | ||
| } | ||
| use(pathOrMiddleware, ...middlewares) { | ||
| // support array of paths | ||
| // use(paths, ...middlewares) | ||
| if (Array.isArray(pathOrMiddleware) && typeof pathOrMiddleware[0] === 'string') { | ||
| for (const path of pathOrMiddleware) { | ||
| this.use(path, ...middlewares); | ||
| } | ||
| return this; | ||
| } | ||
| let path = ''; | ||
| let hasPath = false; | ||
| if (typeof pathOrMiddleware === 'string') { | ||
| // use(path, ...middlewares) | ||
| path = pathOrMiddleware; | ||
| hasPath = true; | ||
| } | ||
| else if (typeof pathOrMiddleware === 'function') { | ||
| // use(...middlewares) | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| } | ||
| for (const m of middlewares) { | ||
| if (m.router) { | ||
| for (const nestedLayer of m.router.stack) { | ||
| if (path) { | ||
| nestedLayer.setPrefix(path); | ||
| } | ||
| if (this.opts.prefix) { | ||
| nestedLayer.setPrefix(this.opts.prefix); | ||
| } | ||
| this.stack.push(nestedLayer); | ||
| } | ||
| if (this.params) { | ||
| for (const key in this.params) { | ||
| m.router.param(key, this.params[key]); | ||
| } | ||
| } | ||
| } | ||
| else { | ||
| this.register(path || '(.*)', [], m, { | ||
| end: false, | ||
| ignoreCaptures: !hasPath, | ||
| }); | ||
| } | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * 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) { | ||
| prefix = prefix.replace(/\/$/, ''); | ||
| this.opts.prefix = prefix; | ||
| for (const layer of this.stack) { | ||
| layer.setPrefix(prefix); | ||
| } | ||
| return this; | ||
| } | ||
| /** | ||
| * Returns router middleware which dispatches a route matching the request. | ||
| * | ||
| * @return {Function} middleware function | ||
| */ | ||
| routes() { | ||
| const dispatch = (ctx, next) => { | ||
| const routerPath = this.opts.routerPath || ctx.routerPath || ctx.path; | ||
| const matched = this.match(routerPath, ctx.method); | ||
| debug('dispatch: %s %s, routerPath: %s, matched: %s', ctx.method, ctx.path, routerPath, matched.route); | ||
| if (ctx.matched) { | ||
| ctx.matched.push(...matched.path); | ||
| } | ||
| else { | ||
| ctx.matched = matched.path; | ||
| } | ||
| ctx.router = this; | ||
| if (!matched.route) { | ||
| return next(); | ||
| } | ||
| const matchedLayers = matched.pathAndMethod; | ||
| const layerChain = matchedLayers.reduce((memo, layer) => { | ||
| memo.push((ctx, next) => { | ||
| // ctx.captures = layer.captures(routerPath, ctx.captures); | ||
| ctx.captures = layer.captures(routerPath); | ||
| ctx.params = layer.params(routerPath, ctx.captures, ctx.params); | ||
| // ctx._matchedRouteName & ctx._matchedRoute for compatibility | ||
| ctx._matchedRouteName = ctx.routerName = layer.name; | ||
| if (!layer.name) { | ||
| ctx._matchedRouteName = undefined; | ||
| } | ||
| ctx._matchedRoute = ctx.routerPath = layer.path; | ||
| return next(); | ||
| }); | ||
| return memo.concat(layer.stack); | ||
| }, []); | ||
| return compose(layerChain)(ctx, next); | ||
| }; | ||
| dispatch.router = this; | ||
| return dispatch; | ||
| } | ||
| /** | ||
| * @alias to routes() | ||
| */ | ||
| middleware() { | ||
| return this.routes(); | ||
| } | ||
| /** | ||
| * 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) { | ||
| const implemented = this.methods; | ||
| return async function allowedMethods(ctx, next) { | ||
| await next(); | ||
| if (ctx.status && ctx.status !== 404) | ||
| return; | ||
| const allowed = {}; | ||
| ctx.matched.forEach((route) => { | ||
| route.methods.forEach((method) => { | ||
| allowed[method] = method; | ||
| }); | ||
| }); | ||
| const allowedMethods = Object.keys(allowed); | ||
| if (!implemented.includes(ctx.method)) { | ||
| if (options?.throw) { | ||
| let notImplementedThrowable; | ||
| if (typeof options?.notImplemented === 'function') { | ||
| notImplementedThrowable = options.notImplemented(); // set whatever the user returns from their function | ||
| } | ||
| else { | ||
| notImplementedThrowable = new HttpError.NotImplemented(); | ||
| } | ||
| throw notImplementedThrowable; | ||
| } | ||
| else { | ||
| ctx.status = 501; | ||
| ctx.set('Allow', allowedMethods.join(', ')); | ||
| } | ||
| } | ||
| else if (allowedMethods.length > 0) { | ||
| if (ctx.method === 'OPTIONS') { | ||
| ctx.status = 200; | ||
| ctx.body = ''; | ||
| ctx.set('Allow', allowedMethods.join(', ')); | ||
| } | ||
| else if (!allowed[ctx.method]) { | ||
| if (options?.throw) { | ||
| let notAllowedThrowable; | ||
| if (typeof options?.methodNotAllowed === 'function') { | ||
| notAllowedThrowable = options.methodNotAllowed(); // set whatever the user returns from their function | ||
| } | ||
| else { | ||
| notAllowedThrowable = new HttpError.MethodNotAllowed(); | ||
| } | ||
| throw notAllowedThrowable; | ||
| } | ||
| else { | ||
| ctx.status = 405; | ||
| ctx.set('Allow', allowedMethods.join(', ')); | ||
| } | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| /** | ||
| * 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, destination, status = 301) { | ||
| // lookup source route by name | ||
| if (source[0] !== '/') { | ||
| const routeUrl = this.url(source); | ||
| if (routeUrl instanceof Error) { | ||
| throw routeUrl; | ||
| } | ||
| source = routeUrl; | ||
| } | ||
| // lookup destination route by name | ||
| if (destination[0] !== '/') { | ||
| const routeUrl = this.url(destination); | ||
| if (routeUrl instanceof Error) { | ||
| throw routeUrl; | ||
| } | ||
| destination = routeUrl; | ||
| } | ||
| return this.all(source, (ctx) => { | ||
| ctx.redirect(destination); | ||
| ctx.status = status; | ||
| }); | ||
| } | ||
| /** | ||
| * 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, methods, middleware, opts) { | ||
| // support array of paths | ||
| if (Array.isArray(path)) { | ||
| const routes = []; | ||
| for (const p of path) { | ||
| const route = this.#register(p, methods, middleware, opts); | ||
| routes.push(route); | ||
| } | ||
| return routes; | ||
| } | ||
| // create route | ||
| const route = this.#register(path, methods, middleware, opts); | ||
| return route; | ||
| } | ||
| #register(path, methods, middleware, opts) { | ||
| opts = opts ?? {}; | ||
| // create route | ||
| const route = new Layer(path, methods, middleware, { | ||
| end: opts.end === false ? opts.end : true, | ||
| name: opts.name, | ||
| sensitive: opts.sensitive ?? this.opts.sensitive ?? false, | ||
| strict: opts.strict ?? this.opts.strict ?? false, | ||
| prefix: opts.prefix ?? this.opts.prefix ?? '', | ||
| ignoreCaptures: opts.ignoreCaptures, | ||
| }); | ||
| // FIXME: why??? | ||
| if (this.opts.prefix) { | ||
| route.setPrefix(this.opts.prefix); | ||
| } | ||
| // add parameter middleware to the new route layer | ||
| for (const param in this.params) { | ||
| route.param(param, this.params[param]); | ||
| } | ||
| this.stack.push(route); | ||
| return route; | ||
| } | ||
| /** | ||
| * Lookup route with given `name`. | ||
| * | ||
| * @param {String} name route name | ||
| * @return {Layer|false} layer instance of false | ||
| */ | ||
| route(name) { | ||
| for (const route of this.stack) { | ||
| if (route.name === name) { | ||
| return route; | ||
| } | ||
| } | ||
| return 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, params, ...paramsOrOptions) { | ||
| const route = this.route(name); | ||
| if (route) { | ||
| return route.url(params, ...paramsOrOptions); | ||
| } | ||
| return new Error(`No route found for name: ${name}`); | ||
| } | ||
| /** | ||
| * 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, params, ...paramsOrOptions) { | ||
| return Layer.prototype.url.call({ path }, params, ...paramsOrOptions); | ||
| } | ||
| /** | ||
| * 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, method) { | ||
| const matched = { | ||
| // matched path | ||
| path: [], | ||
| // matched path and method(including none method) | ||
| pathAndMethod: [], | ||
| // method matched or not | ||
| route: false, | ||
| }; | ||
| for (const layer of this.stack) { | ||
| debug('test %s %s', layer.path, layer.regexp); | ||
| if (layer.match(path)) { | ||
| matched.path.push(layer); | ||
| if (layer.methods.length === 0 || layer.methods.includes(method)) { | ||
| matched.pathAndMethod.push(layer); | ||
| if (layer.methods.length > 0) { | ||
| matched.route = true; | ||
| } | ||
| } | ||
| // if (layer.methods.length === 0) { | ||
| // matched.pathAndMethod.push(layer); | ||
| // } else if (layer.methods.includes(method)) { | ||
| // matched.pathAndMethod.push(layer); | ||
| // matched.route = true; | ||
| // } | ||
| } | ||
| } | ||
| return matched; | ||
| } | ||
| /** | ||
| * 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, middleware) { | ||
| this.params[param] = middleware; | ||
| for (const route of this.stack) { | ||
| route.param(param, middleware); | ||
| } | ||
| return this; | ||
| } | ||
| _formatRouteParams(nameOrPath, pathOrMiddleware, middlewares) { | ||
| const options = {}; | ||
| let path; | ||
| if (typeof nameOrPath === 'string' && nameOrPath.startsWith('/')) { | ||
| // verb(method, path, ...middlewares) | ||
| path = nameOrPath; | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| if (typeof pathOrMiddleware === 'string') { | ||
| // verb(method, path, controllerString) | ||
| // set controller name to router name | ||
| options.name = pathOrMiddleware; | ||
| } | ||
| } | ||
| else if (nameOrPath instanceof RegExp) { | ||
| // verb(method, pathRegex, ...middlewares) | ||
| path = nameOrPath; | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| if (typeof pathOrMiddleware === 'string') { | ||
| // verb(method, pathRegex, controllerString) | ||
| // set controller name to router name | ||
| options.name = pathOrMiddleware; | ||
| } | ||
| } | ||
| else if (Array.isArray(nameOrPath)) { | ||
| // verb(method, paths, ...middlewares) | ||
| path = nameOrPath; | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| if (typeof pathOrMiddleware === 'string') { | ||
| // verb(method, pathRegex, controllerString) | ||
| // set controller name to router name | ||
| options.name = pathOrMiddleware; | ||
| } | ||
| } | ||
| else if (typeof pathOrMiddleware === 'string' || pathOrMiddleware instanceof RegExp) { | ||
| // verb(method, name, path, ...middlewares) | ||
| path = pathOrMiddleware; | ||
| assert(typeof nameOrPath === 'string', 'route name should be string'); | ||
| options.name = nameOrPath; | ||
| } | ||
| else if (Array.isArray(pathOrMiddleware)) { | ||
| // verb(method, name, paths, ...middlewares) | ||
| path = pathOrMiddleware; | ||
| assert(typeof nameOrPath === 'string', 'route name should be string'); | ||
| options.name = nameOrPath; | ||
| } | ||
| else { | ||
| // verb(method, path, ...middlewares) | ||
| path = nameOrPath; | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| } | ||
| return { | ||
| path, | ||
| middlewares, | ||
| options, | ||
| }; | ||
| } | ||
| /** | ||
| * 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, nameOrPath, pathOrMiddleware, ...middleware) { | ||
| const { options, path, middlewares } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware); | ||
| if (typeof method === 'string') { | ||
| method = [method]; | ||
| } | ||
| this.register(path, method, middlewares, options); | ||
| return this; | ||
| } | ||
| all(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb(methods, nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| acl(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('acl', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| bind(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('bind', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| checkout(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('checkout', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| connect(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('connect', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| copy(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('copy', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| delete(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('delete', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| del(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('delete', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| get(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('get', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| query(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('query', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| head(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('head', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| link(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('link', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| lock(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('lock', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| ['m-search'](nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('m-search', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| merge(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('merge', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| mkactivity(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('mkactivity', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| mkcalendar(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('mkcalendar', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| mkcol(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('mkcol', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| move(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('move', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| notify(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('notify', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| options(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('options', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| patch(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('patch', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| post(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('post', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| propfind(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('propfind', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| proppatch(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('proppatch', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| purge(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('purge', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| put(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('put', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| rebind(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('rebind', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| report(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('report', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| search(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('search', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| source(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('source', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| subscribe(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('subscribe', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| trace(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('trace', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| unbind(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('unbind', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| unlink(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('unlink', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| unlock(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('unlock', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| unsubscribe(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb('unsubscribe', nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| } | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUm91dGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL1JvdXRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7R0FFRztBQUVILE9BQU8sTUFBTSxNQUFNLGFBQWEsQ0FBQztBQUNqQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXJDLE9BQU8sU0FBUyxNQUFNLGFBQWEsQ0FBQztBQUNwQyxPQUFPLE9BQU8sTUFBTSxhQUFhLENBQUM7QUFDbEMsT0FBTyxPQUFPLE1BQU0sU0FBUyxDQUFDO0FBRTlCLE9BQU8sRUFBRSxLQUFLLEVBQXdCLE1BQU0sWUFBWSxDQUFDO0FBQ3pELE9BQU8sRUFNTixNQUFNLFlBQVksQ0FBQztBQUVwQixNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsbUJBQW1CLENBQUMsQ0FBQztBQW9DNUMsTUFBTSxPQUFPLE1BQU07SUFDUixJQUFJLENBQWdCO0lBQ3BCLE9BQU8sQ0FBVztJQUMzQixrQkFBa0I7SUFDVCxLQUFLLEdBQVksRUFBRSxDQUFDO0lBQ3BCLE1BQU0sR0FBd0MsRUFBRSxDQUFDO0lBRTFEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0EyQkc7SUFDSCxZQUFZLElBQW9CO1FBQzlCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDbkcsQ0FBQztJQWdDRCxHQUFHLENBQUMsZ0JBQW9ELEVBQUUsR0FBRyxXQUE2QjtRQUN4Rix5QkFBeUI7UUFDekIsNkJBQTZCO1FBQzdCLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLE9BQU8sZ0JBQWdCLENBQUMsQ0FBQyxD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 | ||
| * RESTful resource routing middleware for eggjs. | ||
| */ | ||
| const debug = debuglog("egg/router:Router"); | ||
| var Router = class { | ||
| opts; | ||
| methods; | ||
| /** Layer stack */ | ||
| stack = []; | ||
| params = {}; | ||
| /** | ||
| * 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) { | ||
| this.opts = opts ?? {}; | ||
| this.methods = this.opts.methods ?? [ | ||
| "HEAD", | ||
| "OPTIONS", | ||
| "GET", | ||
| "PUT", | ||
| "PATCH", | ||
| "POST", | ||
| "DELETE" | ||
| ]; | ||
| } | ||
| use(pathOrMiddleware, ...middlewares) { | ||
| if (Array.isArray(pathOrMiddleware) && typeof pathOrMiddleware[0] === "string") { | ||
| for (const path$1 of pathOrMiddleware) this.use(path$1, ...middlewares); | ||
| return this; | ||
| } | ||
| let path = ""; | ||
| let hasPath = false; | ||
| if (typeof pathOrMiddleware === "string") { | ||
| path = pathOrMiddleware; | ||
| hasPath = true; | ||
| } else if (typeof pathOrMiddleware === "function") middlewares = [pathOrMiddleware, ...middlewares]; | ||
| for (const m of middlewares) if (m.router) { | ||
| for (const nestedLayer of m.router.stack) { | ||
| if (path) nestedLayer.setPrefix(path); | ||
| if (this.opts.prefix) nestedLayer.setPrefix(this.opts.prefix); | ||
| this.stack.push(nestedLayer); | ||
| } | ||
| if (this.params) for (const key in this.params) m.router.param(key, this.params[key]); | ||
| } else this.register(path || "(.*)", [], m, { | ||
| end: false, | ||
| ignoreCaptures: !hasPath | ||
| }); | ||
| return this; | ||
| } | ||
| /** | ||
| * 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) { | ||
| prefix = prefix.replace(/\/$/, ""); | ||
| this.opts.prefix = prefix; | ||
| for (const layer of this.stack) layer.setPrefix(prefix); | ||
| return this; | ||
| } | ||
| /** | ||
| * Returns router middleware which dispatches a route matching the request. | ||
| * | ||
| * @return {Function} middleware function | ||
| */ | ||
| routes() { | ||
| const dispatch = (ctx, next) => { | ||
| const routerPath = this.opts.routerPath || ctx.routerPath || ctx.path; | ||
| const matched = this.match(routerPath, ctx.method); | ||
| debug("dispatch: %s %s, routerPath: %s, matched: %s", ctx.method, ctx.path, routerPath, matched.route); | ||
| if (ctx.matched) ctx.matched.push(...matched.path); | ||
| else ctx.matched = matched.path; | ||
| ctx.router = this; | ||
| if (!matched.route) return next(); | ||
| return compose(matched.pathAndMethod.reduce((memo, layer) => { | ||
| memo.push((ctx$1, next$1) => { | ||
| ctx$1.captures = layer.captures(routerPath); | ||
| ctx$1.params = layer.params(routerPath, ctx$1.captures, ctx$1.params); | ||
| ctx$1._matchedRouteName = ctx$1.routerName = layer.name; | ||
| if (!layer.name) ctx$1._matchedRouteName = void 0; | ||
| ctx$1._matchedRoute = ctx$1.routerPath = layer.path; | ||
| return next$1(); | ||
| }); | ||
| return memo.concat(layer.stack); | ||
| }, []))(ctx, next); | ||
| }; | ||
| dispatch.router = this; | ||
| return dispatch; | ||
| } | ||
| /** | ||
| * @alias to routes() | ||
| */ | ||
| middleware() { | ||
| return this.routes(); | ||
| } | ||
| /** | ||
| * 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) { | ||
| const implemented = this.methods; | ||
| return async function allowedMethods(ctx, next) { | ||
| await next(); | ||
| if (ctx.status && ctx.status !== 404) return; | ||
| const allowed = {}; | ||
| ctx.matched.forEach((route) => { | ||
| route.methods.forEach((method) => { | ||
| allowed[method] = method; | ||
| }); | ||
| }); | ||
| const allowedMethods$1 = Object.keys(allowed); | ||
| if (!implemented.includes(ctx.method)) if (options?.throw) { | ||
| let notImplementedThrowable; | ||
| if (typeof options?.notImplemented === "function") notImplementedThrowable = options.notImplemented(); | ||
| else notImplementedThrowable = new HttpError.NotImplemented(); | ||
| throw notImplementedThrowable; | ||
| } else { | ||
| ctx.status = 501; | ||
| ctx.set("Allow", allowedMethods$1.join(", ")); | ||
| } | ||
| else if (allowedMethods$1.length > 0) { | ||
| if (ctx.method === "OPTIONS") { | ||
| ctx.status = 200; | ||
| ctx.body = ""; | ||
| ctx.set("Allow", allowedMethods$1.join(", ")); | ||
| } else if (!allowed[ctx.method]) if (options?.throw) { | ||
| let notAllowedThrowable; | ||
| if (typeof options?.methodNotAllowed === "function") notAllowedThrowable = options.methodNotAllowed(); | ||
| else notAllowedThrowable = new HttpError.MethodNotAllowed(); | ||
| throw notAllowedThrowable; | ||
| } else { | ||
| ctx.status = 405; | ||
| ctx.set("Allow", allowedMethods$1.join(", ")); | ||
| } | ||
| } | ||
| }; | ||
| } | ||
| /** | ||
| * 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, destination, status = 301) { | ||
| if (source[0] !== "/") { | ||
| const routeUrl = this.url(source); | ||
| if (routeUrl instanceof Error) throw routeUrl; | ||
| source = routeUrl; | ||
| } | ||
| if (destination[0] !== "/") { | ||
| const routeUrl = this.url(destination); | ||
| if (routeUrl instanceof Error) throw routeUrl; | ||
| destination = routeUrl; | ||
| } | ||
| return this.all(source, (ctx) => { | ||
| ctx.redirect(destination); | ||
| ctx.status = status; | ||
| }); | ||
| } | ||
| /** | ||
| * 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, methods$1, middleware, opts) { | ||
| if (Array.isArray(path)) { | ||
| const routes = []; | ||
| for (const p of path) { | ||
| const route = this.#register(p, methods$1, middleware, opts); | ||
| routes.push(route); | ||
| } | ||
| return routes; | ||
| } | ||
| return this.#register(path, methods$1, middleware, opts); | ||
| } | ||
| #register(path, methods$1, middleware, opts) { | ||
| opts = opts ?? {}; | ||
| const route = new Layer(path, methods$1, middleware, { | ||
| end: opts.end === false ? opts.end : true, | ||
| name: opts.name, | ||
| sensitive: opts.sensitive ?? this.opts.sensitive ?? false, | ||
| strict: opts.strict ?? this.opts.strict ?? false, | ||
| prefix: opts.prefix ?? this.opts.prefix ?? "", | ||
| ignoreCaptures: opts.ignoreCaptures | ||
| }); | ||
| if (this.opts.prefix) route.setPrefix(this.opts.prefix); | ||
| for (const param in this.params) route.param(param, this.params[param]); | ||
| this.stack.push(route); | ||
| return route; | ||
| } | ||
| /** | ||
| * Lookup route with given `name`. | ||
| * | ||
| * @param {String} name route name | ||
| * @return {Layer|false} layer instance of false | ||
| */ | ||
| route(name) { | ||
| for (const route of this.stack) if (route.name === name) return route; | ||
| return 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, params, ...paramsOrOptions) { | ||
| const route = this.route(name); | ||
| if (route) return route.url(params, ...paramsOrOptions); | ||
| return /* @__PURE__ */ new Error(`No route found for name: ${name}`); | ||
| } | ||
| /** | ||
| * 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, params, ...paramsOrOptions) { | ||
| return Layer.prototype.url.call({ path }, params, ...paramsOrOptions); | ||
| } | ||
| /** | ||
| * 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, method) { | ||
| const matched = { | ||
| path: [], | ||
| pathAndMethod: [], | ||
| route: false | ||
| }; | ||
| for (const layer of this.stack) { | ||
| debug("test %s %s", layer.path, layer.regexp); | ||
| if (layer.match(path)) { | ||
| matched.path.push(layer); | ||
| if (layer.methods.length === 0 || layer.methods.includes(method)) { | ||
| matched.pathAndMethod.push(layer); | ||
| if (layer.methods.length > 0) matched.route = true; | ||
| } | ||
| } | ||
| } | ||
| return matched; | ||
| } | ||
| /** | ||
| * 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, middleware) { | ||
| this.params[param] = middleware; | ||
| for (const route of this.stack) route.param(param, middleware); | ||
| return this; | ||
| } | ||
| _formatRouteParams(nameOrPath, pathOrMiddleware, middlewares) { | ||
| const options = {}; | ||
| let path; | ||
| if (typeof nameOrPath === "string" && nameOrPath.startsWith("/")) { | ||
| path = nameOrPath; | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| if (typeof pathOrMiddleware === "string") options.name = pathOrMiddleware; | ||
| } else if (nameOrPath instanceof RegExp) { | ||
| path = nameOrPath; | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| if (typeof pathOrMiddleware === "string") options.name = pathOrMiddleware; | ||
| } else if (Array.isArray(nameOrPath)) { | ||
| path = nameOrPath; | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| if (typeof pathOrMiddleware === "string") options.name = pathOrMiddleware; | ||
| } else if (typeof pathOrMiddleware === "string" || pathOrMiddleware instanceof RegExp) { | ||
| path = pathOrMiddleware; | ||
| assert(typeof nameOrPath === "string", "route name should be string"); | ||
| options.name = nameOrPath; | ||
| } else if (Array.isArray(pathOrMiddleware)) { | ||
| path = pathOrMiddleware; | ||
| assert(typeof nameOrPath === "string", "route name should be string"); | ||
| options.name = nameOrPath; | ||
| } else { | ||
| path = nameOrPath; | ||
| middlewares = [pathOrMiddleware, ...middlewares]; | ||
| } | ||
| return { | ||
| path, | ||
| middlewares, | ||
| options | ||
| }; | ||
| } | ||
| /** | ||
| * 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, nameOrPath, pathOrMiddleware, ...middleware) { | ||
| const { options, path, middlewares } = this._formatRouteParams(nameOrPath, pathOrMiddleware, middleware); | ||
| if (typeof method === "string") method = [method]; | ||
| this.register(path, method, middlewares, options); | ||
| return this; | ||
| } | ||
| all(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb(methods, nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| acl(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("acl", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| bind(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("bind", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| checkout(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("checkout", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| connect(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("connect", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| copy(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("copy", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| delete(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("delete", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| del(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("delete", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| get(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("get", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| query(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("query", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| head(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("head", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| link(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("link", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| lock(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("lock", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| ["m-search"](nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("m-search", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| merge(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("merge", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| mkactivity(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("mkactivity", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| mkcalendar(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("mkcalendar", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| mkcol(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("mkcol", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| move(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("move", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| notify(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("notify", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| options(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("options", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| patch(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("patch", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| post(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("post", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| propfind(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("propfind", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| proppatch(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("proppatch", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| purge(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("purge", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| put(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("put", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| rebind(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("rebind", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| report(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("report", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| search(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("search", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| source(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("source", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| subscribe(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("subscribe", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| trace(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("trace", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| unbind(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("unbind", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| unlink(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("unlink", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| unlock(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("unlock", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| unsubscribe(nameOrPath, pathOrMiddleware, ...middlewares) { | ||
| return this.verb("unsubscribe", nameOrPath, pathOrMiddleware, ...middlewares); | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { Router }; |
+18
-15
@@ -1,18 +0,21 @@ | ||
| export type Next = () => Promise<void>; | ||
| export type MiddlewareFunc = (ctx: any, next: Next) => Promise<void> | void; | ||
| export type MiddlewareFuncWithParamProperty = MiddlewareFunc & { | ||
| param?: string; | ||
| //#region src/types.d.ts | ||
| type Next = () => Promise<void>; | ||
| type MiddlewareFunc = (ctx: any, next: Next) => Promise<void> | void; | ||
| type MiddlewareFuncWithParamProperty = MiddlewareFunc & { | ||
| param?: string; | ||
| }; | ||
| export type ParamMiddlewareFunc = (param: string, ctx: any, next: Next) => Promise<void> | void; | ||
| export type MiddlewareFuncWithRouter<T> = MiddlewareFunc & { | ||
| router: T; | ||
| type ParamMiddlewareFunc = (param: string, ctx: any, next: Next) => Promise<void> | void; | ||
| type MiddlewareFuncWithRouter<T> = MiddlewareFunc & { | ||
| router: T; | ||
| }; | ||
| export interface ResourcesController { | ||
| index?: MiddlewareFunc; | ||
| new?: MiddlewareFunc; | ||
| create?: MiddlewareFunc; | ||
| show?: MiddlewareFunc; | ||
| edit?: MiddlewareFunc; | ||
| update?: MiddlewareFunc; | ||
| destroy?: MiddlewareFunc; | ||
| interface ResourcesController { | ||
| index?: MiddlewareFunc; | ||
| new?: MiddlewareFunc; | ||
| create?: MiddlewareFunc; | ||
| show?: MiddlewareFunc; | ||
| edit?: MiddlewareFunc; | ||
| update?: MiddlewareFunc; | ||
| destroy?: MiddlewareFunc; | ||
| } | ||
| //#endregion | ||
| export { MiddlewareFunc, MiddlewareFuncWithParamProperty, MiddlewareFuncWithRouter, Next, ParamMiddlewareFunc, ResourcesController }; |
+32
-38
| { | ||
| "name": "@eggjs/router", | ||
| "version": "4.0.0-beta.35", | ||
| "engines": { | ||
| "node": ">=22.18.0" | ||
| "version": "4.0.0-beta.36", | ||
| "description": "Router middleware for egg/koa. Provides RESTful resource routing.", | ||
| "keywords": [ | ||
| "koa", | ||
| "middleware", | ||
| "route", | ||
| "router" | ||
| ], | ||
| "homepage": "https://github.com/eggjs/egg/tree/next/packages/router", | ||
| "bugs": { | ||
| "url": "https://github.com/eggjs/egg/issues" | ||
| }, | ||
| "description": "Router middleware for egg/koa. Provides RESTful resource routing.", | ||
| "license": "MIT", | ||
| "author": "eggjs", | ||
| "repository": { | ||
@@ -13,13 +22,16 @@ "type": "git", | ||
| }, | ||
| "bugs": { | ||
| "url": "https://github.com/eggjs/egg/issues" | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "type": "module", | ||
| "main": "./dist/index.js", | ||
| "module": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "exports": { | ||
| ".": "./dist/index.js", | ||
| "./package.json": "./package.json" | ||
| }, | ||
| "homepage": "https://github.com/eggjs/egg/tree/next/packages/router", | ||
| "author": "eggjs", | ||
| "keywords": [ | ||
| "koa", | ||
| "middleware", | ||
| "router", | ||
| "route" | ||
| ], | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "dependencies": { | ||
@@ -40,32 +52,14 @@ "http-errors": "^2.0.0", | ||
| "@types/urijs": "^1.19.25", | ||
| "tsdown": "^0.17.0", | ||
| "typescript": "^5.9.3", | ||
| "vitest": "^4.0.15", | ||
| "@eggjs/tsconfig": "3.1.0-beta.35", | ||
| "@eggjs/koa": "3.1.0-beta.35", | ||
| "@eggjs/supertest": "9.0.0-beta.35" | ||
| "@eggjs/koa": "3.1.0-beta.36", | ||
| "@eggjs/supertest": "9.0.0-beta.36", | ||
| "@eggjs/tsconfig": "3.1.0-beta.36" | ||
| }, | ||
| "license": "MIT", | ||
| "files": [ | ||
| "dist" | ||
| ], | ||
| "type": "module", | ||
| "exports": { | ||
| ".": "./dist/index.js", | ||
| "./package.json": "./package.json" | ||
| "engines": { | ||
| "node": ">=22.18.0" | ||
| }, | ||
| "publishConfig": { | ||
| "access": "public" | ||
| }, | ||
| "main": "./dist/index.js", | ||
| "types": "./dist/index.d.ts", | ||
| "module": "./dist/index.js", | ||
| "scripts": { | ||
| "lint": "oxlint --type-aware", | ||
| "typecheck": "tsc --noEmit", | ||
| "test": "vitest run", | ||
| "build": "tsdown && rimraf dist *.tsbuildinfo && tsc -p tsconfig.build.json", | ||
| "prebench": "npm run build", | ||
| "typecheck": "tsgo --noEmit", | ||
| "bench": "cd bench && make" | ||
| } | ||
| } |
| export {}; | ||
| //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdHlwZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IiJ9 |
Network access
Supply chain riskThis module accesses the network.
Network access
Supply chain riskThis module accesses the network.
8
-20%82055
-39.18%12
-7.69%1828
-8.6%