mongoose 8.9.7 → 8.10.1

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/query.js CHANGED
@@ -65,6 +65,25 @@ const queryOptionMethods = new Set([
65
65
  'wtimeout'
66
66
  ]);
67
67
 
68
+ // Map from operation name to the name of the function that executes the actual operation against MongoDB.
69
+ // Called a thunk for legacy reasons, "thunk" means function that takes exactly 1 param, a callback.
70
+ // Currently `_countDocuments()`, etc. are async functions that take no params.
71
+ const opToThunk = new Map([
72
+ ['countDocuments', '_countDocuments'],
73
+ ['distinct', '__distinct'],
74
+ ['estimatedDocumentCount', '_estimatedDocumentCount'],
75
+ ['find', '_find'],
76
+ ['findOne', '_findOne'],
77
+ ['findOneAndReplace', '_findOneAndReplace'],
78
+ ['findOneAndUpdate', '_findOneAndUpdate'],
79
+ ['replaceOne', '_replaceOne'],
80
+ ['updateMany', '_updateMany'],
81
+ ['updateOne', '_updateOne'],
82
+ ['deleteMany', '_deleteMany'],
83
+ ['deleteOne', '_deleteOne'],
84
+ ['findOneAndDelete', '_findOneAndDelete']
85
+ ]);
86
+
68
87
  /**
69
88
  * Query constructor used for building queries. You do not need
70
89
  * to instantiate a `Query` directly. Instead use Model functions like
@@ -2337,18 +2356,17 @@ Query.prototype._find = async function _find() {
2337
2356
  }
2338
2357
 
2339
2358
  const mongooseOptions = this._mongooseOptions;
2340
- const _this = this;
2341
- const userProvidedFields = _this._userProvidedFields || {};
2359
+ const userProvidedFields = this._userProvidedFields || {};
2342
2360
 
2343
2361
  applyGlobalMaxTimeMS(this.options, this.model.db.options, this.model.base.options);
2344
2362
  applyGlobalDiskUse(this.options, this.model.db.options, this.model.base.options);
2345
2363
 
2346
2364
  // Separate options to pass down to `completeMany()` in case we need to
2347
2365
  // set a session on the document
2348
- const completeManyOptions = Object.assign({}, {
2366
+ const completeManyOptions = {
2349
2367
  session: this && this.options && this.options.session || null,
2350
2368
  lean: mongooseOptions.lean || null
2351
- });
2369
+ };
2352
2370
 
2353
2371
  const options = this._optionsForExec();
2354
2372
 
@@ -2366,7 +2384,7 @@ Query.prototype._find = async function _find() {
2366
2384
  }
2367
2385
 
2368
2386
  if (!mongooseOptions.populate) {
2369
- const versionKey = _this.schema.options.versionKey;
2387
+ const versionKey = this.schema.options.versionKey;
2370
2388
  if (mongooseOptions.lean && mongooseOptions.lean.versionKey === false && versionKey) {
2371
2389
  docs.forEach((doc) => {
2372
2390
  if (versionKey in doc) {
@@ -2375,17 +2393,17 @@ Query.prototype._find = async function _find() {
2375
2393
  });
2376
2394
  }
2377
2395
  return mongooseOptions.lean ?
2378
- _completeManyLean(_this.model.schema, docs, null, completeManyOptions) :
2379
- _this._completeMany(docs, fields, userProvidedFields, completeManyOptions);
2396
+ _completeManyLean(this.model.schema, docs, null, completeManyOptions) :
2397
+ this._completeMany(docs, fields, userProvidedFields, completeManyOptions);
2380
2398
  }
2381
2399
 
2382
- const pop = helpers.preparePopulationOptionsMQ(_this, mongooseOptions);
2400
+ const pop = helpers.preparePopulationOptionsMQ(this, mongooseOptions);
2383
2401
 
2384
2402
  if (mongooseOptions.lean) {
2385
- return _this.model.populate(docs, pop);
2403
+ return this.model.populate(docs, pop);
2386
2404
  }
2387
2405
 
2388
- docs = await _this._completeMany(docs, fields, userProvidedFields, completeManyOptions);
2406
+ docs = await this._completeMany(docs, fields, userProvidedFields, completeManyOptions);
2389
2407
  await this.model.populate(docs, pop);
2390
2408
 
2391
2409
  return docs;
@@ -3992,6 +4010,10 @@ Query.prototype._replaceOne = async function _replaceOne() {
3992
4010
  * res.n; // Number of documents matched
3993
4011
  * res.nModified; // Number of documents modified
3994
4012
  *
4013
+ * // Other supported syntaxes
4014
+ * await Person.find({ name: /Stark$/ }).updateMany({ isDeleted: true }); // Using chaining syntax
4015
+ * await Person.find().updateMany({ isDeleted: true }); // Set `isDeleted` on _all_ Person documents
4016
+ *
3995
4017
  * This function triggers the following middleware.
3996
4018
  *
3997
4019
  * - `updateMany()`
@@ -4062,6 +4084,10 @@ Query.prototype.updateMany = function(conditions, doc, options, callback) {
4062
4084
  * res.upsertedCount; // Number of documents that were upserted
4063
4085
  * res.upsertedId; // Identifier of the inserted document (if an upsert took place)
4064
4086
  *
4087
+ * // Other supported syntaxes
4088
+ * await Person.findOne({ name: 'Jean-Luc Picard' }).updateOne({ ship: 'USS Enterprise' }); // Using chaining syntax
4089
+ * await Person.updateOne({ ship: 'USS Enterprise' }); // Updates first doc's `ship` property
4090
+ *
4065
4091
  * This function triggers the following middleware.
4066
4092
  *
4067
4093
  * - `updateOne()`
@@ -4389,22 +4415,14 @@ Query.prototype.exec = async function exec(op) {
4389
4415
  if (this.model == null) {
4390
4416
  throw new MongooseError('Query must have an associated model before executing');
4391
4417
  }
4392
- this._validateOp();
4393
4418
 
4394
- if (!this.op) {
4395
- return;
4419
+ const thunk = opToThunk.get(this.op);
4420
+ if (!thunk) {
4421
+ throw new MongooseError('Query has invalid `op`: "' + this.op + '"');
4396
4422
  }
4397
4423
 
4398
- if (this.options && this.options.sort) {
4399
- const keys = Object.keys(this.options.sort);
4400
- if (keys.includes('')) {
4401
- throw new Error('Invalid field "" passed to sort()');
4402
- }
4403
- }
4404
-
4405
- let thunk = '_' + this.op;
4406
- if (this.op === 'distinct') {
4407
- thunk = '__distinct';
4424
+ if (this.options && this.options.sort && typeof this.options.sort === 'object' && this.options.sort.hasOwnProperty('')) {
4425
+ throw new Error('Invalid field "" passed to sort()');
4408
4426
  }
4409
4427
 
4410
4428
  if (this._executionStack != null) {
@@ -21,6 +21,7 @@ const isOperator = require('../helpers/query/isOperator');
21
21
  const util = require('util');
22
22
  const utils = require('../utils');
23
23
  const castToNumber = require('./operators/helpers').castToNumber;
24
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
24
25
  const geospatial = require('./operators/geospatial');
25
26
  const getDiscriminatorByValue = require('../helpers/discriminator/getDiscriminatorByValue');
26
27
 
@@ -403,6 +404,9 @@ SchemaArray.prototype.cast = function(value, doc, init, prev, options) {
403
404
  opts.arrayPathIndex = i;
404
405
  }
405
406
  }
407
+ if (options.hydratedPopulatedDocs) {
408
+ opts.hydratedPopulatedDocs = options.hydratedPopulatedDocs;
409
+ }
406
410
  rawValue[i] = caster.applySetters(rawValue[i], doc, init, void 0, opts);
407
411
  }
408
412
  } catch (e) {
@@ -697,6 +701,23 @@ handle.$ne = SchemaArray.prototype._castForQuery;
697
701
  handle.$nin = SchemaType.prototype.$conditionalHandlers.$nin;
698
702
  handle.$in = SchemaType.prototype.$conditionalHandlers.$in;
699
703
 
704
+ /**
705
+ * Returns this schema type's representation in a JSON schema.
706
+ *
707
+ * @param [options]
708
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
709
+ * @returns {Object} JSON schema properties
710
+ */
711
+
712
+ SchemaArray.prototype.toJSONSchema = function toJSONSchema(options) {
713
+ const embeddedSchemaType = this.getEmbeddedSchemaType();
714
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
715
+ return {
716
+ ...createJSONSchemaTypeDefinition('array', 'array', options?.useBsonType, isRequired),
717
+ items: embeddedSchemaType.toJSONSchema(options)
718
+ };
719
+ };
720
+
700
721
  /*!
701
722
  * Module exports.
702
723
  */
