Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

koa2-router

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

koa2-router - npm Package Compare versions

Comparing version 1.0.6 to 1.0.7

566

lib/index.js

@@ -8,3 +8,3 @@ /*!

'use strict';
'use strict'

@@ -16,11 +16,11 @@ /**

var Route = require('./route');
var Layer = require('./layer');
var methods = require('methods');
var mixin = require('utils-merge');
var debug = require('debug')('koa2-router');
var deprecate = require('depd')('koa2-router');
var flatten = require('array-flatten');
var parseUrl = require('parseurl');
var setPrototypeOf = require('setprototypeof');
var Route = require('./route')
var Layer = require('./layer')
var methods = require('methods')
var mixin = require('utils-merge')
var debug = require('debug')('koa2-router')
var deprecate = require('depd')('koa2-router')
var flatten = require('array-flatten')
var parseUrl = require('parseurl')
var setPrototypeOf = require('setprototypeof')

@@ -32,7 +32,19 @@ /**

var objectRegExp = /^\[object (\S+)\]$/;
var slice = Array.prototype.slice;
var toString = Object.prototype.toString;
var objectRegExp = /^\[object (\S+)\]$/
var slice = Array.prototype.slice
var toString = Object.prototype.toString
/**
* Expose `Router`.
*/
module.exports = Router
/**
* Expose `Route`.
*/
module.exports.Route = Route
/**
* Initialize a new `Router` with the given `options`.

@@ -45,25 +57,63 @@ *

var proto = module.exports = function(options) {
var opts = options || {};
var name = opts.name;
function Router(options) {
if (!(this instanceof Router)) {
return new Router(options)
}
var opts = options || {}
function router(ctx, next) {
return router.handle(ctx, next);
// set ctx.originalUrl and ctx.req.originalUrl
if (typeof ctx.originalUrl !== 'string') {
Object.defineProperties(ctx, {
originalUrl: {
get: function() { return ctx.req.originalUrl },
set: function(originalUrl) { return ctx.req.originalUrl = originalUrl },
enumerable: true,
configurable: true
},
baseUrl: {
get: function() { return ctx.req.baseUrl },
set: function(baseUrl) { return ctx.req.baseUrl = baseUrl },
enumerable: true,
configurable: true
},
params: {
get: function() { return ctx.params.params },
set: function(params) { return ctx.req.params = params },
enumerable: true,
configurable: true
}
})
// initialize ctx.req with `originalUrl`, `baseUrl`, `params`
ctx.req.originalUrl = ctx.req.originalUrl || ctx.req.url
ctx.req.baseUrl = ctx.req.baseUrl || ''
ctx.req.params = ctx.req.params || {}
}
return router.handle(ctx, next)
}
router._name = name;
router._name = typeof opts === 'object' ? opts.name : opts
// mixin Router class functions
setPrototypeOf(router, proto);
// inherit from the correct prototype
setPrototypeOf(router, this)
router.params = {};
router.caseSensitive = opts.caseSensitive;
router.mergeParams = opts.mergeParams;
router.strict = opts.strict;
router.middleware = [];
router.caseSensitive = opts.caseSensitive
router.mergeParams = opts.mergeParams
router.params = {}
router.strict = opts.strict
router.stack = []
return router;
return router
}
/**
* Router prototype inherits from a Function.
*/
/* istanbul ignore next */
Router.prototype = function () {}
/**
* Map the given param placeholder `name`(s) to the given callback.

@@ -85,9 +135,9 @@ *

* router.param('user_id', async function(ctx, next, id) {
* const user = await User.find(id);
* const user = await User.find(id)
* if (!user) {
* throw new Error('failed to load user');
* throw new Error('failed to load user')
* }
* ctx.user = user;
* await next();
* });
* ctx.user = user
* await next()
* })
*

@@ -99,29 +149,31 @@ * @param {String} name

*/
proto.param = function param(name, fn) {
Router.prototype.param = function param(name, fn) {
// if name is an array, make each being invoked again
if (Array.isArray(name) && name.length) {
for (var i = 0; i < name.length; i++) {
param.call(this, name[i], fn);
param.call(this, name[i], fn)
}
return this;
return this
}
if ('string' !== typeof name) {
throw new TypeError('invalid param() call, got name type ' + gettype(name));
throw new TypeError('invalid param() call, got name type ' + gettype(name))
}
if (name[0] === ':') {
deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.substr(1)) + ', fn) instead');
deprecate('router.param(' + JSON.stringify(name) + ', fn): Use router.param(' + JSON.stringify(name.substr(1)) + ', fn) instead')
// eslint-disable-next-line no-param-reassign
name = name.substr(1);
name = name.substr(1)
}
if ('function' !== typeof fn) {
throw new TypeError('invalid param() call for ' + name + ', got ' + gettype(fn));
throw new TypeError('invalid param() call for ' + name + ', got ' + gettype(fn))
}
(this.params[name] = this.params[name] || []).push(fn);
return this;
};
(this.params[name] = this.params[name] || []).push(fn)
return this
}
/**

@@ -132,31 +184,42 @@ * Dispatch a koa context into the router.

proto.handle = async function handle(ctx, upstream) {
Router.prototype.handle = async function handle(ctx, upstream) {
if (typeof upstream !== 'function') {
throw new TypeError('argument next(upstream) is required')
}
// store options for OPTIONS request
// only used if OPTIONS request
var options = [];
var methods = []
// initialize mounted base url and params
ctx.baseUrl = ctx.baseUrl || '';
ctx.params = ctx.params || {};
// save point 1
var restore1 = restore(ctx, 'baseUrl', 'params', 'url')
// setup basic req values (fix `morgan` middleware `:url` print)
ctx.req.originalUrl = ctx.originalUrl || ctx.url;
var restore1 = restore(ctx, 'baseUrl', 'params', 'url');
try {
await this.downstream(ctx, async function() {
var restore2 = restore(ctx, 'baseUrl', 'params', 'url');
// dispatch into the current router
await this.dispatch(ctx, methods)
} catch(e) {
if (e === 'router') {
// if just want to jump the current router
// save point 2
var restore2 = restore(ctx, 'baseUrl', 'params', 'url')
try {
restore1();
await upstream();
// restore point 1
restore1()
// go upstream
await upstream()
} finally {
restore2();
// restore point 2
restore2()
}
}, options);
} else {
// any other errors just throw it out
throw e
}
} finally {
// restore all url state after handling this router
restore1();
// restore point 1
restore1()
// for options requests, respond with a default if nothing else responds
if (ctx.status === 404 && options.length && ctx.method === 'OPTIONS') {
sendOptionsResponse(ctx, options);
if (ctx.status === 404 && methods.length && ctx.method === 'OPTIONS') {
sendOptionsResponse(ctx, methods)
}

@@ -167,25 +230,26 @@ }

/**
* Middleware downstream.
* dispatch koa context into this router
* @param methods collection for methods it has
* @private
*/
proto.downstream = function downstream(ctx, done, options) {
var self = this;
Router.prototype.dispatch = function dispatch(ctx, methods) {
var self = this
debug('dispatching %s %s%s', ctx.method, ctx.baseUrl, ctx.url);
debug('dispatching %s %s%s', ctx.method, ctx.baseUrl, ctx.url)
var idx = 0;
var protohost = getProtohost(ctx.url) || '';
var removed = '';
var slashAdded = false;
var paramcalled = {};
var idx = 0
var protohost = getProtohost(ctx.url) || ''
var removed = ''
var slashAdded = false
var paramcalled = {}
// middleware and routes
var middleware = self.middleware;
var stack = self.stack
// manage inter-router variables
var parentParams = ctx.params;
var parentUrl = ctx.baseUrl;
var parentParams = ctx.params
var parentUrl = ctx.baseUrl
return next();
return next()

@@ -195,4 +259,4 @@ function next() {

if (slashAdded) {
ctx.url = ctx.url.substr(1);
slashAdded = false;
ctx.url = ctx.url.substr(1)
slashAdded = false
}

@@ -202,38 +266,33 @@

if (removed.length !== 0) {
ctx.baseUrl = parentUrl;
ctx.url = protohost + removed + ctx.url.substr(protohost.length);
removed = '';
ctx.baseUrl = parentUrl
ctx.url = protohost + removed + ctx.url.substr(protohost.length)
removed = ''
}
// no more matching layers
if (idx >= middleware.length) {
return done();
if (idx >= stack.length) {
throw 'router'
}
// get pathname of request
var path = getPathname(ctx);
var path = getPathname(ctx)
if (path == null) {
return done();
// layer error for this router
console.error('null pathname in ctx')
throw 'router'
}
// find next matching layer
var layer;
var match;
var route;
var result;
var layer
var match
var route
while (match !== true && idx < middleware.length) {
layer = middleware[idx++];
result = matchLayer(layer, path);
route = layer.route;
match = result.matched;
while (match !== true && idx < stack.length) {
layer = stack[idx++]
match = layer.match(path)
route = layer.route
if (typeof match !== 'boolean') {
// FIXME hold on to layerError?
return Promise.reject(match);
}
if (match !== true) {
continue;
continue
}

@@ -243,11 +302,11 @@

// process non-route handlers normally
continue;
continue
}
var method = ctx.method;
var has_method = route._handles_method(method);
var method = ctx.method
var has_method = route._handles_method(method)
// build up automatic options response
if (!has_method && method === 'OPTIONS') {
appendMethods(options, route._options());
methods.push.apply(methods, route._methods())
}

@@ -257,4 +316,4 @@

if (!has_method && method !== 'HEAD') {
match = false;
continue;
match = false
continue
}

@@ -265,3 +324,3 @@ }

if (match !== true) {
return done();
throw 'router'
}

@@ -271,3 +330,3 @@

if (route) {
ctx.route = route;
ctx.route = route
}

@@ -277,27 +336,13 @@

ctx.params = self.mergeParams
? mergeParams(result.params, parentParams)
: result.params;
var layerPath = result.path;
? mergeParams(layer.params, parentParams)
: layer.params
var layerPath = layer.path
// this should be done for the layer
return self.process_params(layer, paramcalled, ctx, function () {
return self.process_params(layer, paramcalled, ctx, function() {
if (route) {
return layer.handle(ctx, next);
return layer.handle(ctx, next)
}
return trim_prefix(layer, layerPath, path, next);
}).catch(function(e) {
// signal to exit route
if (e === 'route') {
return next();
}
// signal to exit router with no error
if (e === 'router') {
return done();
}
// signal to exit router with error
throw e;
});
return trim_prefix(layer, layerPath, path, next)
})
}

@@ -308,4 +353,4 @@

// Validate path breaks on a path separator
var c = path[layerPath.length];
if (c && c !== '/' && c !== '.') return next();
var c = path[layerPath.length]
if (c && c !== '/' && c !== '.') return next()

@@ -315,9 +360,9 @@ // Trim off the part of the url that matches the route

debug('trim prefix (%s) from url %s', layerPath, ctx.url);
removed = layerPath;
ctx.url = protohost + ctx.url.substr(protohost.length + removed.length);
removed = layerPath
ctx.url = protohost + ctx.url.substr(protohost.length + removed.length)
// Ensure leading slash
if (!protohost && ctx.url[0] !== '/') {
ctx.url = '/' + ctx.url;
slashAdded = true;
ctx.url = '/' + ctx.url
slashAdded = true
}

@@ -328,10 +373,10 @@

? removed.substring(0, removed.length - 1)
: removed);
: removed)
}
debug('%s %s : %s', layer.name, layerPath, ctx.originalUrl);
debug('%s %s : %s', layer.name, layerPath, ctx.originalUrl)
return layer.handle(ctx, next);
return layer.handle(ctx, next)
}
};
}

