arnaucube
arnaucube/thoughtsPublic Self-hosted repository
thoughts/node_modules/mongoose/lib/schema/embedded.js
node_modules/mongoose/lib/schema/embedded.jsRaw
  1'use strict';
  2
  3/*!
  4 * Module dependencies.
  5 */
  6
  7var SchemaType = require('../schematype');
  8var Subdocument = require('../types/subdocument');
  9var castToNumber = require('./operators/helpers').castToNumber;
 10var geospatial = require('./operators/geospatial');
 11
 12module.exports = Embedded;
 13
 14/**
 15 * Sub-schema schematype constructor
 16 *
 17 * @param {Schema} schema
 18 * @param {String} key
 19 * @param {Object} options
 20 * @inherits SchemaType
 21 * @api public
 22 */
 23
 24function Embedded(schema, path, options) {
 25  var _embedded = function(value, path, parent) {
 26    var _this = this;
 27    Subdocument.apply(this, arguments);
 28    this.$parent = parent;
 29    if (parent) {
 30      parent.on('save', function() {
 31        _this.emit('save', _this);
 32      });
 33
 34      parent.on('isNew', function(val) {
 35        _this.isNew = val;
 36        _this.emit('isNew', val);
 37      });
 38    }
 39  };
 40  _embedded.prototype = Object.create(Subdocument.prototype);
 41  _embedded.prototype.$__setSchema(schema);
 42  _embedded.schema = schema;
 43  _embedded.$isSingleNested = true;
 44  _embedded.prototype.$basePath = path;
 45
 46  // apply methods
 47  for (var i in schema.methods) {
 48    _embedded.prototype[i] = schema.methods[i];
 49  }
 50
 51  // apply statics
 52  for (i in schema.statics) {
 53    _embedded[i] = schema.statics[i];
 54  }
 55
 56  this.caster = _embedded;
 57  this.schema = schema;
 58  this.$isSingleNested = true;
 59  SchemaType.call(this, path, options, 'Embedded');
 60}
 61
 62Embedded.prototype = Object.create(SchemaType.prototype);
 63
 64/**
 65 * Special case for when users use a common location schema to represent
 66 * locations for use with $geoWithin.
 67 * https://docs.mongodb.org/manual/reference/operator/query/geoWithin/
 68 *
 69 * @param {Object} val
 70 * @api private
 71 */
 72
 73Embedded.prototype.$conditionalHandlers.$geoWithin = function(val) {
 74  return { $geometry: this.castForQuery(val.$geometry) };
 75};
 76
 77/*!
 78 * ignore
 79 */
 80
 81Embedded.prototype.$conditionalHandlers.$near =
 82Embedded.prototype.$conditionalHandlers.$nearSphere = geospatial.cast$near;
 83
 84Embedded.prototype.$conditionalHandlers.$within =
 85Embedded.prototype.$conditionalHandlers.$geoWithin = geospatial.cast$within;
 86
 87Embedded.prototype.$conditionalHandlers.$geoIntersects =
 88  geospatial.cast$geoIntersects;
 89
 90Embedded.prototype.$conditionalHandlers.$minDistance = castToNumber;
 91Embedded.prototype.$conditionalHandlers.$maxDistance = castToNumber;
 92
 93/**
 94 * Casts contents
 95 *
 96 * @param {Object} value
 97 * @api private
 98 */
 99
100Embedded.prototype.cast = function(val, doc, init) {
101  if (val && val.$isSingleNested) {
102    return val;
103  }
104  var subdoc = new this.caster(void 0, doc ? doc.$__.selected : void 0, doc);
105  if (init) {
106    subdoc.init(val);
107  } else {
108    subdoc.set(val, undefined, true);
109  }
110  return subdoc;
111};
112
113/**
114 * Casts contents for query
115 *
116 * @param {string} [$conditional] optional query operator (like `$eq` or `$in`)
117 * @param {any} value
118 * @api private
119 */
120
121Embedded.prototype.castForQuery = function($conditional, val) {
122  var handler;
123  if (arguments.length === 2) {
124    handler = this.$conditionalHandlers[$conditional];
125    if (!handler) {
126      throw new Error('Can\'t use ' + $conditional);
127    }
128    return handler.call(this, val);
129  }
130  val = $conditional;
131  if (val == null) {
132    return val;
133  }
134  return new this.caster(val).toObject({virtuals: false});
135};
136
137/**
138 * Async validation on this single nested doc.
139 *
140 * @api private
141 */
142
143Embedded.prototype.doValidate = function(value, fn) {
144  SchemaType.prototype.doValidate.call(this, value, function(error) {
145    if (error) {
146      return fn(error);
147    }
148    if (!value) {
149      return fn(null);
150    }
151    value.validate(fn, {__noPromise: true});
152  });
153};
154
155/**
156 * Synchronously validate this single nested doc
157 *
158 * @api private
159 */
160
161Embedded.prototype.doValidateSync = function(value) {
162  var schemaTypeError = SchemaType.prototype.doValidateSync.call(this, value);
163  if (schemaTypeError) {
164    return schemaTypeError;
165  }
166  if (!value) {
167    return;
168  }
169  return value.validateSync();
170};