/node_modules/mongoose/lib/services/populate/getSchemaTypes.js

https://bitbucket.org/coleman333/smartsite · JavaScript · 115 lines · 82 code · 14 blank · 19 comment · 28 complexity · 82fd703b05e5e620b9d82366d816dac4 MD5 · raw file

  1. 'use strict';
  2. /*!
  3. * ignore
  4. */
  5. var Mixed = require('../../schema/mixed');
  6. var mpath = require('mpath');
  7. /*!
  8. * @param {Schema} schema
  9. * @param {Object} doc POJO
  10. * @param {string} path
  11. */
  12. module.exports = function getSchemaTypes(schema, doc, path) {
  13. const pathschema = schema.path(path);
  14. if (pathschema) {
  15. return pathschema;
  16. }
  17. function search(parts, schema) {
  18. let p = parts.length + 1;
  19. let foundschema;
  20. let trypath;
  21. while (p--) {
  22. trypath = parts.slice(0, p).join('.');
  23. foundschema = schema.path(trypath);
  24. if (foundschema) {
  25. if (foundschema.caster) {
  26. // array of Mixed?
  27. if (foundschema.caster instanceof Mixed) {
  28. return foundschema.caster;
  29. }
  30. let schemas = null;
  31. if (doc != null && foundschema.schema != null && foundschema.schema.discriminators != null) {
  32. const discriminators = foundschema.schema.discriminators;
  33. const keys = mpath.get(trypath + '.' + foundschema.schema.options.discriminatorKey,
  34. doc);
  35. schemas = Object.keys(discriminators).
  36. reduce(function(cur, discriminator) {
  37. if (keys.indexOf(discriminator) !== -1) {
  38. cur.push(discriminators[discriminator]);
  39. }
  40. return cur;
  41. }, []);
  42. }
  43. // Now that we found the array, we need to check if there
  44. // are remaining document paths to look up for casting.
  45. // Also we need to handle array.$.path since schema.path
  46. // doesn't work for that.
  47. // If there is no foundschema.schema we are dealing with
  48. // a path like array.$
  49. if (p !== parts.length && foundschema.schema) {
  50. let ret;
  51. if (parts[p] === '$') {
  52. if (p + 1 === parts.length) {
  53. // comments.$
  54. return foundschema;
  55. }
  56. // comments.$.comments.$.title
  57. ret = search(parts.slice(p + 1), schema);
  58. if (ret) {
  59. ret.$isUnderneathDocArray = ret.$isUnderneathDocArray ||
  60. !foundschema.schema.$isSingleNested;
  61. }
  62. return ret;
  63. }
  64. if (schemas != null && schemas.length > 0) {
  65. ret = [];
  66. for (var i = 0; i < schemas.length; ++i) {
  67. let _ret = search(parts.slice(p), schemas[i]);
  68. if (_ret != null) {
  69. _ret.$isUnderneathDocArray = _ret.$isUnderneathDocArray ||
  70. !foundschema.schema.$isSingleNested;
  71. if (_ret.$isUnderneathDocArray) {
  72. ret.$isUnderneathDocArray = true;
  73. }
  74. ret.push(_ret);
  75. }
  76. }
  77. return ret;
  78. } else {
  79. ret = search(parts.slice(p), foundschema.schema);
  80. if (ret) {
  81. ret.$isUnderneathDocArray = ret.$isUnderneathDocArray ||
  82. !foundschema.schema.$isSingleNested;
  83. }
  84. return ret;
  85. }
  86. }
  87. }
  88. return foundschema;
  89. }
  90. }
  91. }
  92. // look for arrays
  93. const parts = path.split('.');
  94. for (let i = 0; i < parts.length; ++i) {
  95. if (parts[i] === '$') {
  96. // Re: gh-5628, because `schema.path()` doesn't take $ into account.
  97. parts[i] = '0';
  98. }
  99. }
  100. return search(parts, schema);
  101. };