@@ -343,22 +388,22 @@ /**

proto.process_params = function process_params(layer, called, ctx, done) {
var params = this.params;
Router.prototype.process_params = function process_params(layer, called, ctx, done) {
var params = this.params
// captured parameters from the layer, keys and values
var keys = layer.keys;
var keys = layer.keys
// fast track
if (!keys || keys.length === 0) {
return done();
return done()
}
var i = 0;
var name;
var paramIndex = 0;
var key;
var paramVal;
var paramCallbacks;
var paramCalled;
var i = 0
var name
var paramIndex = 0
var key
var paramVal
var paramCallbacks
var paramCalled
return param();
return param()

@@ -368,15 +413,15 @@ // process params in order

function param() {
if (i >= keys.length ) {
return done();
if (i >= keys.length) {
return done()
}
paramIndex = 0;
key = keys[i++];
name = key.name;
paramVal = ctx.params[name];
paramCallbacks = params[name];
paramCalled = called[name];
paramIndex = 0
key = keys[i++]
name = key.name
paramVal = ctx.params[name]
paramCallbacks = params[name]
paramCalled = called[name]
if (paramVal === undefined || !paramCallbacks) {
return param();
return param()
}

@@ -387,7 +432,7 @@

// restore value
ctx.params[name] = paramCalled.value;
ctx.params[name] = paramCalled.value
// process next param, don't re-process
// unless not match with the last called
return param();
return param()
}

@@ -397,11 +442,6 @@

match: paramVal,
value: paramVal,
};
value: paramVal
}
return paramCallback().catch(function(e) {
// signal to exit this param
if (e === 'param') return param();
throw e;
});
return paramCallback()
}

@@ -411,22 +451,22 @@

async function paramCallback() {
var fn = paramCallbacks[paramIndex++];
var fn = paramCallbacks[paramIndex++]
// acquire the reference of the outer variable for
// later use, otherwise we may alter it by mistake
var pcalled = paramCalled;
var k = key;
var pcalled = paramCalled
var k = key
// store updated value
pcalled.value = ctx.params[k.name];
pcalled.value = ctx.params[k.name]
if (!fn) return param();
if (typeof fn !== 'function') return param()
try {
await fn(ctx, paramCallback, paramVal, k.name);
await fn(ctx, paramCallback, paramVal, k.name)
} finally {
// store updated value
pcalled.value = ctx.params[k.name];
pcalled.value = ctx.params[k.name]
}
}
};
}

@@ -448,13 +488,13 @@ /**

proto.use = function use(fn) {
var offset = 0;
var path = '/';
Router.prototype.use = function use(handler) {
var offset = 0
var path = '/'
// default path to '/'
// disambiguate router.use([fn])
if (typeof fn !== 'function') {
var arg = fn;
// disambiguate router.use([handler])
if (typeof handler !== 'function') {
var arg = handler
while (Array.isArray(arg) && arg.length !== 0) {
arg = arg[0];
arg = arg[0]
}

@@ -464,8 +504,8 @@

if (typeof arg !== 'function') {
offset = 1;
path = fn;
offset = 1
path = handler
}
}
var callbacks = flatten(slice.call(arguments, offset));
var callbacks = flatten(slice.call(arguments, offset))

@@ -477,3 +517,3 @@ if (callbacks.length === 0) {

for (var i = 0; i < callbacks.length; i++) {
var fn = callbacks[i];
var fn = callbacks[i]

@@ -490,12 +530,12 @@ if (typeof fn !== 'function') {

strict: false,
end: false,
}, fn);
end: false
}, fn)
layer.route = undefined;
layer.route = undefined
this.middleware.push(layer);
this.stack.push(layer)
}
return this;
};
return this
}

@@ -515,4 +555,4 @@ /**

proto.route = function route(path) {
var route = new Route(path);
Router.prototype.route = function route(path) {
var route = new Route(path)

@@ -522,24 +562,24 @@ var layer = new Layer(path, {

strict: this.strict,
end: true,
}, route.dispatch.bind(route));
end: true
}, route.handle.bind(route))
layer.route = route;
layer.route = route
this.middleware.push(layer);
return route;
};
this.stack.push(layer)
return route
}
// create Router#VERB functions
methods.concat('all').forEach(function(method) {
proto[method] = function(path) {
var offset = 1;
Router.prototype[method] = function(path) {
var offset = 1
if (typeof path === 'function') {
path = '/';
offset = 0;
path = '/'
offset = 0
}
var route = this.route(path);
route[method].apply(route, slice.call(arguments, offset));
return this;
};
});
var route = this.route(path)
route[method].apply(route, slice.call(arguments, offset))
return this
}
})

@@ -549,21 +589,7 @@ /**

*/
proto.del = proto.delete;
Router.prototype.del = Router.prototype.delete
// append methods to a list of methods
function appendMethods(list, addition) {
for (var i = 0; i < addition.length; i++) {
var method = addition[i];
if (list.indexOf(method) === -1) {
list.push(method);
}
}
}
// get pathname of request context
function getPathname(ctx) {
try {
return parseUrl(ctx).pathname;
} catch (err) {
return undefined;
}
return parseUrl(ctx).pathname
}

