mongoose 6.9.2 → 6.9.3

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.
@@ -195,6 +195,7 @@ function walkUpdatePath(schema, obj, op, options, context, filter, pref) {
195
195
  if (
196
196
  schema.discriminatorMapping != null &&
197
197
  discriminatorKey === schema.options.discriminatorKey &&
198
+ schema.discriminatorMapping.value !== obj[key] &&
198
199
  !options.overwriteDiscriminatorKey
199
200
  ) {
200
201
  if (strictMode === 'throw') {
package/lib/model.js CHANGED
@@ -63,6 +63,7 @@ const prepareDiscriminatorPipeline = require('./helpers/aggregate/prepareDiscrim
63
63
  const pushNestedArrayPaths = require('./helpers/model/pushNestedArrayPaths');
64
64
  const removeDeselectedForeignField = require('./helpers/populate/removeDeselectedForeignField');
65
65
  const setDottedPath = require('./helpers/path/setDottedPath');
66
+ const STATES = require('./connectionstate');
66
67
  const util = require('util');
67
68
  const utils = require('./utils');
68
69
 
@@ -283,8 +284,10 @@ Model.prototype.$__handleSave = function(options, callback) {
283
284
  if ('checkKeys' in options) {
284
285
  saveOptions.checkKeys = options.checkKeys;
285
286
  }
286
- if (!saveOptions.hasOwnProperty('session')) {
287
- saveOptions.session = this.$session();
287
+
288
+ const session = this.$session();
289
+ if (!saveOptions.hasOwnProperty('session') && session != null) {
290
+ saveOptions.session = session;
288
291
  }
289
292
 
290
293
  if (this.$isNew) {
@@ -1350,17 +1353,30 @@ Model.init = function init(callback) {
1350
1353
  }
1351
1354
 
1352
1355
  const Promise = PromiseProvider.get();
1353
- const autoIndex = utils.getOption('autoIndex',
1354
- this.schema.options, this.db.config, this.db.base.options);
1355
- const autoCreate = utils.getOption('autoCreate',
1356
- this.schema.options, this.db.config, this.db.base.options);
1357
-
1358
- const _ensureIndexes = autoIndex ?
1359
- cb => this.ensureIndexes({ _automatic: true }, cb) :
1360
- cb => cb();
1361
- const _createCollection = autoCreate ?
1362
- cb => this.createCollection({}, cb) :
1363
- cb => cb();
1356
+
1357
+ const model = this;
1358
+ const _ensureIndexes = function(cb) {
1359
+ const autoIndex = utils.getOption('autoIndex',
1360
+ model.schema.options, model.db.config, model.db.base.options);
1361
+ if (autoIndex) model.ensureIndexes({ _automatic: true }, cb);
1362
+ else cb();
1363
+ };
1364
+ const _createCollection = function(cb) {
1365
+ const conn = model.db;
1366
+
1367
+ if ((conn.readyState === STATES.connecting || conn.readyState === STATES.disconnected) && conn._shouldBufferCommands()) {
1368
+ conn._queue.push({ fn: _createCollection, ctx: conn, args: [cb] });
1369
+ } else {
1370
+ try {
1371
+ const autoCreate = utils.getOption('autoCreate',
1372
+ model.schema.options, model.db.config, model.db.base.options);
1373
+ if (autoCreate) model.createCollection({}, cb);
1374
+ else cb();
1375
+ } catch (err) {
1376
+ return cb(err);
1377
+ }
1378
+ }
1379
+ };
1364
1380
 
1365
1381
  this.$init = new Promise((resolve, reject) => {
1366
1382
  _createCollection(error => {
package/lib/query.js CHANGED
@@ -1876,6 +1876,12 @@ Query.prototype.setUpdate = function(val) {
1876
1876
  */
1877
1877
 
1878
1878
  Query.prototype._fieldsForExec = function() {
1879
+ if (this._fields == null) {
1880
+ return null;
1881
+ }
1882
+ if (Object.keys(this._fields).length === 0) {
1883
+ return null;
1884
+ }
1879
1885
  return utils.clone(this._fields);
1880
1886
  };
1881
1887
 
@@ -1996,6 +2002,12 @@ Query.prototype._optionsForExec = function(model) {
1996
2002
  delete options.wtimeout;
1997
2003
  }
1998
2004
  }
2005
+
2006
+ const projection = this._fieldsForExec();
2007
+ if (projection != null) {
2008
+ options.projection = projection;
2009
+ }
2010
+
1999
2011
  return options;
2000
2012
  };
2001
2013
 
@@ -2306,7 +2318,6 @@ Query.prototype._find = wrapThunk(function(callback) {
2306
2318
  };
2307
2319
 
2308
2320
  const options = this._optionsForExec();
2309
- options.projection = this._fieldsForExec();
2310
2321
  const filter = this._conditions;
2311
2322
 
2312
2323
  this._collection.collection.find(filter, options, (err, cursor) => {
@@ -2525,8 +2536,10 @@ Query.prototype._findOne = wrapThunk(function(callback) {
2525
2536
  applyGlobalMaxTimeMS(this.options, this.model);
2526
2537
  applyGlobalDiskUse(this.options, this.model);
2527
2538
 
2528
- // don't pass in the conditions because we already merged them in
2529
- Query.base.findOne.call(this, {}, (err, doc) => {
2539
+ const conds = this._conditions;
2540
+ const options = this._optionsForExec();
2541
+
2542
+ this._collection.findOne(conds, options, (err, doc) => {
2530
2543
  if (err) {
2531
2544
  callback(err);
2532
2545
  return null;
@@ -4038,10 +4051,12 @@ Query.prototype._findAndModify = function(type, callback) {
4038
4051
  }
4039
4052
 
4040
4053
  this._applyPaths();
4041
-
4042
4054
  if (this._fields) {
4043
- fields = utils.clone(this._fields);
4044
- opts.projection = this._castFields(fields);
4055
+ this._fields = this._castFields(this._fields);
4056
+ fields = this._fieldsForExec();
4057
+ if (fields != null) {
4058
+ opts.projection = fields;
4059
+ }
4045
4060
  if (opts.projection instanceof Error) {
4046
4061
  return callback(opts.projection);
4047
4062
  }
@@ -5469,14 +5484,12 @@ Query.prototype._applyPaths = function applyPaths() {
5469
5484
  Query.prototype.cursor = function cursor(opts) {
5470
5485
  this._applyPaths();
5471
5486
  this._fields = this._castFields(this._fields);
5472
- this.setOptions({ projection: this._fieldsForExec() });
5487
+
5473
5488
  if (opts) {
5474
5489
  this.setOptions(opts);
5475
5490
  }
5476
5491
 
5477
- const options = Object.assign({}, this._optionsForExec(), {
5478
- projection: this.projection()
5479
- });
5492
+ const options = this._optionsForExec();
5480
5493
  try {
5481
5494
  this.cast(this.model);
5482
5495
  } catch (err) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "6.9.2",
4
+ "version": "6.9.3",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -32,8 +32,8 @@
32
32
  "@babel/preset-env": "7.20.2",
33
33
  "@typescript-eslint/eslint-plugin": "5.50.0",
34
34
  "@typescript-eslint/parser": "5.50.0",
35
- "acquit": "1.2.1",
36
- "acquit-ignore": "0.2.0",
35
+ "acquit": "1.3.0",
36
+ "acquit-ignore": "0.2.1",
37
37
  "acquit-require": "0.1.1",
38
38
  "assert-browserify": "2.0.0",
39
39
  "axios": "1.1.3",
@@ -79,7 +79,7 @@
79
79
  "docs:checkout:gh-pages": "git checkout gh-pages",
80
80
  "docs:checkout:legacy": "git checkout 5.x",
81
81
  "docs:generate": "node ./scripts/website.js",
82
- "docs:generate:search": "node docs/search.js",
82
+ "docs:generate:search": "node ./scripts/generateSearch.js",
83
83
  "docs:merge:stable": "git merge master",
84
84
  "docs:merge:legacy": "git merge 5.x",
85
85
  "docs:test": "npm run docs:generate && npm run docs:generate:search",
@@ -0,0 +1,158 @@
1
+ 'use strict';
2
+
3
+ const config = require('../.config');
4
+ const cheerio = require('cheerio');
5
+ const filemap = require('../docs/source');
6
+ const fs = require('fs');
7
+ const pug = require('pug');
8
+ const mongoose = require('../');
9
+ let { version } = require('../package.json');
10
+
11
+ const { marked: markdown } = require('marked');
12
+ const highlight = require('highlight.js');
13
+ markdown.setOptions({
14
+ highlight: function(code) {
15
+ return highlight.highlight(code, { language: 'JavaScript' }).value;
16
+ }
17
+ });
18
+
19
+ mongoose.set('strictQuery', false);
20
+
21
+ // 5.13.5 -> 5.x, 6.8.2 -> 6.x, etc.
22
+ version = version.slice(0, version.indexOf('.')) + '.x';
23
+
24
+ const contentSchema = new mongoose.Schema({
25
+ title: { type: String, required: true },
26
+ body: { type: String, required: true },
27
+ url: { type: String, required: true },
28
+ version: { type: String, required: true, default: version }
29
+ });
30
+ contentSchema.index({ title: 'text', body: 'text' });
31
+ const Content = mongoose.model('Content', contentSchema, 'Content');
32
+
33
+ const contents = [];
34
+
35
+ for (const [filename, file] of Object.entries(filemap)) {
36
+ if (file.api) {
37
+ // API docs are special, raw content is in the `docs` property
38
+ for (const _class of file.docs) {
39
+ for (const prop of _class.props) {
40
+ const content = new Content({
41
+ title: `API: ${prop.string}`,
42
+ body: prop.description,
43
+ url: `api/${_class.fileName}.html#${prop.anchorId}`
44
+ });
45
+ const err = content.validateSync();
46
+ if (err != null) {
47
+ console.error(content);
48
+ throw err;
49
+ }
50
+ contents.push(content);
51
+ }
52
+ }
53
+ } else if (file.markdown) {
54
+ let text = fs.readFileSync(filename, 'utf8');
55
+ text = markdown.parse(text);
56
+
57
+ const content = new Content({
58
+ title: file.title,
59
+ body: text,
60
+ url: filename.replace('.md', '.html').replace(/^docs/, '')
61
+ });
62
+
63
+ content.validateSync();
64
+
65
+ const $ = cheerio.load(text);
66
+
67
+ contents.push(content);
68
+
69
+ // Break up individual h3's into separate content for more fine grained search
70
+ $('h3').each((index, el) => {
71
+ el = $(el);
72
+ const title = el.text();
73
+ const html = el.nextUntil('h3').html();
74
+ const content = new Content({
75
+ title: `${file.title}: ${title}`,
76
+ body: html,
77
+ url: `${filename.replace('.md', '.html').replace(/^docs/, '')}#${el.prop('id')}`
78
+ });
79
+
80
+ content.validateSync();
81
+ contents.push(content);
82
+ });
83
+ } else if (file.guide) {
84
+ let text = fs.readFileSync(filename, 'utf8');
85
+ text = text.substr(text.indexOf('block content') + 'block content\n'.length);
86
+ text = pug.render(`div\n${text}`, { filters: { markdown }, filename });
87
+
88
+ const content = new Content({
89
+ title: file.title,
90
+ body: text,
91
+ url: filename.replace('.pug', '.html').replace(/^docs/, '')
92
+ });
93
+
94
+ content.validateSync();
95
+
96
+ const $ = cheerio.load(text);
97
+
98
+ contents.push(content);
99
+
100
+ // Break up individual h3's into separate content for more fine grained search
101
+ $('h3').each((index, el) => {
102
+ el = $(el);
103
+ const title = el.text();
104
+ const html = el.nextUntil('h3').html();
105
+ const content = new Content({
106
+ title: `${file.title}: ${title}`,
107
+ body: html,
108
+ url: `${filename.replace('.pug', '.html').replace(/^docs/, '')}#${el.prop('id')}`
109
+ });
110
+
111
+ content.validateSync();
112
+ contents.push(content);
113
+ });
114
+ }
115
+ }
116
+
117
+ run().catch(async error => {
118
+ console.error(error.stack);
119
+
120
+ // ensure the script exists in case of error
121
+ await mongoose.disconnect();
122
+ });
123
+
124
+ async function run() {
125
+ if (!config || !config.uri) {
126
+ console.error('No Config or config.URI given, please create a .config.js file with those values');
127
+ process.exit(-1);
128
+ }
129
+
130
+ await mongoose.connect(config.uri, { dbName: 'mongoose' });
131
+
132
+ // wait for the index to be created
133
+ await Content.init();
134
+
135
+ await Content.deleteMany({ version });
136
+ for (const content of contents) {
137
+ if (version === '6.x') {
138
+ let url = content.url.startsWith('/') ? content.url : `/${content.url}`;
139
+ if (!url.startsWith('/docs')) {
140
+ url = '/docs' + url;
141
+ }
142
+ content.url = url;
143
+ } else {
144
+ const url = content.url.startsWith('/') ? content.url : `/${content.url}`;
145
+ content.url = `/docs/${version}/docs${url}`;
146
+ }
147
+ await content.save();
148
+ }
149
+
150
+ const results = await Content.
151
+ find({ $text: { $search: 'validate' }, version }, { score: { $meta: 'textScore' } }).
152
+ sort({ score: { $meta: 'textScore' } }).
153
+ limit(10);
154
+
155
+ console.log(results.map(res => res.url));
156
+
157
+ process.exit(0);
158
+ }
package/types/index.d.ts CHANGED
@@ -129,12 +129,14 @@ declare module 'mongoose' {
129
129
  ? IfAny<U, T & { _id: Types.ObjectId }, T & Required<{ _id: U }>>
130
130
  : T & { _id: Types.ObjectId };
131
131
 
132
- export type HydratedDocument<DocType, TMethodsAndOverrides = {}, TVirtuals = {}> = DocType extends Document ? Require_id<DocType> : (Document<unknown, any, DocType> & Require_id<DocType> & TVirtuals & TMethodsAndOverrides);
132
+ export type HydratedDocument<DocType, TMethodsAndOverrides = {}, TVirtuals = {}> = DocType extends Document ?
133
+ Require_id<DocType> :
134
+ Document<unknown, any, DocType> & MergeType<Require_id<DocType>, TVirtuals & TMethodsAndOverrides>;
133
135
 
134
136
  export type HydratedDocumentFromSchema<TSchema extends Schema> = HydratedDocument<
135
137
  InferSchemaType<TSchema>,
136
- ObtainSchemaGeneric<TSchema, 'TQueryHelpers'>,
137
- ObtainSchemaGeneric<TSchema, 'TInstanceMethods'>
138
+ ObtainSchemaGeneric<TSchema, 'TInstanceMethods'>,
139
+ ObtainSchemaGeneric<TSchema, 'TVirtuals'>
138
140
  >;
139
141
 
140
142
  export interface TagSet {