mongoose 8.8.4 → 8.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/model.js CHANGED
@@ -436,6 +436,7 @@ Model.prototype.$__handleSave = function(options, callback) {
436
436
  Model.prototype.$__save = function(options, callback) {
437
437
  this.$__handleSave(options, (error, result) => {
438
438
  if (error) {
439
+ error = this.$__schema._transformDuplicateKeyError(error);
439
440
  const hooks = this.$__schema.s.hooks;
440
441
  return hooks.execPost('save:error', this, [this], { error: error }, (error) => {
441
442
  callback(error, this);
@@ -3356,7 +3357,7 @@ Model.bulkWrite = async function bulkWrite(ops, options) {
3356
3357
  let error;
3357
3358
  [res, error] = await this.$__collection.bulkWrite(validOps, options).
3358
3359
  then(res => ([res, null])).
3359
- catch(err => ([null, err]));
3360
+ catch(error => ([null, error]));
3360
3361
 
3361
3362
  if (error) {
3362
3363
  if (validationErrors.length > 0) {
@@ -4199,6 +4200,7 @@ Model.validate = async function validate(obj, pathsOrOptions, context) {
4199
4200
  * - options: optional query options like sort, limit, etc
4200
4201
  * - justOne: optional boolean, if true Mongoose will always set `path` to a document, or `null` if no document was found. If false, Mongoose will always set `path` to an array, which will be empty if no documents are found. Inferred from schema by default.
4201
4202
  * - strictPopulate: optional boolean, set to `false` to allow populating paths that aren't in the schema.
4203
+ * - forceRepopulate: optional boolean, defaults to `true`. Set to `false` to prevent Mongoose from repopulating paths that are already populated
4202
4204
  *
4203
4205
  * #### Example:
4204
4206
  *
@@ -4235,6 +4237,7 @@ Model.validate = async function validate(obj, pathsOrOptions, context) {
4235
4237
  * @param {Boolean} [options.strictPopulate=true] Set to false to allow populating paths that aren't defined in the given model's schema.
4236
4238
  * @param {Object} [options.options=null] Additional options like `limit` and `lean`.
4237
4239
  * @param {Function} [options.transform=null] Function that Mongoose will call on every populated document that allows you to transform the populated document.
4240
+ * @param {Boolean} [options.forceRepopulate=true] Set to `false` to prevent Mongoose from repopulating paths that are already populated
4238
4241
  * @param {Function} [callback(err,doc)] Optional callback, executed upon completion. Receives `err` and the `doc(s)`.
4239
4242
  * @return {Promise}
4240
4243
  * @api public
@@ -4245,67 +4248,34 @@ Model.populate = async function populate(docs, paths) {
4245
4248
  if (typeof paths === 'function' || typeof arguments[2] === 'function') {
4246
4249
  throw new MongooseError('Model.populate() no longer accepts a callback');
4247
4250
  }
4248
- const _this = this;
4249
4251
  // normalized paths
4250
4252
  paths = utils.populate(paths);
4251
- // data that should persist across subPopulate calls
4252
- const cache = {};
4253
-
4254
- return new Promise((resolve, reject) => {
4255
- _populate(_this, docs, paths, cache, (err, res) => {
4256
- if (err) {
4257
- return reject(err);
4258
- }
4259
- resolve(res);
4260
- });
4261
- });
4262
- };
4263
-
4264
- /**
4265
- * Populate helper
4266
- *
4267
- * @param {Model} model the model to use
4268
- * @param {Document|Array} docs Either a single document or array of documents to populate.
4269
- * @param {Object} paths
4270
- * @param {never} cache Unused
4271
- * @param {Function} [callback] Optional callback, executed upon completion. Receives `err` and the `doc(s)`.
4272
- * @return {Function}
4273
- * @api private
4274
- */
4275
4253
 
4276
- function _populate(model, docs, paths, cache, callback) {
4277
- let pending = paths.length;
4278
4254
  if (paths.length === 0) {
4279
- return callback(null, docs);
4255
+ return docs;
4280
4256
  }
4257
+
4281
4258
  // each path has its own query options and must be executed separately
4259
+ const promises = [];
4282
4260
  for (const path of paths) {
4283
- populate(model, docs, path, next);
4261
+ promises.push(_populatePath(this, docs, path));
4284
4262
  }
4263
+ await Promise.all(promises);
4285
4264
 
4286
- function next(err) {
4287
- if (err) {
4288
- return callback(err, null);
4289
- }
4290
- if (--pending) {
4291
- return;
4292
- }
4293
- callback(null, docs);
4294
- }
4295
- }
4265
+ return docs;
4266
+ };
4296
4267
 
4297
4268
  /*!
4298
- * Populates `docs`
4269
+ * Populates `docs` for a single `populateOptions` instance.
4299
4270
  */
4300
4271
  const excludeIdReg = /\s?-_id\s?/;
4301
4272
  const excludeIdRegGlobal = /\s?-_id\s?/g;
4302
4273
 
4303
- function populate(model, docs, options, callback) {
4304
- const populateOptions = options;
4305
- if (options.strictPopulate == null) {
4306
- if (options._localModel != null && options._localModel.schema._userProvidedOptions.strictPopulate != null) {
4307
- populateOptions.strictPopulate = options._localModel.schema._userProvidedOptions.strictPopulate;
4308
- } else if (options._localModel != null && model.base.options.strictPopulate != null) {
4274
+ async function _populatePath(model, docs, populateOptions) {
4275
+ if (populateOptions.strictPopulate == null) {
4276
+ if (populateOptions._localModel != null && populateOptions._localModel.schema._userProvidedOptions.strictPopulate != null) {
4277
+ populateOptions.strictPopulate = populateOptions._localModel.schema._userProvidedOptions.strictPopulate;
4278
+ } else if (populateOptions._localModel != null && model.base.options.strictPopulate != null) {
4309
4279
  populateOptions.strictPopulate = model.base.options.strictPopulate;
4310
4280
  } else if (model.base.options.strictPopulate != null) {
4311
4281
  populateOptions.strictPopulate = model.base.options.strictPopulate;
@@ -4317,15 +4287,12 @@ function populate(model, docs, options, callback) {
4317
4287
  docs = [docs];
4318
4288
  }
4319
4289
  if (docs.length === 0 || docs.every(utils.isNullOrUndefined)) {
4320
- return callback();
4290
+ return;
4321
4291
  }
4322
4292
 
4323
4293
  const modelsMap = getModelsMapForPopulate(model, docs, populateOptions);
4324
-
4325
4294
  if (modelsMap instanceof MongooseError) {
4326
- return immediate(function() {
4327
- callback(modelsMap);
4328
- });
4295
+ throw modelsMap;
4329
4296
  }
4330
4297
  const len = modelsMap.length;
4331
4298
  let vals = [];
@@ -4335,7 +4302,6 @@ function populate(model, docs, options, callback) {
4335
4302
  return undefined !== item;
4336
4303
  }
4337
4304
 
4338
- let _remaining = len;
4339
4305
  let hasOne = false;
4340
4306
  const params = [];
4341
4307
  for (let i = 0; i < len; ++i) {
@@ -4366,7 +4332,6 @@ function populate(model, docs, options, callback) {
4366
4332
  // Ensure that we set to 0 or empty array even
4367
4333
  // if we don't actually execute a query to make sure there's a value
4368
4334
  // and we know this path was populated for future sets. See gh-7731, gh-8230
4369
- --_remaining;
4370
4335
  _assign(model, [], mod, assignmentOpts);
4371
4336
  continue;
4372
4337
  }
@@ -4397,64 +4362,50 @@ function populate(model, docs, options, callback) {
4397
4362
  } else if (mod.options.limit != null) {
4398
4363
  assignmentOpts.originalLimit = mod.options.limit;
4399
4364
  }
4400
- params.push([mod, match, select, assignmentOpts, _next]);
4365
+ params.push([mod, match, select, assignmentOpts]);
4401
4366
  }
4402
4367
  if (!hasOne) {
4403
4368
  // If models but no docs, skip further deep populate.
4404
4369
  if (modelsMap.length !== 0) {
4405
- return callback();
4370
+ return;
4406
4371
  }
4407
- // If no models to populate but we have a nested populate,
4408
- // keep trying, re: gh-8946
4372
+ // If no models and no docs to populate but we have a nested populate,
4373
+ // probably a case of unnecessarily populating a non-ref path re: gh-8946
4409
4374
  if (populateOptions.populate != null) {
4410
4375
  const opts = utils.populate(populateOptions.populate).map(pop => Object.assign({}, pop, {
4411
4376
  path: populateOptions.path + '.' + pop.path
4412
4377
  }));
4413
- model.populate(docs, opts).then(res => { callback(null, res); }, err => { callback(err); });
4414
- return;
4378
+ return model.populate(docs, opts);
4415
4379
  }
4416
- return callback();
4380
+ return;
4417
4381
  }
4418
4382
 
4383
+ const promises = [];
4419
4384
  for (const arr of params) {
4420
- _execPopulateQuery.apply(null, arr);
4421
- }
4422
- function _next(err, valsFromDb) {
4423
- if (err != null) {
4424
- return callback(err, null);
4425
- }
4426
- vals = vals.concat(valsFromDb);
4427
- if (--_remaining === 0) {
4428
- _done();
4429
- }
4385
+ promises.push(_execPopulateQuery.apply(null, arr).then(valsFromDb => { vals = vals.concat(valsFromDb); }));
4430
4386
  }
4431
4387
 
4432
- function _done() {
4433
- for (const arr of params) {
4434
- const mod = arr[0];
4435
- const assignmentOpts = arr[3];
4436
- for (const val of vals) {
4437
- mod.options._childDocs.push(val);
4438
- }
4439
- try {
4440
- _assign(model, vals, mod, assignmentOpts);
4441
- } catch (err) {
4442
- return callback(err);
4443
- }
4444
- }
4388
+ await Promise.all(promises);
4445
4389
 
4446
- for (const arr of params) {
4447
- removeDeselectedForeignField(arr[0].foreignField, arr[0].options, vals);
4390
+ for (const arr of params) {
4391
+ const mod = arr[0];
4392
+ const assignmentOpts = arr[3];
4393
+ for (const val of vals) {
4394
+ mod.options._childDocs.push(val);
4448
4395
  }
4449
- for (const arr of params) {
4450
- const mod = arr[0];
4451
- if (mod.options && mod.options.options && mod.options.options._leanTransform) {
4452
- for (const doc of vals) {
4453
- mod.options.options._leanTransform(doc);
4454
- }
4396
+ _assign(model, vals, mod, assignmentOpts);
4397
+ }
4398
+
4399
+ for (const arr of params) {
4400
+ removeDeselectedForeignField(arr[0].foreignField, arr[0].options, vals);
4401
+ }
4402
+ for (const arr of params) {
4403
+ const mod = arr[0];
4404
+ if (mod.options && mod.options.options && mod.options.options._leanTransform) {
4405
+ for (const doc of vals) {
4406
+ mod.options.options._leanTransform(doc);
4455
4407
  }
4456
4408
  }
4457
- callback();
4458
4409
  }
4459
4410
  }
4460
4411
 
@@ -4462,7 +4413,7 @@ function populate(model, docs, options, callback) {
4462
4413
  * ignore
4463
4414
  */
4464
4415
 
4465
- function _execPopulateQuery(mod, match, select, assignmentOpts, callback) {
4416
+ function _execPopulateQuery(mod, match, select) {
4466
4417
  let subPopulate = clone(mod.options.populate);
4467
4418
  const queryOptions = Object.assign({
4468
4419
  skip: mod.options.skip,
@@ -4528,15 +4479,12 @@ function _execPopulateQuery(mod, match, select, assignmentOpts, callback) {
4528
4479
  query.populate(subPopulate);
4529
4480
  }
4530
4481
 
4531
- query.exec().then(
4482
+ return query.exec().then(
4532
4483
  docs => {
4533
4484
  for (const val of docs) {
4534
4485
  leanPopulateMap.set(val, mod.model);
4535
4486
  }
4536
- callback(null, docs);
4537
- },
4538
- err => {
4539
- callback(err);
4487
+ return docs;
4540
4488
  }
4541
4489
  );
4542
4490
  }
@@ -4934,6 +4882,23 @@ Model.inspect = function() {
4934
4882
  return `Model { ${this.modelName} }`;
4935
4883
  };
4936
4884
 
4885
+ /**
4886
+ * Return the MongoDB namespace for this model as a string. The namespace is the database name, followed by '.', followed by the collection name.
4887
+ *
4888
+ * #### Example:
4889
+ *
4890
+ * const conn = mongoose.createConnection('mongodb://127.0.0.1:27017/mydb');
4891
+ * const TestModel = conn.model('Test', mongoose.Schema({ name: String }));
4892
+ *
4893
+ * TestModel.namespace(); // 'mydb.tests'
4894
+ *
4895
+ * @api public
4896
+ */
4897
+
4898
+ Model.namespace = function namespace() {
4899
+ return this.db.name + '.' + this.collection.collectionName;
4900
+ };
4901
+
4937
4902
  if (util.inspect.custom) {
4938
4903
  // Avoid Node deprecation warning DEP0079
4939
4904
  Model[util.inspect.custom] = Model.inspect;
package/lib/mongoose.js CHANGED
@@ -987,6 +987,7 @@ Mongoose.prototype.VirtualType = VirtualType;
987
987
  * - [ObjectId](https://mongoosejs.com/docs/schematypes.html#objectids)
988
988
  * - [Map](https://mongoosejs.com/docs/schematypes.html#maps)
989
989
  * - [Subdocument](https://mongoosejs.com/docs/schematypes.html#schemas)
990
+ * - [Int32](https://mongoosejs.com/docs/schematypes.html#int32)
990
991
  *
991
992
  * Using this exposed access to the `ObjectId` type, we can construct ids on demand.
992
993
  *
@@ -1138,6 +1139,7 @@ Mongoose.prototype.syncIndexes = function(options) {
1138
1139
 
1139
1140
  Mongoose.prototype.Decimal128 = SchemaTypes.Decimal128;
1140
1141
 
1142
+
1141
1143
  /**
1142
1144
  * The Mongoose Mixed [SchemaType](https://mongoosejs.com/docs/schematypes.html). Used for
1143
1145
  * declaring paths in your schema that Mongoose's change tracking, casting,
package/lib/query.js CHANGED
@@ -2381,6 +2381,7 @@ Query.prototype._find = async function _find() {
2381
2381
  _completeManyLean(_this.model.schema, docs, null, completeManyOptions) :
2382
2382
  _this._completeMany(docs, fields, userProvidedFields, completeManyOptions);
2383
2383
  }
2384
+
2384
2385
  const pop = helpers.preparePopulationOptionsMQ(_this, mongooseOptions);
2385
2386
 
2386
2387
  if (mongooseOptions.lean) {
@@ -4466,6 +4467,8 @@ Query.prototype.exec = async function exec(op) {
4466
4467
  } else {
4467
4468
  error = err;
4468
4469
  }
4470
+
4471
+ error = this.model.schema._transformDuplicateKeyError(error);
4469
4472
  }
4470
4473
 
4471
4474
  res = await _executePostHooks(this, res, error);
@@ -4762,12 +4765,13 @@ Query.prototype._castUpdate = function _castUpdate(obj) {
4762
4765
  */
4763
4766
 
4764
4767
  Query.prototype.populate = function() {
4768
+ const args = Array.from(arguments);
4765
4769
  // Bail when given no truthy arguments
4766
- if (!Array.from(arguments).some(Boolean)) {
4770
+ if (!args.some(Boolean)) {
4767
4771
  return this;
4768
4772
  }
4769
4773
 
4770
- const res = utils.populate.apply(null, arguments);
4774
+ const res = utils.populate.apply(null, args);
4771
4775
 
4772
4776
  // Propagate readConcern and readPreference and lean from parent query,
4773
4777
  // unless one already specified
@@ -4,6 +4,7 @@
4
4
  * Module dependencies
5
5
  */
6
6
 
7
+ const PopulateOptions = require('./options/populateOptions');
7
8
  const checkEmbeddedDiscriminatorKeyProjection =
8
9
  require('./helpers/discriminator/checkEmbeddedDiscriminatorKeyProjection');
9
10
  const get = require('./helpers/get');
@@ -13,32 +14,6 @@ const isDefiningProjection = require('./helpers/projection/isDefiningProjection'
13
14
  const clone = require('./helpers/clone');
14
15
  const isPathSelectedInclusive = require('./helpers/projection/isPathSelectedInclusive');
15
16
 
16
- /**
17
- * Prepare a set of path options for query population.
18
- *
19
- * @param {Query} query
20
- * @param {Object} options
21
- * @return {Array}
22
- */
23
-
24
- exports.preparePopulationOptions = function preparePopulationOptions(query, options) {
25
- const _populate = query.options.populate;
26
- const pop = Object.keys(_populate).reduce((vals, key) => vals.concat([_populate[key]]), []);
27
-
28
- // lean options should trickle through all queries
29
- if (options.lean != null) {
30
- pop
31
- .filter(p => (p && p.options && p.options.lean) == null)
32
- .forEach(makeLean(options.lean));
33
- }
34
-
35
- pop.forEach(opts => {
36
- opts._localModel = query.model;
37
- });
38
-
39
- return pop;
40
- };
41
-
42
17
  /**
43
18
  * Prepare a set of path options for query population. This is the MongooseQuery
44
19
  * version
@@ -73,12 +48,18 @@ exports.preparePopulationOptionsMQ = function preparePopulationOptionsMQ(query,
73
48
  }
74
49
 
75
50
  const projection = query._fieldsForExec();
76
- pop.forEach(p => {
77
- p._queryProjection = projection;
78
- });
79
- pop.forEach(opts => {
80
- opts._localModel = query.model;
81
- });
51
+ for (let i = 0; i < pop.length; ++i) {
52
+ if (pop[i] instanceof PopulateOptions) {
53
+ pop[i] = new PopulateOptions({
54
+ ...pop[i],
55
+ _queryProjection: projection,
56
+ _localModel: query.model
57
+ });
58
+ } else {
59
+ pop[i]._queryProjection = projection;
60
+ pop[i]._localModel = query.model;
61
+ }
62
+ }
82
63
 
83
64
  return pop;
84
65
  };
@@ -81,12 +81,12 @@ SchemaBigInt.setters = [];
81
81
  SchemaBigInt.get = SchemaType.get;
82
82
 
83
83
  /**
84
- * Get/set the function used to cast arbitrary values to booleans.
84
+ * Get/set the function used to cast arbitrary values to bigints.
85
85
  *
86
86
  * #### Example:
87
87
  *
88
88
  * // Make Mongoose cast empty string '' to false.
89
- * const original = mongoose.Schema.BigInt.cast();
89
+ * const original = mongoose.Schema.Types.BigInt.cast();
90
90
  * mongoose.Schema.BigInt.cast(v => {
91
91
  * if (v === '') {
92
92
  * return false;
@@ -0,0 +1,212 @@
1
+ 'use strict';
2
+
3
+ /*!
4
+ * Module dependencies.
5
+ */
6
+
7
+ const CastError = require('../error/cast');
8
+ const SchemaType = require('../schemaType');
9
+ const castDouble = require('../cast/double');
10
+
11
+ /**
12
+ * Double SchemaType constructor.
13
+ *
14
+ * @param {String} path
15
+ * @param {Object} options
16
+ * @inherits SchemaType
17
+ * @api public
18
+ */
19
+
20
+ function SchemaDouble(path, options) {
21
+ SchemaType.call(this, path, options, 'Double');
22
+ }
23
+
24
+ /**
25
+ * This schema type's name, to defend against minifiers that mangle
26
+ * function names.
27
+ *
28
+ * @api public
29
+ */
30
+ SchemaDouble.schemaName = 'Double';
31
+
32
+ SchemaDouble.defaultOptions = {};
33
+
34
+ /*!
35
+ * Inherits from SchemaType.
36
+ */
37
+ SchemaDouble.prototype = Object.create(SchemaType.prototype);
38
+ SchemaDouble.prototype.constructor = SchemaDouble;
39
+
40
+ /*!
41
+ * ignore
42
+ */
43
+
44
+ SchemaDouble._cast = castDouble;
45
+
46
+ /**
47
+ * Sets a default option for all Double instances.
48
+ *
49
+ * #### Example:
50
+ *
51
+ * // Make all Double fields required by default
52
+ * mongoose.Schema.Double.set('required', true);
53
+ *
54
+ * @param {String} option The option you'd like to set the value for
55
+ * @param {Any} value value for option
56
+ * @return {undefined}
57
+ * @function set
58
+ * @static
59
+ * @api public
60
+ */
61
+
62
+ SchemaDouble.set = SchemaType.set;
63
+
64
+ SchemaDouble.setters = [];
65
+
66
+ /**
67
+ * Attaches a getter for all Double instances
68
+ *
69
+ * #### Example:
70
+ *
71
+ * // Converts Double to be a represent milliseconds upon access
72
+ * mongoose.Schema.Double.get(v => v == null ? '0.000 ms' : v.toString() + ' ms');
73
+ *
74
+ * @param {Function} getter
75
+ * @return {this}
76
+ * @function get
77
+ * @static
78
+ * @api public
79
+ */
80
+
81
+ SchemaDouble.get = SchemaType.get;
82
+
83
+ /*!
84
+ * ignore
85
+ */
86
+
87
+ SchemaDouble._defaultCaster = v => {
88
+ if (v != null) {
89
+ if (v._bsontype !== 'Double') {
90
+ throw new Error();
91
+ }
92
+ }
93
+
94
+ return v;
95
+ };
96
+
97
+ /**
98
+ * Get/set the function used to cast arbitrary values to IEEE 754-2008 floating points
99
+ *
100
+ * #### Example:
101
+ *
102
+ * // Make Mongoose cast any NaNs to 0
103
+ * const defaultCast = mongoose.Schema.Types.Double.cast();
104
+ * mongoose.Schema.Types.Double.cast(v => {
105
+ * if (isNaN(v)) {
106
+ * return 0;
107
+ * }
108
+ * return defaultCast(v);
109
+ * });
110
+ *
111
+ * // Or disable casting for Doubles entirely (only JS numbers are permitted)
112
+ * mongoose.Schema.Double.cast(false);
113
+ *
114
+ *
115
+ * @param {Function} caster
116
+ * @return {Function}
117
+ * @function get
118
+ * @static
119
+ * @api public
120
+ */
121
+
122
+ SchemaDouble.cast = function cast(caster) {
123
+ if (arguments.length === 0) {
124
+ return this._cast;
125
+ }
126
+ if (caster === false) {
127
+ caster = this._defaultCaster;
128
+ }
129
+
130
+ this._cast = caster;
131
+
132
+ return this._cast;
133
+ };
134
+
135
+
136
+ /*!
137
+ * ignore
138
+ */
139
+
140
+ SchemaDouble._checkRequired = v => v != null;
141
+ /**
142
+ * Override the function the required validator uses to check whether a value
143
+ * passes the `required` check.
144
+ *
145
+ * @param {Function} fn
146
+ * @return {Function}
147
+ * @function checkRequired
148
+ * @static
149
+ * @api public
150
+ */
151
+
152
+ SchemaDouble.checkRequired = SchemaType.checkRequired;
153
+
154
+ /**
155
+ * Check if the given value satisfies a required validator.
156
+ *
157
+ * @param {Any} value
158
+ * @return {Boolean}
159
+ * @api public
160
+ */
161
+
162
+ SchemaDouble.prototype.checkRequired = function(value) {
163
+ return this.constructor._checkRequired(value);
164
+ };
165
+
166
+ /**
167
+ * Casts to Double
168
+ *
169
+ * @param {Object} value
170
+ * @param {Object} model this value is optional
171
+ * @api private
172
+ */
173
+
174
+ SchemaDouble.prototype.cast = function(value) {
175
+ let castDouble;
176
+ if (typeof this._castFunction === 'function') {
177
+ castDouble = this._castFunction;
178
+ } else if (typeof this.constructor.cast === 'function') {
179
+ castDouble = this.constructor.cast();
180
+ } else {
181
+ castDouble = SchemaDouble.cast();
182
+ }
183
+
184
+ try {
185
+ return castDouble(value);
186
+ } catch (error) {
187
+ throw new CastError('Double', value, this.path, error, this);
188
+ }
189
+ };
190
+
191
+ /*!
192
+ * ignore
193
+ */
194
+
195
+ function handleSingle(val) {
196
+ return this.cast(val);
197
+ }
198
+
199
+ SchemaDouble.prototype.$conditionalHandlers = {
200
+ ...SchemaType.prototype.$conditionalHandlers,
201
+ $gt: handleSingle,
202
+ $gte: handleSingle,
203
+ $lt: handleSingle,
204
+ $lte: handleSingle
205
+ };
206
+
207
+
208
+ /*!
209
+ * Module exports.
210
+ */
211
+
212
+ module.exports = SchemaDouble;
@@ -19,6 +19,8 @@ exports.ObjectId = require('./objectId');
19
19
  exports.String = require('./string');
20
20
  exports.Subdocument = require('./subdocument');
21
21
  exports.UUID = require('./uuid');
22
+ exports.Double = require('./double');
23
+ exports.Int32 = require('./int32');
22
24
 
23
25
  // alias
24
26