UNPKG

express-declarative-routing

Version:

Declarative Routing for Express.js

80 lines (70 loc) 2.65 kB
utils = require('./utils') deepExtend = utils.deepExtend ensureArray = utils.ensureArray actions = [ 'use' 'all' 'options' 'get' 'post' 'put' 'delete' ] # preparing the routes actually creates middleware first # and returns functions which are used to create the routes later # this allows middleware to be created before routes # therefore we should only call buildRoutes once createBuilder = (app, action, route, endpoint, groups=[]) -> return () -> console.log('| ' + action.toUpperCase() + ' | ' + route + ' | ' + groups.join(', ') + ' | |') app[action](route, endpoint) if endpoint wrapMethodSpecific = (methods, middleware) -> return (req, res, next) -> if req.method.toLowerCase() in ensureArray(methods) middleware(req, res, next) else next() createMiddleware = (app, name, route, middleware, action=null) -> if action actionText = "#{action.toUpperCase()} " else actionText = '' console.log('adding ' + name + ' middleware for ' + actionText + route) for m in ensureArray(middleware) if action app.use(route, wrapMethodSpecific(action, m)) else app.use(route, m) prepareRoutes = (app, baseRoute, routeObject, groups=[]) -> # collect the routes toDo = [] if routeObject for key, value of routeObject when key != '_middleware' if key in actions # it's a leaf node of the routes createMiddleware(app, groups[groups.length - 1], baseRoute, routeObject._middleware, key) if routeObject._middleware? for endpoint in ensureArray(value) toDo.push(createBuilder(app, key, baseRoute, endpoint, groups)) else if key[0] == '_' # it's a group that shares middleware deeperRoute = baseRoute newGroups = groups.concat([key.slice(1)]) else # it's a nested route key = key.replace('$', ':') # '$' in our routes means ':' in express routes deeperRoute = baseRoute + '/' + key newGroups = groups createMiddleware(app, newGroups[newGroups.length - 1], deeperRoute, routeObject._middleware) if routeObject._middleware toDo.push.apply(toDo, prepareRoutes(app, deeperRoute, value, newGroups)) return toDo exports.buildRoutes = (app, routes, callback) -> toDo = [] for baseRoute, routeObjects of routes for routeObject in routeObjects toDo.push.apply(toDo, prepareRoutes(app, baseRoute, routeObject)) if callback callback(toDo) else console.log('ROUTING TABLE:') console.log('| verb | route | groups | params |') console.log('| ---- | ----- | ------ | ------ |') for prepared in toDo prepared()