UNPKG

2.82 kBJavaScriptView Raw
1'use strict'
2
3const fileHandlers = require('./fileHandlers')
4const security = require('./routeSecurity')
5const validation = require('./routeValidation')
6const util = require('./util')
7
8exports.buildHandlerStack = buildHandlerStack
9
10function buildHandlerStack(operation, authorizers, options) {
11 let middleware = []
12 let handler = getHandler(operation, options)
13 if (util.isObj(handler)) {
14 if (Array.isArray(handler.middleware)) {
15 middleware = handler.middleware
16 } else if (util.isFunc(handler.middleware) || util.isObj(handler.middleware)) {
17 middleware = [ handler.middleware ]
18 }
19 handler = handler.handler || handler.default || handler[operation.id]
20 }
21 if (util.isFunc(handler)) {
22 handler = wrapRequestHandler(handler)
23 middleware = getMiddleware(middleware, operation, authorizers)
24 return middleware.concat([ handler ])
25 }
26 return []
27}
28
29function getHandler(operation, options) {
30 let handler
31 if (typeof options.handlers.create === 'function') handler = options.handlers.create(operation)
32 if (handler) fileHandlers.disableHandler(operation, options)
33 else handler = requireHandler(operation, options)
34 return handler
35}
36
37function requireHandler(operation, options) {
38 const fileInfo = fileHandlers.enableHandler(operation, options)
39 try { return require(fileInfo.path) }
40 catch(e) {
41 if (e.code === 'MODULE_NOT_FOUND') return null
42 else throw e
43 }
44}
45
46function getMiddleware(customMiddleware, operation, authorizers) {
47 const middleware = []
48 const authCheck = security.createAuthCheck(operation, authorizers)
49 const validationCheck = validation.createValidationCheck(operation)
50
51 const getAction = m => util.isObj(m) ? m.action : m
52 const preValidation = customMiddleware.filter(m => !m.validated).map(getAction).filter(util.isFunc)
53 const postValidation = customMiddleware.filter(m => !!m.validated).map(getAction).filter(util.isFunc)
54
55 middleware.push(augmentRequest(operation))
56
57 if (authCheck) middleware.push(authCheck)
58 if (preValidation.length) middleware.push.apply(middleware, preValidation)
59 if (validationCheck) middleware.push(validationCheck)
60 if (postValidation.length) middleware.push.apply(middleware, postValidation)
61
62 return middleware
63}
64
65function augmentRequest(operation) {
66 return function augmentReq(req, res, next) {
67 req.operation = operation
68 return next()
69 }
70}
71
72/*
73Wrap primary handler and capture any errors, especially if returning a Promise as the
74error will be lost otherwise. A Promise may be returned manually, or more often when
75using async / await on a handler.
76*/
77function wrapRequestHandler(func) {
78 return function handler(req, res, next) {
79 try {
80 const result = func(req, res, next)
81 if (result && result.catch) result.catch(e => next(e))
82 } catch(e) {
83 next(e)
84 }
85 }
86}