@@ -7,6 +7,7 @@
7
7
  const CastError = require('../error/cast');
8
8
  const SchemaType = require('../schemaType');
9
9
  const castBigInt = require('../cast/bigint');
10
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
10
11
 
11
12
  /**
12
13
  * BigInt SchemaType constructor.
@@ -240,6 +241,19 @@ SchemaBigInt.prototype._castNullish = function _castNullish(v) {
240
241
  return v;
241
242
  };
242
243
 
244
+ /**
245
+ * Returns this schema type's representation in a JSON schema.
246
+ *
247
+ * @param [options]
248
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
249
+ * @returns {Object} JSON schema properties
250
+ */
251
+
252
+ SchemaBigInt.prototype.toJSONSchema = function toJSONSchema(options) {
253
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
254
+ return createJSONSchemaTypeDefinition('string', 'long', options?.useBsonType, isRequired);
255
+ };
256
+
243
257
  /*!
244
258
  * Module exports.
245
259
  */
@@ -7,6 +7,7 @@
7
7
  const CastError = require('../error/cast');
8
8
  const SchemaType = require('../schemaType');
9
9
  const castBoolean = require('../cast/boolean');
10
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
10
11
 
11
12
  /**
12
13
  * Boolean SchemaType constructor.
@@ -290,6 +291,19 @@ SchemaBoolean.prototype._castNullish = function _castNullish(v) {
290
291
  return v;
291
292
  };
292
293
 
294
+ /**
295
+ * Returns this schema type's representation in a JSON schema.
296
+ *
297
+ * @param [options]
298
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
299
+ * @returns {Object} JSON schema properties
300
+ */
301
+
302
+ SchemaBoolean.prototype.toJSONSchema = function toJSONSchema(options) {
303
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
304
+ return createJSONSchemaTypeDefinition('boolean', 'bool', options?.useBsonType, isRequired);
305
+ };
306
+
293
307
  /*!
294
308
  * Module exports.
295
309
  */