@@ -574,14 +600,14 @@

if (typeof url !== 'string' || url.length === 0 || url[0] === '/') {
return undefined;
return undefined
}
var searchIndex = url.indexOf('?');
var searchIndex = url.indexOf('?')
var pathLength = searchIndex !== -1
? searchIndex
: url.length;
var fqdnIndex = url.substr(0, pathLength).indexOf('://');
: url.length
var fqdnIndex = url.substr(0, pathLength).indexOf('://')
return fqdnIndex !== -1
? url.substr(0, url.indexOf('/', 3 + fqdnIndex))
: undefined;
: undefined
}

@@ -591,53 +617,36 @@

function gettype(obj) {
var type = typeof obj;
var type = typeof obj
if (type !== 'object') {
return type;
return type
}
// inspect [[Class]] for objects
return toString.call(obj)
.replace(objectRegExp, '$1');
return toString.call(obj).replace(objectRegExp, '$1')
}
/**
* Match path to a layer.
*
* @param {Layer} layer
* @param {string} path
* @private
*/
function matchLayer(layer, path) {
try {
return layer.match(path);
} catch (err) {
return { matched: err };
}
}
// merge params with parent params
function mergeParams(params, parent) {
if (typeof parent !== 'object' || !parent) {
return params;
return params
}
// make copy of parent for base
var obj = mixin({}, parent);
var obj = mixin({}, parent)
// simple non-numeric merging
if (!(0 in params) || !(0 in parent)) {
return mixin(obj, params);
return mixin(obj, params)
}
var i = 0;
var o = 0;
var i = 0
var o = 0
// determine numeric gaps
while (i in params) {
i++;
i++
}
while (o in parent) {
o++;
o++
}

@@ -647,11 +656,11 @@

for (i--; i >= 0; i--) {
params[i + o] = params[i];
params[i + o] = params[i]
// create holes for the merge when necessary
if (i < o) {
delete params[i];
delete params[i]
}
}
return mixin(obj, params);
return mixin(obj, params)
}

