/** * Dependencies */ var compose = require('koa-compose') , debug = require('debug')('koa-router') , pathToRegexp = require('path-to-regexp'); /** * Expose `Route`. */ module.exports = Route; /** * Initialize a new Route with given `method`, `path`, and `middleware`. * * @param {String|RegExp} path Path string or regular expression. * @param {Array} methods Array of HTTP verbs. * @param {Array} middleware Route callback/middleware or series of. * @param {String} name Optional. * @param {Object=} opts Optional. Passed to `path-to-regexp`. * @return {Route} * @api private */ function Route(path, methods, middleware, name, opts) { this.name = name || null; this.methods = []; methods.forEach(function(method) { this.methods.push(method.toUpperCase()); }, this); this.params = []; this.fns = { params: {}, middleware: [] }; if (path instanceof RegExp) { this.path = path.source; this.regexp = path; } else { this.path = path; this.regexp = pathToRegexp(path, this.params, opts); } // ensure middleware is a function middleware.forEach(function(fn) { var type = (typeof fn); if (type != 'function') { throw new Error( methods.toString() + " `" + (name || path) +"`: `middleware` " + "must be a function, not `" + type + "`" ); } }); if (middleware.length > 1) { this.middleware = compose(middleware); } else { this.middleware = middleware[0]; } this.fns.middleware = middleware; debug('defined route %s %s', this.methods, this.path); }; /** * Route prototype */ var route = Route.prototype; /** * Check if given request `path` matches route, * and if so populate `route.params`. * * @param {String} path * @return {Array} of matched params or null if not matched * @api private */ route.match = function(path) { if (this.regexp.test(path)) { var params = []; var captures = []; // save route capture groups var matches = path.match(this.regexp); if (matches && matches.length > 0) { captures = matches.slice(1); } if (this.params.length) { // If route has parameterized capture groups, // use parameter names for properties for (var len = captures.length, i=0; i "/users/123" * * @param {Object} params url parameters * @return {String} * @api private */ route.url = function(params) { var args = params; var url = this.path; // argument is of form { key: val } if (typeof params != 'object') { args = Array.prototype.slice.call(arguments); } if (args instanceof Array) { for (var len = args.length, i=0; i