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};