@@ -661,8 +670,8 @@

function restore(obj) {
var props = new Array(arguments.length - 1);
var vals = new Array(arguments.length - 1);
var props = new Array(arguments.length - 1)
var vals = new Array(arguments.length - 1)
for (var i = 0; i < props.length; i++) {
props[i] = arguments[i + 1];
vals[i] = obj[props[i]];
props[i] = arguments[i + 1]
vals[i] = obj[props[i]]
}

@@ -673,3 +682,3 @@

for (var i = 0; i < props.length; i++) {
obj[props[i]] = vals[i];
obj[props[i]] = vals[i]
}

@@ -679,7 +688,24 @@ }

// send an OPTIONS response
function sendOptionsResponse(ctx, options) {
var body = options.join(',');
ctx.set('Allow', body);
ctx.body = body;
/**
* Send an OPTIONS response.
*
* @private
*/
function sendOptionsResponse(ctx, methods) {
if (ctx.respond !== false) {
var options = Object.create(null)
// build unique method map
for (var i = 0; i < methods.length; i++) {
options[methods[i]] = true
}
// construct the allow list
var body = Object.keys(options).sort().join(', ')
ctx.set('Allow', body)
ctx.set('X-Content-Type-Options', 'nosniff')
ctx.body = body
}
}

@@ -8,3 +8,3 @@ /*!

'use strict';
'use strict'

@@ -16,4 +16,4 @@ /**

var pathRegexp = require('path-to-regexp');
var debug = require('debug')('koa2-router:layer');
var pathRegexp = require('path-to-regexp')
var debug = require('debug')('koa2-router:layer')

@@ -25,3 +25,3 @@ /**

var hasOwnProperty = Object.prototype.hasOwnProperty;
var hasOwnProperty = Object.prototype.hasOwnProperty

@@ -33,19 +33,23 @@ /**

module.exports = Layer;
module.exports = Layer
function Layer(path, options, fn) {
if (!(this instanceof Layer)) {
return new Layer(path, options, fn);
return new Layer(path, options, fn)
}
debug('new %o', path)
var opts = options || {};
var opts = options || {}
this.handler = fn;
this.name = fn._name || fn.name || '<anonymous>';
this.regexp = pathRegexp(path, this.keys = [], opts);
this.handler = fn
this.name = fn._name || fn.name || '<anonymous>'
this.regexp = pathRegexp(path, this.keys = [], opts)
// temperary matched result for faster matching
this.path = undefined
this.params = undefined
// set fast path flags
this.regexp.fast_star = path === '*';
this.regexp.fast_slash = path === '/' && opts.end === false;
this.regexp.fast_star = path === '*'
this.regexp.fast_slash = path === '/' && opts.end === false
}

@@ -62,12 +66,13 @@

Layer.prototype.handle = async function handle(ctx, next) {
var fn = this.handler;
await fn(ctx, next);
};
var fn = this.handler
var owner = this.owner
await fn.call(owner, ctx, next)
}
/**
* Check if this route matches `path`, if so
* populate `.params` and `.path` for temporary usage.
* populate `.params`, `.path` properties for temporary usage.
*
* @param {String} path
* @return {Object}
* @return {Boolean}
* @api private

@@ -77,3 +82,3 @@ */

Layer.prototype.match = function match(path) {
var match;
var match

@@ -83,7 +88,5 @@ if (path != null) {

if (this.regexp.fast_slash) {
return {
params: {},
path: '',
matched: true,
};
this.params = {}
this.path = ''
return true
}

@@ -93,39 +96,37 @@

if (this.regexp.fast_star) {
return {
params: {'0': decode_param(path)},
path: path,
matched: true,
};
this.params = {'0': decode_param(path)}
this.path = path
return true
}
// match the path
match = this.regexp.exec(path);
match = this.regexp.exec(path)
}
if (!match) {
return { matched: false };
this.params = undefined
this.path = undefined
return false
}
var keys = this.keys;
var params = {};
// store values
var result = {
params: params,
path: match[0],
matched: true,
};
this.params = {}
this.path = match[0]
// iterate matches
var keys = this.keys
var params = this.params
for (var i = 1; i < match.length; i++) {
var key = keys[i - 1];
var prop = key.name;
var val = decode_param(match[i]);
var key = keys[i - 1]
var prop = key.name
var val = decode_param(match[i])
if (val !== undefined || !(hasOwnProperty.call(params, prop))) {
params[prop] = val;
params[prop] = val
}
}
return result;
};
return true
}

