getEmbeddedDiscriminatorPath.js 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. 'use strict';
  2. const get = require('../get');
  3. const getSchemaDiscriminatorByValue = require('../discriminator/getSchemaDiscriminatorByValue');
  4. /*!
  5. * Like `schema.path()`, except with a document, because impossible to
  6. * determine path type without knowing the embedded discriminator key.
  7. */
  8. module.exports = function getEmbeddedDiscriminatorPath(doc, path, options) {
  9. options = options || {};
  10. const typeOnly = options.typeOnly;
  11. const parts = path.indexOf('.') === -1 ? [path] : path.split('.');
  12. let schemaType = null;
  13. let type = 'adhocOrUndefined';
  14. const schema = getSchemaDiscriminatorByValue(doc.schema, doc.get(doc.schema.options.discriminatorKey)) || doc.schema;
  15. for (let i = 0; i < parts.length; ++i) {
  16. const subpath = parts.slice(0, i + 1).join('.');
  17. schemaType = schema.path(subpath);
  18. if (schemaType == null) {
  19. type = 'adhocOrUndefined';
  20. continue;
  21. }
  22. if (schemaType.instance === 'Mixed') {
  23. return typeOnly ? 'real' : schemaType;
  24. }
  25. type = schema.pathType(subpath);
  26. if ((schemaType.$isSingleNested || schemaType.$isMongooseDocumentArrayElement) &&
  27. schemaType.schema.discriminators != null) {
  28. const discriminators = schemaType.schema.discriminators;
  29. const discriminatorKey = doc.get(subpath + '.' +
  30. get(schemaType, 'schema.options.discriminatorKey'));
  31. if (discriminatorKey == null || discriminators[discriminatorKey] == null) {
  32. continue;
  33. }
  34. const rest = parts.slice(i + 1).join('.');
  35. return getEmbeddedDiscriminatorPath(doc.get(subpath), rest, options);
  36. }
  37. }
  38. // Are we getting the whole schema or just the type, 'real', 'nested', etc.
  39. return typeOnly ? type : schemaType;
  40. };