applyMethods.js 1.7 KB

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