applyStaticHooks.js 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. 'use strict';
  2. const middlewareFunctions = require('../query/applyQueryMiddleware').middlewareFunctions;
  3. const promiseOrCallback = require('../promiseOrCallback');
  4. module.exports = function applyStaticHooks(model, hooks, statics) {
  5. const kareemOptions = {
  6. useErrorHandlers: true,
  7. numCallbackParams: 1
  8. };
  9. hooks = hooks.filter(hook => {
  10. // If the custom static overwrites an existing query middleware, don't apply
  11. // middleware to it by default. This avoids a potential backwards breaking
  12. // change with plugins like `mongoose-delete` that use statics to overwrite
  13. // built-in Mongoose functions.
  14. if (middlewareFunctions.indexOf(hook.name) !== -1) {
  15. return !!hook.model;
  16. }
  17. return hook.model !== false;
  18. });
  19. model.$__insertMany = hooks.createWrapper('insertMany',
  20. model.$__insertMany, model, kareemOptions);
  21. for (const key of Object.keys(statics)) {
  22. if (hooks.hasHooks(key)) {
  23. const original = model[key];
  24. model[key] = function() {
  25. const numArgs = arguments.length;
  26. const lastArg = numArgs > 0 ? arguments[numArgs - 1] : null;
  27. const cb = typeof lastArg === 'function' ? lastArg : null;
  28. const args = Array.prototype.slice.
  29. call(arguments, 0, cb == null ? numArgs : numArgs - 1);
  30. // Special case: can't use `Kareem#wrap()` because it doesn't currently
  31. // support wrapped functions that return a promise.
  32. return promiseOrCallback(cb, callback => {
  33. hooks.execPre(key, model, args, function(err) {
  34. if (err != null) {
  35. return callback(err);
  36. }
  37. let postCalled = 0;
  38. const ret = original.apply(model, args.concat(post));
  39. if (ret != null && typeof ret.then === 'function') {
  40. ret.then(res => post(null, res), err => post(err));
  41. }
  42. function post(error, res) {
  43. if (postCalled++ > 0) {
  44. return;
  45. }
  46. if (error != null) {
  47. return callback(error);
  48. }
  49. hooks.execPost(key, model, [res], function(error) {
  50. if (error != null) {
  51. return callback(error);
  52. }
  53. callback(null, res);
  54. });
  55. }
  56. });
  57. }, model.events);
  58. };
  59. }
  60. }
  61. };