You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
1.8 KiB
JavaScript

'use strict'
var url = require('url')
var NotFoundError = require('./error').NotFound
var RouteNode = require('./route-node')
var utils = require('./utils')
var assign = utils.assign
var isArray = utils.isArray
var isFunction = utils.isFunction
var isString = utils.isString
var noop = utils.noop
function Router(options) {
options = options || {}
this.routes = new RouteNode()
}
assign(Router.prototype, {
add: function add(path, handler) {
return this.routes.add(this._uriToParts(path), handler)
},
route: function route(path, options, done) {
if (done == null && isFunction(options)) {
done = options
options = {}
}
options = options || {}
var routeArray = this._uriToParts(path)
done = done || noop
function _routeCallback(err, func, context, args) {
if (err) {
return done(err)
} else {
if (isFunction(func)) {
return done(null, func.apply(context, args))
} else {
return done(new NotFoundError('not found', {location: path}))
}
}
}
return this.routes.get(routeArray, (options.args || []), _routeCallback)
},
_uriToParts: function _uriToParts(uri) {
if (isString(uri)) {
return url.parse(uri)
.pathname
.split('/')
.filter(function (str) { return str !== ''})
} else if (isArray(uri)) {
return uri.reduce(this._uriToPartsReducer.bind(this), [])
}
},
_uriToPartsReducer: function _uriToPartsReducer(memo, item) {
if (isArray(item)) {
return memo.concat(item)
} else if (isString(item)) {
return memo.concat(this._uriToParts(item))
} else {
return memo.concat(item)
}
}
})
Router.isNotFound = function isNotFound(err) {
return err instanceof NotFoundError
}
module.exports = Router