index.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. module['exports'] = function bindHooks (Resource) {
  2. var arrObj = Object.getOwnPropertyNames(Resource.prototype);
  3. arrObj = arrObj.filter(function(item){
  4. if (['before', 'after', 'constructor', 'method', 'property'].indexOf(item) === -1) {
  5. return item;
  6. }
  7. })
  8. for ( var funcKey in arrObj ) {
  9. var og = Resource.prototype[arrObj[funcKey]];
  10. var localMethod = arrObj[funcKey];
  11. (function(og, localMethod){
  12. // do not double wrap methods ( if parent API has called hooks() twice on the same Resource)
  13. if (Resource.prototype[localMethod]._wrapped) {
  14. return;
  15. }
  16. Resource.prototype[localMethod] = function _wrap () {
  17. var args = Array.prototype.slice.call(arguments);
  18. // todo: beforeAll hooks
  19. var self = this;
  20. beforeHooks(Resource.prototype[localMethod], args[0], function (err){
  21. var _cb = args[1];
  22. if (err) {
  23. return _cb(err);
  24. }
  25. og.call(self, args[0], function (err, d) {
  26. if (err) {
  27. return _cb(err);
  28. }
  29. afterHooks(Resource.prototype[localMethod], d, args[1]);
  30. })
  31. })
  32. }
  33. Resource.prototype[localMethod]._wrapped = true;
  34. })(og, localMethod);
  35. Resource.prototype[localMethod].before = Resource.prototype[localMethod].before || [];
  36. Resource.prototype[localMethod].after = Resource.prototype[localMethod].after || [];
  37. }
  38. Resource.prototype.before = function (localMethod, cb) {
  39. Resource.prototype[localMethod].before.unshift(cb);
  40. };
  41. Resource.prototype.after = function (localMethod, cb) {
  42. Resource.prototype[localMethod].after.push(cb);
  43. };
  44. return Resource;
  45. };
  46. function beforeHooks(fn, data, cb) {
  47. var hooks;
  48. var self = this;
  49. if (Array.isArray(fn.before) && fn.before.length > 0) {
  50. hooks = fn.before.slice();
  51. function iter() {
  52. var hook = hooks.pop();
  53. hook.call(self, data, function (err, r) {
  54. if (err) {
  55. return cb(err);
  56. }
  57. data = r;
  58. if (hooks.length > 0) {
  59. iter();
  60. }
  61. else {
  62. cb(null, data[0]);
  63. }
  64. });
  65. }
  66. iter();
  67. }
  68. else {
  69. return cb(null);
  70. }
  71. }
  72. function afterHooks(fn, data, cb) {
  73. cb = cb || function noop(){};
  74. var hooks;
  75. if (Array.isArray(fn.after) && fn.after.length > 0) {
  76. hooks = fn.after.slice();
  77. function iter() {
  78. var hook = hooks.shift();
  79. hook(data, function (err, d) {
  80. if (err) {
  81. return cb(err);
  82. }
  83. data = d;
  84. if (hooks.length > 0) {
  85. iter();
  86. }
  87. else {
  88. return cb(null, data);
  89. }
  90. });
  91. }
  92. iter();
  93. }
  94. else {
  95. cb(null, data);
  96. }
  97. }