All files / server/utils/join index.js

93.1% Statements 27/29
83.33% Branches 15/18
100% Functions 3/3
92.86% Lines 26/28
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 6312x 12x 12x     12x 1819x     96x 87x       9x             9x   9x 9x             12x     196x     196x 194x 194x 2033x   2033x   216x 98x 98x 98x         1817x 1721x     102x     193x      
const load = require('loadware');
const assert = require('assert');
const reply = require('../../reply');
 
// Recursively resolve possible function returns
const processReturn = async (ctx, ret) => {
  if (!ret) return;
 
  // Use the returned reply instance
  if (ret.constructor && ret.constructor.name === 'Reply') {
    return ret.exec(ctx);
  }
 
  // Errors should be thrown to trickle down
  Iif (ret instanceof Error) {
    throw ret;
  }
 
  // TODO: make a check for only accepting the right types of return values
 
  // Create a whole new reply thing
  const fn = typeof ret === 'number' ? 'status' : 'send';
 
  Eif (ctx.res) {
    return await reply[fn](ret).exec(ctx);
  }
 
  return ret;
};
 
// Pass an array of modern middleware and return a single modern middleware
module.exports = (...middles) => {
 
  // Flattify all of the middleware
  const middle = load(middles);
 
  // Go through each of them
  return async ctx => {
    let globalReturn = false;
    for (const mid of middle) {
      try {
        // DO NOT MERGE; the else is relevant only for ctx.error
        if (ctx.error) {
          // See if this middleware can fix it
          if (mid.error) {
            assert(mid.error instanceof Function, 'Error handler should be a function');
            let ret = await mid.error(ctx);
            await processReturn(ctx, ret);
          }
        }
        // No error, call next middleware. Skips middleware if there's an error
        else {
          let ret = await mid(ctx);
          globalReturn = await processReturn(ctx, ret) || globalReturn;
        }
      } catch (err) {
        ctx.error = err;
      }
    }
    return globalReturn;
  };
};