archive/src-concept/generate/middleware.js
function nextMiddleware (factory, mw, info) {
  const {
    resolved,
    index,
    routes,
    middlewares,
    errorMiddleware,
    req,
    res,
    metrics
  } = info

  const local = {
    finished: false,
    timeout: null
  }

  // check if the request has already been resolved
  if (resolved) return

  // get the current middleware
  const current = mw[index]
  const exec = {
    name: current.functionName,
    started: Date.now(),
    ended: null,
    data: null
  }

  metrics.executions.push(exec)

  // create a next method
  const next = data => {
    clearTimeout(local.timeout)
    if (local.finished || info.resolved) return
    local.finished = true

    // add the result
    exec.ended = Date.now()
    exec.data = data

    // allow reroutes to valid named route paths
    if (_.isString(data)) {
      const route = routes[data]
      if (!route) {
        if (current.type !== ERROR_MIDDLEWARE && errorMiddleware.length) {
          info.index = 0
          req.error = new Error(`No route found for "${data}"`)
          return nextMiddleware(factory, errorMiddleware, info)
        }
        res.end(data)
      }

      // get the correct route set
      const mwSet = route.type === ERROR_MIDDLEWARE
        ? errorMiddleware
        : middlewares

      // increment the re-route counter, set the index and go
      req.reroutes += 1
      info.index = route.index
      return nextMiddleware(factory, mwSet, info)
    }

    // check for an error passed to the next method and not
    // already in the error middleware chain. if condition met
    // start processing error middleware
    if (data instanceof Error) {
      if (current.type !== ERROR_MIDDLEWARE && errorMiddleware.length) {
        info.index = 0
        req.error = data
        return nextMiddleware(factory, errorMiddleware, info)
      }
      res.end(data)
    }

    // check if there is any more middleware in the chain
    // if not, call end to complete the request
   return info.index === mw.length
     ? res.end()
     : nextMiddleware(factory, mw, info)
  }

  // create a timeout for the middleware if timeout > 0
  if (current.timeout > 0) {
    local.timeout = setTimeout(() => {
      local.finished = true
      req.error = new Error(current.functionName
        + ' middleware timed out')

      // add the result
      exec.ended = Date.now()
      exec.data = req.error

      // if already in error middleware and timed out
      // end the entire request, othewise move to error mw
      if (current.type !== ERROR_MIDDLEWARE && errorMiddleware.length) {
        info.index = 0
        return nextMiddleware(factory, errorMiddleware, info)
      }
      return res.end()
    }, current.timeout)
  }

  // try to execute the resolver and if unable
  // move to error middleware. if already in error
  // middleware end the request
  try {
    info.index += 1
    current.resolver(req, res, next)
  } catch (err) {
    clearTimeout(local.timeout)
    local.finished = true
    factory.emit(EVENT_ERROR, err)
    req.error = err

    // add the result
    exec.ended = Date.now()
    exec.data = req.error

    if (current.type !== ERROR_MIDDLEWARE && errorMiddleware.length) {
      info.index = 0
      return nextMiddleware(factory, errorMiddleware, info)
    }
    return res.end()
  }
}
function nextMiddleware (factory, mw, info) {
  const {
    resolved,
    index,
    routes,
    middlewares,
    errorMiddleware,
    req,
    res,
    metrics
  } = info

  const local = {
    finished: false,
    timeout: null
  }

  // check if the request has already been resolved
  if (resolved) return

  // get the current middleware
  const current = mw[index]
  const exec = {
    name: current.functionName,
    started: Date.now(),
    ended: null,
    data: null
  }

  metrics.executions.push(exec)

  // create a next method
  const next = data => {
    clearTimeout(local.timeout)
    if (local.finished || info.resolved) return
    local.finished = true

    // add the result
    exec.ended = Date.now()
    exec.data = data

    // allow reroutes to valid named route paths
    if (_.isString(data)) {
      const route = routes[data]
      if (!route) {
        if (current.type !== ERROR_MIDDLEWARE && errorMiddleware.length) {
          info.index = 0
          req.error = new Error(`No route found for "${data}"`)
          return nextMiddleware(factory, errorMiddleware, info)
        }
        res.end(data)
      }

      // get the correct route set
      const mwSet = route.type === ERROR_MIDDLEWARE
        ? errorMiddleware
        : middlewares

      // increment the re-route counter, set the index and go
      req.reroutes += 1
      info.index = route.index
      return nextMiddleware(factory, mwSet, info)
    }

    // check for an error passed to the next method and not
    // already in the error middleware chain. if condition met
    // start processing error middleware
    if (data instanceof Error) {
      if (current.type !== ERROR_MIDDLEWARE && errorMiddleware.length) {
        info.index = 0
        req.error = data
        return nextMiddleware(factory, errorMiddleware, info)
      }
      res.end(data)
    }

    // check if there is any more middleware in the chain
    // if not, call end to complete the request
   return info.index === mw.length
     ? res.end()
     : nextMiddleware(factory, mw, info)
  }

  // create a timeout for the middleware if timeout > 0
  if (current.timeout > 0) {
    local.timeout = setTimeout(() => {
      local.finished = true
      req.error = new Error(current.functionName
        + ' middleware timed out')

      // add the result
      exec.ended = Date.now()
      exec.data = req.error

      // if already in error middleware and timed out
      // end the entire request, othewise move to error mw
      if (current.type !== ERROR_MIDDLEWARE && errorMiddleware.length) {
        info.index = 0
        return nextMiddleware(factory, errorMiddleware, info)
      }
      return res.end()
    }, current.timeout)
  }

  // try to execute the resolver and if unable
  // move to error middleware. if already in error
  // middleware end the request
  try {
    info.index += 1
    current.resolver(req, res, next)
  } catch (err) {
    clearTimeout(local.timeout)
    local.finished = true
    factory.emit(EVENT_ERROR, err)
    req.error = err

    // add the result
    exec.ended = Date.now()
    exec.data = req.error

    if (current.type !== ERROR_MIDDLEWARE && errorMiddleware.length) {
      info.index = 0
      return nextMiddleware(factory, errorMiddleware, info)
    }
    return res.end()
  }
}
function nextMiddleware ( factory , mw , info ) { const { resolved , index , routes , middlewares , errorMiddleware , req , res , metrics } = info const local = { finished : false , timeout : null } // check if the request has already been resolved if ( resolved ) return // get the current middleware const current = mw [ index ] const exec = { name : current . functionName , started : Date . now ( ) , ended : null , data : null } metrics . executions . push ( exec ) // create a next method const next = data => { clearTimeout ( local . timeout ) if ( local . finished || info . resolved ) return local . finished = true // add the result exec . ended = Date . now ( ) exec . data = data // allow reroutes to valid named route paths if ( _ . isString ( data ) ) { const route = routes [ data ] if ( ! route ) { if ( current . type !== ERROR_MIDDLEWARE && errorMiddleware . length ) { info . index = 0 req . error = new Error ( ` ${ data } ` ) return nextMiddleware ( factory , errorMiddleware , info ) } res . end ( data ) } // get the correct route set const mwSet = route . type === ERROR_MIDDLEWARE ? errorMiddleware : middlewares // increment the re-route counter, set the index and go req . reroutes += 1 info . index = route . index return nextMiddleware ( factory , mwSet , info ) } // check for an error passed to the next method and not // already in the error middleware chain. if condition met // start processing error middleware if ( data instanceof Error ) { if ( current . type !== ERROR_MIDDLEWARE && errorMiddleware . length ) { info . index = 0 req . error = data return nextMiddleware ( factory , errorMiddleware , info ) } res . end ( data ) } // check if there is any more middleware in the chain // if not, call end to complete the request return info . index === mw . length ? res . end ( ) : nextMiddleware ( factory , mw , info ) } // create a timeout for the middleware if timeout > 0 if ( current . timeout > 0 ) { local . timeout = setTimeout ( ( ) => { local . finished = true req . error = new Error ( current . functionName + ' middleware timed out' ) // add the result exec . ended = Date . now ( ) exec . data = req . error // if already in error middleware and timed out // end the entire request, othewise move to error mw if ( current . type !== ERROR_MIDDLEWARE && errorMiddleware . length ) { info . index = 0 return nextMiddleware ( factory , errorMiddleware , info ) } return res . end ( ) } , current . timeout ) } // try to execute the resolver and if unable // move to error middleware. if already in error // middleware end the request try { info . index += 1 current . resolver ( req , res , next ) } catch ( err ) { clearTimeout ( local . timeout ) local . finished = true factory . emit ( EVENT_ERROR , err ) req . error = err // add the result exec . ended = Date . now ( ) exec . data = req . error if ( current . type !== ERROR_MIDDLEWARE && errorMiddleware . length ) { info . index = 0 return nextMiddleware ( factory , errorMiddleware , info ) } return res . end ( ) } }
Processes the next middleware in the queue
@param mw
@param info
@returns {*}
Processes the next middleware in the queue