Code coverage report for lib/index.js

Statements: 100% (76 / 76)      Branches: 100% (34 / 34)      Functions: 100% (16 / 16)      Lines: 100% (68 / 68)      Ignored: none     

All files » lib/ » index.js
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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141    1 1 1 1   1 26 26 26 26 26 26 26     26 25 24 24 1 1 1     24 23               24 23               24 23               24 23               24 23                 1 3 3   3 4     3 2 2 1       1 1       1 6 6 1       1 6 6   6 9     6 4 4 1       2 2       1 2 2 1       1 2 2 2   2 2 1       1 1    
'use strict';
 
module.exports = null;
var errHandler = require('err-handler');
var async = require('async');
var paramRegx = /\/:([^\/]+)$/;
 
require('express').application.crud = function(route, optionalWare, resource){
  var args = [].slice.call(arguments);
  route = args.shift();
  resource = args.pop();
  var middleware = args.filter(byMiddleware);
  var param = '/:id';
  var paramName = 'id';
  var paramMatch = paramRegx.exec(route);
 
 
  if(typeof route !== 'string')throw new Error('route expected as string');
  if(!(resource instanceof Object))throw new Error('expected resource Object');
  if(route[0] !== '/')route = '/'+route;
  if(paramMatch){
    param = paramMatch[0];
    paramName = paramMatch[1];
    route = route.replace(paramRegx, '');
  }
 
  if(resource.create){
    this.post.apply(
      this,
      [route]
      .concat(middleware)
      .concat([postHandler.bind(null, resource)])
    );
  }
 
  if(resource.delete){
    this.delete.apply(
      this,
      [route + param]
      .concat(middleware)
      .concat(deleteHandler.bind(null, resource, paramName))
    );
  }
 
  if(resource.read){
    this.get.apply(
      this,
      [route]
      .concat(middleware)
      .concat(getHandler.bind(null, resource))
    );
  }
 
  if(resource.readById){
    this.get.apply(
      this,
      [route + param]
      .concat(middleware)
      .concat(getByIdHandler.bind(null, resource, paramName))
    );
  }
 
  if(resource.update){
    this.put.apply(
      this,
      [route + param]
      .concat(middleware)
      .concat(putHandler.bind(null, resource, paramName))
    );
  }
};
 
function deleteHandler(resource, param, req, res, next){
  var ids = req.params[param].split(',');
  var query = req.query;
 
  var tasks = ids.map(function(id){
    return resource.delete.bind(null, id, query);
  });
 
  if(tasks.length === 1) {
    return tasks[0](errHandler(next, function(resource){
      if(resource)return res.status(200).json(resource);
      res.status(204).json(null);
    }));
  }
 
  async.parallel(tasks, errHandler(next, function(results){
    res.status(200).json(results);
  }));
}
 
function getHandler(resource, req, res, next){
  resource.read(req.query, errHandler(next, function(resource){
    if(Array.isArray(resource))res.status(200).json(resource);
    else res.status(204).json(null);
  }));
}
 
function getByIdHandler(resource, param, req, res, next){
  var ids = req.params[param].split(',');
  var query = req.query;
 
  var tasks = ids.map(function(id){
    return resource.readById.bind(null, id, query);
  });
 
  if(tasks.length === 1){
    return tasks[0](errHandler(next, function(resource){
      if(resource)res.status(200).json(resource);
      else res.status(204).json(null);
    }));
  }
 
  async.parallel(tasks, errHandler(next, function(result){
    res.status(200).json(result);
  }));
}
 
function postHandler(resource, req, res, next){
  resource.create(req.query, req.body, errHandler(next, function(resource){
    if(resource)res.status(200).json(resource);
    else res.status(204).json(null);
  }));
}
 
function putHandler(resource, param, req, res, next){
  var id = req.params[param];
  var query = req.query;
  var body = req.body;
 
  resource.update(id, query, body, errHandler(next, function(resource){
    if(resource)res.status(200).json(resource);
    else res.status(204).json(null);
  }));
}
 
function byMiddleware(proposed){
  return typeof proposed === 'function' && proposed.length === 3;
}