@@ -7,6 +7,7 @@
7
7
  const MongooseBuffer = require('../types/buffer');
8
8
  const SchemaBufferOptions = require('../options/schemaBufferOptions');
9
9
  const SchemaType = require('../schemaType');
10
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
10
11
  const handleBitwiseOperator = require('./operators/bitwise');
11
12
  const utils = require('../utils');
12
13
 
@@ -140,7 +141,7 @@ SchemaBuffer.prototype.checkRequired = function(value, doc) {
140
141
  * @api private
141
142
  */
142
143
 
143
- SchemaBuffer.prototype.cast = function(value, doc, init) {
144
+ SchemaBuffer.prototype.cast = function(value, doc, init, prev, options) {
144
145
  let ret;
145
146
  if (SchemaType._isRef(this, value, doc, init)) {
146
147
  if (value && value.isMongooseBuffer) {
@@ -167,7 +168,7 @@ SchemaBuffer.prototype.cast = function(value, doc, init) {
167
168
  }
168
169
 
169
170
  if (value == null || utils.isNonBuiltinObject(value)) {
170
- return this._castRef(value, doc, init);
171
+ return this._castRef(value, doc, init, options);
171
172
  }
172
173
  }
173
174
 
@@ -300,6 +301,19 @@ SchemaBuffer.prototype.castForQuery = function($conditional, val, context) {
300
301
  return casted ? casted.toObject({ transform: false, virtuals: false }) : casted;
301
302
  };
302
303
 
304
+ /**
305
+ * Returns this schema type's representation in a JSON schema.
306
+ *
307
+ * @param [options]
308
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
309
+ * @returns {Object} JSON schema properties
310
+ */
311
+
312
+ SchemaBuffer.prototype.toJSONSchema = function toJSONSchema(options) {
313
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
314
+ return createJSONSchemaTypeDefinition('string', 'binData', options?.useBsonType, isRequired);
315
+ };
316
+
303
317
  /*!
304
318
  * Module exports.
305
319
  */
@@ -8,6 +8,7 @@ const MongooseError = require('../error/index');
8
8
  const SchemaDateOptions = require('../options/schemaDateOptions');
9
9
  const SchemaType = require('../schemaType');
10
10
  const castDate = require('../cast/date');
11
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
11
12
  const getConstructorName = require('../helpers/getConstructorName');
12
13
  const utils = require('../utils');
13
14
 
@@ -426,6 +427,19 @@ SchemaDate.prototype.castForQuery = function($conditional, val, context) {
426
427
  return handler.call(this, val);
427
428
  };
428
429
 
430
+ /**
431
+ * Returns this schema type's representation in a JSON schema.
432
+ *
433
+ * @param [options]
434
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
435
+ * @returns {Object} JSON schema properties
436
+ */
437
+
438
+ SchemaDate.prototype.toJSONSchema = function toJSONSchema(options) {
439
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
440
+ return createJSONSchemaTypeDefinition('string', 'date', options?.useBsonType, isRequired);
441
+ };
442
+
429
443
  /*!
430
444
  * Module exports.
431
445
  */
@@ -7,6 +7,7 @@
7
7
  const SchemaType = require('../schemaType');
8
8
  const CastError = SchemaType.CastError;
9
9
  const castDecimal128 = require('../cast/decimal128');
10
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
10
11
  const isBsonType = require('../helpers/isBsonType');
11
12
 
12
13
  /**
@@ -180,13 +181,13 @@ SchemaDecimal128.prototype.checkRequired = function checkRequired(value, doc) {
180
181
  * @api private
181
182
  */
182
183
 
183
- SchemaDecimal128.prototype.cast = function(value, doc, init) {
184
+ SchemaDecimal128.prototype.cast = function(value, doc, init, prev, options) {
184
185
  if (SchemaType._isRef(this, value, doc, init)) {
185
186
  if (isBsonType(value, 'Decimal128')) {
186
187
  return value;
187
188
  }
188
189
 
189
- return this._castRef(value, doc, init);
190
+ return this._castRef(value, doc, init, options);
190
191
  }
191
192
 
192
193
  let castDecimal128;
@@ -221,6 +222,19 @@ SchemaDecimal128.prototype.$conditionalHandlers = {
221
222
  $lte: handleSingle
222
223
  };
223
224
 
225
+ /**
226
+ * Returns this schema type's representation in a JSON schema.
227
+ *
228
+ * @param [options]
229
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
230
+ * @returns {Object} JSON schema properties
231
+ */
232
+
233
+ SchemaDecimal128.prototype.toJSONSchema = function toJSONSchema(options) {
234
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
235
+ return createJSONSchemaTypeDefinition('string', 'decimal', options?.useBsonType, isRequired);
236
+ };
237
+
224
238
  /*!
225
239
  * Module exports.
226
240
  */
@@ -12,6 +12,7 @@ const SchemaDocumentArrayOptions =
12
12
  require('../options/schemaDocumentArrayOptions');
13
13
  const SchemaType = require('../schemaType');
14
14
  const cast = require('../cast');
15
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
15
16
  const discriminator = require('../helpers/model/discriminator');
16
17
  const handleIdOption = require('../helpers/schema/handleIdOption');
17
18
  const handleSpreadDoc = require('../helpers/document/handleSpreadDoc');
@@ -651,6 +652,23 @@ function cast$elemMatch(val, context) {
651
652
  return cast(schema, val, null, this && this.$$context);
652
653
  }
653
654
 
655
+ /**
656
+ * Returns this schema type's representation in a JSON schema.
657
+ *
658
+ * @param [options]
659
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
660
+ * @returns {Object} JSON schema properties
661
+ */
662
+
663
+ SchemaDocumentArray.prototype.toJSONSchema = function toJSONSchema(options) {
664
+ const itemsTypeDefinition = createJSONSchemaTypeDefinition('object', 'object', options?.useBsonType, false);
665
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
666
+ return {
667
+ ...createJSONSchemaTypeDefinition('array', 'array', options?.useBsonType, isRequired),
668
+ items: { ...itemsTypeDefinition, ...this.schema.toJSONSchema(options) }
669
+ };
670
+ };
671
+
654
672
  /*!
655
673
  * Module exports.
656
674
  */
@@ -7,6 +7,7 @@
7
7
  const CastError = require('../error/cast');
8
8
  const SchemaType = require('../schemaType');
9
9
  const castDouble = require('../cast/double');
10
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
10
11
 
11
12
  /**
12
13
  * Double SchemaType constructor.
@@ -204,6 +205,18 @@ SchemaDouble.prototype.$conditionalHandlers = {
204
205
  $lte: handleSingle
205
206
  };
206
207
 
208
+ /**
209
+ * Returns this schema type's representation in a JSON schema.
210
+ *
211
+ * @param [options]
212
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
213
+ * @returns {Object} JSON schema properties
214
+ */
215
+
216
+ SchemaDouble.prototype.toJSONSchema = function toJSONSchema(options) {
217
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
218
+ return createJSONSchemaTypeDefinition('number', 'double', options?.useBsonType, isRequired);
219
+ };
207
220
 
208
221
  /*!
209
222
  * Module exports.
@@ -7,6 +7,7 @@
7
7
  const CastError = require('../error/cast');
8
8
  const SchemaType = require('../schemaType');
9
9
  const castInt32 = require('../cast/int32');
10
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
10
11
  const handleBitwiseOperator = require('./operators/bitwise');
11
12
 
12
13
  /**
@@ -246,6 +247,19 @@ SchemaInt32.prototype.castForQuery = function($conditional, val, context) {
246
247
  }
247
248
  };
248
249
 
250
+ /**
251
+ * Returns this schema type's representation in a JSON schema.
252
+ *
253
+ * @param [options]
254
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
255
+ * @returns {Object} JSON schema properties
256
+ */
257
+
258
+ SchemaInt32.prototype.toJSONSchema = function toJSONSchema(options) {
259
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
260
+ return createJSONSchemaTypeDefinition('number', 'int', options?.useBsonType, isRequired);
261
+ };
262
+
249
263
 
250
264
  /*!
251
265
  * Module exports.
package/lib/schema/map.js CHANGED
@@ -7,6 +7,8 @@
7
7
  const MongooseMap = require('../types/map');
8
8
  const SchemaMapOptions = require('../options/schemaMapOptions');
9
9
  const SchemaType = require('../schemaType');
10
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
11
+
10
12
  /*!
11
13
  * ignore
12
14
  */
@@ -67,6 +69,32 @@ class SchemaMap extends SchemaType {
67
69
  }
68
70
  return schematype;
69
71
  }
72
+
73
+ /**
74
+ * Returns the embedded schema type (i.e. the `.$*` path)
75
+ */
76
+ getEmbeddedSchemaType() {
77
+ return this.$__schemaType;
78
+ }
79
+
80
+ /**
81
+ * Returns this schema type's representation in a JSON schema.
82
+ *
83
+ * @param [options]
84
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
85
+ * @returns {Object} JSON schema properties
86
+ */
87
+
88
+ toJSONSchema(options) {
89
+ const useBsonType = options?.useBsonType;
90
+ const embeddedSchemaType = this.getEmbeddedSchemaType();
91
+
92
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
93
+ const result = createJSONSchemaTypeDefinition('object', 'object', useBsonType, isRequired);
94
+ result.additionalProperties = embeddedSchemaType.toJSONSchema(options);
95
+
96
+ return result;
97
+ }
70
98
  }
71
99
 
72
100
  /**
@@ -8,6 +8,7 @@ const MongooseError = require('../error/index');
8
8
  const SchemaNumberOptions = require('../options/schemaNumberOptions');
9
9
  const SchemaType = require('../schemaType');
10
10
  const castNumber = require('../cast/number');
11
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
11
12
  const handleBitwiseOperator = require('./operators/bitwise');
12
13
  const utils = require('../utils');
13
14
 
@@ -354,10 +355,10 @@ SchemaNumber.prototype.enum = function(values, message) {
354
355
  * @api private
355
356
  */
356
357
 
357
- SchemaNumber.prototype.cast = function(value, doc, init) {
358
+ SchemaNumber.prototype.cast = function(value, doc, init, prev, options) {
358
359
  if (typeof value !== 'number' && SchemaType._isRef(this, value, doc, init)) {
359
360
  if (value == null || utils.isNonBuiltinObject(value)) {
360
- return this._castRef(value, doc, init);
361
+ return this._castRef(value, doc, init, options);
361
362
  }
362
363
  }
363
364
 
@@ -442,6 +443,19 @@ SchemaNumber.prototype.castForQuery = function($conditional, val, context) {
442
443
  return val;
443
444
  };
444
445
 
446
+ /**
447
+ * Returns this schema type's representation in a JSON schema.
448
+ *
449
+ * @param [options]
450
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
451
+ * @returns {Object} JSON schema properties
452
+ */
453
+
454
+ SchemaNumber.prototype.toJSONSchema = function toJSONSchema(options) {
455
+ const isRequired = (this.options.required && typeof this.options.required !== 'function') || this.path === '_id';
456
+ return createJSONSchemaTypeDefinition('number', 'number', options?.useBsonType, isRequired);
457
+ };
458
+
445
459
  /*!
446
460
  * Module exports.
447
461
  */
@@ -7,6 +7,7 @@
7
7
  const SchemaObjectIdOptions = require('../options/schemaObjectIdOptions');
8
8
  const SchemaType = require('../schemaType');
9
9
  const castObjectId = require('../cast/objectid');
10
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
10
11
  const getConstructorName = require('../helpers/getConstructorName');
11
12
  const oid = require('../types/objectid');
12
13
  const isBsonType = require('../helpers/isBsonType');
@@ -223,7 +224,7 @@ SchemaObjectId.prototype.checkRequired = function checkRequired(value, doc) {
223
224
  * @api private
224
225
  */
225
226
 
226
- SchemaObjectId.prototype.cast = function(value, doc, init) {
227
+ SchemaObjectId.prototype.cast = function(value, doc, init, prev, options) {
227
228
  if (!(isBsonType(value, 'ObjectId')) && SchemaType._isRef(this, value, doc, init)) {
228
229
  // wait! we may need to cast this to a document
229
230
  if ((getConstructorName(value) || '').toLowerCase() === 'objectid') {
@@ -231,7 +232,7 @@ SchemaObjectId.prototype.cast = function(value, doc, init) {
231
232
  }
232
233
 
233
234
  if (value == null || utils.isNonBuiltinObject(value)) {
234
- return this._castRef(value, doc, init);
235
+ return this._castRef(value, doc, init, options);
235
236
  }
236
237
  }
237
238
 
@@ -290,6 +291,19 @@ function resetId(v) {
290
291
  return v;
291
292
  }
292
293
 
294
+ /**
295
+ * Returns this schema type's representation in a JSON schema.
296
+ *
297
+ * @param [options]
298
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
299
+ * @returns {Object} JSON schema properties
300
+ */
301
+
302
+ SchemaObjectId.prototype.toJSONSchema = function toJSONSchema(options) {
303
+ const isRequired = (this.options.required && typeof this.options.required !== 'function') || this.path === '_id';
304
+ return createJSONSchemaTypeDefinition('string', 'objectId', options?.useBsonType, isRequired);
305
+ };
306
+
293
307
  /*!
294
308
  * Module exports.
295
309
  */
@@ -8,6 +8,7 @@ const SchemaType = require('../schemaType');
8
8
  const MongooseError = require('../error/index');
9
9
  const SchemaStringOptions = require('../options/schemaStringOptions');
10
10
  const castString = require('../cast/string');
11
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
11
12
  const utils = require('../utils');
12
13
  const isBsonType = require('../helpers/isBsonType');
13
14
 
@@ -586,9 +587,9 @@ SchemaString.prototype.checkRequired = function checkRequired(value, doc) {
586
587
  * @api private
587
588
  */
588
589
 
589
- SchemaString.prototype.cast = function(value, doc, init) {
590
+ SchemaString.prototype.cast = function(value, doc, init, prev, options) {
590
591
  if (typeof value !== 'string' && SchemaType._isRef(this, value, doc, init)) {
591
- return this._castRef(value, doc, init);
592
+ return this._castRef(value, doc, init, options);
592
593
  }
593
594
 
594
595
  let castString;
@@ -698,6 +699,19 @@ SchemaString.prototype.castForQuery = function($conditional, val, context) {
698
699
  }
699
700
  };
700
701
 
702
+ /**
703
+ * Returns this schema type's representation in a JSON schema.
704
+ *
705
+ * @param [options]
706
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
707
+ * @returns {Object} JSON schema properties
708
+ */
709
+
710
+ SchemaString.prototype.toJSONSchema = function toJSONSchema(options) {
711
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
712
+ return createJSONSchemaTypeDefinition('string', 'string', options?.useBsonType, isRequired);
713
+ };
714
+
701
715
  /*!
702
716
  * Module exports.
703
717
  */
@@ -12,6 +12,7 @@ const SchemaType = require('../schemaType');
12
12
  const applyDefaults = require('../helpers/document/applyDefaults');
13
13
  const $exists = require('./operators/exists');
14
14
  const castToNumber = require('./operators/helpers').castToNumber;
15
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
15
16
  const discriminator = require('../helpers/model/discriminator');
16
17
  const geospatial = require('./operators/geospatial');
17
18
  const getConstructor = require('../helpers/discriminator/getConstructor');
@@ -396,3 +397,19 @@ SchemaSubdocument.prototype.clone = function() {
396
397
  schematype._appliedDiscriminators = this._appliedDiscriminators;
397
398
  return schematype;
398
399
  };
400
+
401
+ /**
402
+ * Returns this schema type's representation in a JSON schema.
403
+ *
404
+ * @param [options]
405
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
406
+ * @returns {Object} JSON schema properties
407
+ */
408
+
409
+ SchemaSubdocument.prototype.toJSONSchema = function toJSONSchema(options) {
410
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
411
+ return {
412
+ ...this.schema.toJSONSchema(options),
413
+ ...createJSONSchemaTypeDefinition('object', 'object', options?.useBsonType, isRequired)
414
+ };
415
+ };
@@ -8,6 +8,7 @@ const MongooseBuffer = require('../types/buffer');
8
8
  const SchemaType = require('../schemaType');
9
9
  const CastError = SchemaType.CastError;
10
10
  const castUUID = require('../cast/uuid');
11
+ const createJSONSchemaTypeDefinition = require('../helpers/createJSONSchemaTypeDefinition');
11
12
  const utils = require('../utils');
12
13
  const handleBitwiseOperator = require('./operators/bitwise');
13
14
 
@@ -201,10 +202,10 @@ SchemaUUID.prototype.checkRequired = function checkRequired(value) {
201
202
  * @api private
202
203
  */
203
204
 
204
- SchemaUUID.prototype.cast = function(value, doc, init) {
205
+ SchemaUUID.prototype.cast = function(value, doc, init, prev, options) {
205
206
  if (utils.isNonBuiltinObject(value) &&
206
207
  SchemaType._isRef(this, value, doc, init)) {
207
- return this._castRef(value, doc, init);
208
+ return this._castRef(value, doc, init, options);
208
209
  }
209
210
 
210
211
  let castFn;
@@ -284,6 +285,19 @@ SchemaUUID.prototype.castForQuery = function($conditional, val, context) {
284
285
  }
285
286
  };
286
287
 
288
+ /**
289
+ * Returns this schema type's representation in a JSON schema.
290
+ *
291
+ * @param [options]
292
+ * @param [options.useBsonType=false] If true, return a representation with `bsonType` for use with MongoDB's `$jsonSchema`.
293
+ * @returns {Object} JSON schema properties
294
+ */
295
+
296
+ SchemaUUID.prototype.toJSONSchema = function toJSONSchema(options) {
297
+ const isRequired = this.options.required && typeof this.options.required !== 'function';
298
+ return createJSONSchemaTypeDefinition('string', 'binData', options?.useBsonType, isRequired);
299
+ };
300
+
287
301
  /*!
288
302
  * Module exports.
289
303
  */