applyMethods.js 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. 'use strict';
  2. const get = require('../get');
  3. /*!
  4. * Register methods for this model
  5. *
  6. * @param {Model} model
  7. * @param {Schema} schema
  8. */
  9. module.exports = function applyMethods(model, schema) {
  10. function apply(method, schema) {
  11. Object.defineProperty(model.prototype, method, {
  12. get: function() {
  13. const h = {};
  14. for (const k in schema.methods[method]) {
  15. h[k] = schema.methods[method][k].bind(this);
  16. }
  17. return h;
  18. },
  19. configurable: true
  20. });
  21. }
  22. for (const method of Object.keys(schema.methods)) {
  23. const fn = schema.methods[method];
  24. if (schema.tree.hasOwnProperty(method)) {
  25. throw new Error('You have a method and a property in your schema both ' +
  26. 'named "' + method + '"');
  27. }
  28. if (schema.reserved[method] &&
  29. !get(schema, `methodOptions.${method}.suppressWarning`, false)) {
  30. console.warn(`mongoose: the method name "${method}" is used by mongoose ` +
  31. 'internally, overwriting it may cause bugs. If you\'re sure you know ' +
  32. 'what you\'re doing, you can suppress this error by using ' +
  33. `\`schema.method('${method}', fn, { suppressWarning: true })\`.`);
  34. }
  35. if (typeof fn === 'function') {
  36. model.prototype[method] = fn;
  37. } else {
  38. apply(method, schema);
  39. }
  40. }
  41. // Recursively call `applyMethods()` on child schemas
  42. model.$appliedMethods = true;
  43. for (let i = 0; i < schema.childSchemas.length; ++i) {
  44. if (schema.childSchemas[i].model.$appliedMethods) {
  45. continue;
  46. }
  47. applyMethods(schema.childSchemas[i].model, schema.childSchemas[i].schema);
  48. }
  49. };