@@ -142,15 +143,15 @@ /**

if (typeof val !== 'string' || val.length === 0) {
return val;
return val
}
try {
return decodeURIComponent(val);
return decodeURIComponent(val)
} catch (err) {
if (err instanceof URIError) {
err.message = 'Failed to decode param \'' + val + '\'';
err.status = err.statusCode = 400;
err.message = 'Failed to decode param \'' + val + '\''
err.status = err.statusCode = 400
}
throw err;
throw err
}
}

@@ -8,3 +8,3 @@ /*!

'use strict';
'use strict'

@@ -16,6 +16,6 @@ /**

var debug = require('debug')('koa2-router:route');
var flatten = require('array-flatten');
var methods = require('methods');
var Layer = require('./layer');
var debug = require('debug')('koa2-router:route')
var flatten = require('array-flatten')
var methods = require('methods')
var Layer = require('./layer')

@@ -27,4 +27,4 @@ /**

var slice = Array.prototype.slice;
var toString = Object.prototype.toString;
var slice = Array.prototype.slice
var toString = Object.prototype.toString

@@ -36,3 +36,3 @@ /**

module.exports = Route;
module.exports = Route

@@ -47,9 +47,13 @@ /**

function Route(path) {
this.path = path;
this.middleware = [];
if (!(this instanceof Route)) {
return new Route(path)
}
debug('new %o', path)
this.path = path
this.stack = []
debug('new route %o', path)
// route handlers for various http methods
this.methods = {};
this.methods = {}
}

@@ -64,13 +68,13 @@

if (this.methods._all) {
return true;
return true
}
var name = method.toLowerCase();
var name = method.toLowerCase()
if (name === 'head' && !this.methods['head']) {
name = 'get';
name = 'get'
}
return Boolean(this.methods[name]);
};
return Boolean(this.methods[name])
}

@@ -82,8 +86,8 @@ /**

Route.prototype._options = function _options() {
var methods = Object.keys(this.methods);
Route.prototype._methods = function _methods() {
var methods = Object.keys(this.methods)
// append automatic head
if (this.methods.get && !this.methods.head) {
methods.push('head');
methods.push('head')
}

@@ -93,7 +97,7 @@

// make upper case
methods[i] = methods[i].toUpperCase();
methods[i] = methods[i].toUpperCase()
}
return methods;
};
return methods
}

@@ -105,40 +109,59 @@ /**

Route.prototype.dispatch = function dispatch(ctx, done) {
var idx = 0;
var middleware = this.middleware;
if (middleware.length === 0) {
return done();
Route.prototype.dispatch = function dispatch(ctx) {
var idx = 0
var stack = this.stack
if (stack.length === 0) {
throw 'route'
}
var method = ctx.method.toLowerCase();
var method = ctx.method.toLowerCase()
if (method === 'head' && !this.methods['head']) {
method = 'get';
method = 'get'
}
ctx.route = this;
ctx.route = this
return next();
return next()
function next() {
var layer = middleware[idx++];
if (!layer) {
return done();
var layer
var match
// find next matching layer
while (match !== true && idx < stack.length) {
layer = stack[idx++]
match = !layer.method || layer.method === method
}
if (layer.method && layer.method !== method) {
return next();
// no match
if (match !== true) {
throw 'route'
}
return layer.handle(ctx, next).catch(function(e) {
// signal to exit route
if (e === 'route') {
return done();
}
return layer.handle(ctx, next)
}
}
// signal to exit router
throw e;
});
/**
* handle route middleware
* @private
*/
Route.prototype.handle = async function handle(ctx, upstream) {
if (typeof upstream !== 'function') {
throw new TypeError('argument next(upstream) is required')
}
};
try {
await this.dispatch(ctx)
} catch(e) {
if (e === 'route') {
await upstream()
} else {
throw e
}
}
}
/**

@@ -152,9 +175,9 @@ * Add a handler for all HTTP verbs to this route.

*
* function check_something(req, res, next){
* next();
* };
* function check_something(ctx, next) {
* next()
* }
*
* function validate_user(req, res, next){
* next();
* };
* function validate_user(ctx, next) {
* next()
* }
*

@@ -164,5 +187,5 @@ * route

* .all(check_something)
* .get(function(req, res, next){
* res.send('hello world');
* });
* .get(function(ctx, next) {
* ctx.body = 'hello world'
* })
*

@@ -175,34 +198,38 @@ * @param {function} handler

Route.prototype.all = function all() {
var handlers = flatten(slice.call(arguments));
var handlers = flatten(slice.call(arguments))
if (handlers.length === 0) {
throw new TypeError('argument handler is required')
}
for (var i = 0; i < handlers.length; i++) {
var handler = handlers[i];
var handler = handlers[i]
if (typeof handler !== 'function') {
var type = toString.call(handler);
var type = toString.call(handler)
var msg = 'Route.all() requires a callback function but got a ' + type
throw new TypeError(msg);
throw new TypeError(msg)
}
var layer = new Layer('/', {}, handler);
layer.method = undefined;
var layer = new Layer('/', {}, handler)
layer.method = undefined
this.methods._all = true;
this.middleware.push(layer);
this.methods._all = true
this.stack.push(layer)
}
return this;
};
return this
}
methods.forEach(function(method) {
Route.prototype[method] = function() {
var handlers = flatten(slice.call(arguments));
var handlers = flatten(slice.call(arguments))
for (var i = 0; i < handlers.length; i++) {
var handler = handlers[i];
var handler = handlers[i]
if (typeof handler !== 'function') {
var type = toString.call(handler);
var type = toString.call(handler)
var msg = 'Route.' + method + '() requires a callback function but got a ' + type
throw new TypeError(msg);
throw new TypeError(msg)
}

@@ -212,12 +239,12 @@

var layer = new Layer('/', {}, handler);
layer.method = method;
var layer = new Layer('/', {}, handler)
layer.method = method
this.methods[method] = true;
this.middleware.push(layer);
this.methods[method] = true
this.stack.push(layer)
}
return this;
};
});
return this
}
})

@@ -227,2 +254,2 @@ /**

*/
Route.prototype.del = Route.prototype.delete;
Route.prototype.del = Route.prototype.delete
{
"name": "koa2-router",
"version": "1.0.6",
"version": "1.0.7",
"description": "A express-liked router component for koa2",

@@ -20,3 +20,3 @@ "main": "index.js",

"array-flatten": "^2.1.2",
"debug": "^4.1.0",
"debug": "^4.1.1",
"depd": "^2.0.0",

@@ -26,3 +26,3 @@ "methods": "^1.1.2",

"path-to-regexp": "^2.4.0",
"setprototypeof": "^1.1.0",
"setprototypeof": "^1.1.1",
"utils-merge": "^1.0.1"

@@ -32,4 +32,4 @@ },

"delay": "^4.1.0",
"http-errors": "^1.7.1",
"koa": "^2.6.2",
"http-errors": "^1.7.2",
"koa": "^2.7.0",
"koa-morgan": "^1.0.1"

@@ -36,0 +36,0 @@ },

@@ -89,2 +89,3 @@ # koa2-router

* Thanks to the [koa-router](https://github.com/alexmingoia/koa-router) project
* Thanks to the [router](https://github.com/pillarjs/router) project

@@ -91,0 +92,0 @@ ## License

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc