mongoose 7.0.1 → 7.0.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.
package/lib/aggregate.js CHANGED
@@ -1127,7 +1127,7 @@ Aggregate.prototype.catch = function(reject) {
1127
1127
  * `Symbol.asyncIterator` is undefined, that means your Node.js version does not
1128
1128
  * support async iterators.
1129
1129
  *
1130
- * @method Symbol.asyncIterator
1130
+ * @method [Symbol.asyncIterator]
1131
1131
  * @memberOf Aggregate
1132
1132
  * @instance
1133
1133
  * @api public
package/lib/connection.js CHANGED
@@ -1057,6 +1057,16 @@ Connection.prototype._close = async function _close(force, destroy) {
1057
1057
  return this;
1058
1058
  };
1059
1059
 
1060
+ /**
1061
+ * Abstract method that drivers must implement.
1062
+ *
1063
+ * @api private
1064
+ */
1065
+
1066
+ Connection.prototype.doClose = function() {
1067
+ throw new Error('Connection#doClose unimplemented by driver');
1068
+ };
1069
+
1060
1070
  /**
1061
1071
  * Called when the connection closes
1062
1072
  *
@@ -263,7 +263,7 @@ AggregationCursor.prototype.eachAsync = function(fn, opts, callback) {
263
263
  * `Symbol.asyncIterator` is undefined, that means your Node.js version does not
264
264
  * support async iterators.
265
265
  *
266
- * @method Symbol.asyncIterator
266
+ * @method [Symbol.asyncIterator]
267
267
  * @memberOf AggregationCursor
268
268
  * @instance
269
269
  * @api public
@@ -347,7 +347,7 @@ QueryCursor.prototype._transformForAsyncIterator = function() {
347
347
  * `Symbol.asyncIterator` is undefined, that means your Node.js version does not
348
348
  * support async iterators.
349
349
  *
350
- * @method Symbol.asyncIterator
350
+ * @method [Symbol.asyncIterator]
351
351
  * @memberOf QueryCursor
352
352
  * @instance
353
353
  * @api public
package/lib/document.js CHANGED
@@ -17,7 +17,6 @@ const ValidationError = require('./error/validation');
17
17
  const ValidatorError = require('./error/validator');
18
18
  const VirtualType = require('./virtualtype');
19
19
  const $__hasIncludedChildren = require('./helpers/projection/hasIncludedChildren');
20
- const castNumber = require('./cast/number');
21
20
  const applyDefaults = require('./helpers/document/applyDefaults');
22
21
  const cleanModifiedSubpaths = require('./helpers/document/cleanModifiedSubpaths');
23
22
  const clone = require('./helpers/clone');
@@ -1747,18 +1746,26 @@ Document.prototype.$inc = function $inc(path, val) {
1747
1746
  return this;
1748
1747
  }
1749
1748
 
1749
+ const currentValue = this.$__getValue(path) || 0;
1750
+ let shouldSet = false;
1751
+ let valToSet = null;
1752
+ let valToInc = val;
1753
+
1750
1754
  try {
1751
- val = castNumber(val);
1755
+ val = schemaType.cast(val);
1756
+ valToSet = schemaType.applySetters(currentValue + val, this);
1757
+ valToInc = valToSet - currentValue;
1758
+ shouldSet = true;
1752
1759
  } catch (err) {
1753
1760
  this.invalidate(path, new MongooseError.CastError('number', val, path, err));
1754
1761
  }
1755
1762
 
1756
- const currentValue = this.$__getValue(path) || 0;
1757
-
1758
- this.$__.primitiveAtomics = this.$__.primitiveAtomics || {};
1759
- this.$__.primitiveAtomics[path] = { $inc: val };
1760
- this.markModified(path);
1761
- this.$__setValue(path, currentValue + val);
1763
+ if (shouldSet) {
1764
+ this.$__.primitiveAtomics = this.$__.primitiveAtomics || {};
1765
+ this.$__.primitiveAtomics[path] = { $inc: valToInc };
1766
+ this.markModified(path);
1767
+ this.$__setValue(path, valToSet);
1768
+ }
1762
1769
 
1763
1770
  return this;
1764
1771
  };
@@ -2557,7 +2564,7 @@ function _evaluateRequiredFunctions(doc) {
2557
2564
  * ignore
2558
2565
  */
2559
2566
 
2560
- function _getPathsToValidate(doc) {
2567
+ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
2561
2568
  const skipSchemaValidators = {};
2562
2569
 
2563
2570
  _evaluateRequiredFunctions(doc);
@@ -2628,6 +2635,22 @@ function _getPathsToValidate(doc) {
2628
2635
  }
2629
2636
  }
2630
2637
 
2638
+ for (const path of paths) {
2639
+ // Single nested paths (paths embedded under single nested subdocs) will
2640
+ // be validated on their own when we call `validate()` on the subdoc itself.
2641
+ // Re: gh-8468
2642
+ if (doc.$__schema.singleNestedPaths.hasOwnProperty(path)) {
2643
+ paths.delete(path);
2644
+ continue;
2645
+ }
2646
+ }
2647
+
2648
+ if (Array.isArray(pathsToValidate)) {
2649
+ paths = _handlePathsToValidate(paths, pathsToValidate);
2650
+ } else if (Array.isArray(pathsToSkip)) {
2651
+ paths = _handlePathsToSkip(paths, pathsToSkip);
2652
+ }
2653
+
2631
2654
  // from here on we're not removing items from paths
2632
2655
 
2633
2656
  // gh-661: if a whole array is modified, make sure to run validation on all
@@ -2687,13 +2710,6 @@ function _getPathsToValidate(doc) {
2687
2710
  }
2688
2711
 
2689
2712
  for (const path of paths) {
2690
- // Single nested paths (paths embedded under single nested subdocs) will
2691
- // be validated on their own when we call `validate()` on the subdoc itself.
2692
- // Re: gh-8468
2693
- if (doc.$__schema.singleNestedPaths.hasOwnProperty(path)) {
2694
- paths.delete(path);
2695
- continue;
2696
- }
2697
2713
  const _pathType = doc.$__schema.path(path);
2698
2714
  if (!_pathType || !_pathType.$isSchemaMap) {
2699
2715
  continue;
@@ -2776,19 +2792,14 @@ Document.prototype.$__validate = function(pathsToValidate, options, callback) {
2776
2792
  };
2777
2793
 
2778
2794
  // only validate required fields when necessary
2779
- const pathDetails = _getPathsToValidate(this);
2780
- let paths = shouldValidateModifiedOnly ?
2795
+ const pathDetails = _getPathsToValidate(this, pathsToValidate, pathsToSkip);
2796
+ const paths = shouldValidateModifiedOnly ?
2781
2797
  pathDetails[0].filter((path) => this.$isModified(path)) :
2782
2798
  pathDetails[0];
2783
2799
  const skipSchemaValidators = pathDetails[1];
2784
2800
  if (typeof pathsToValidate === 'string') {
2785
2801
  pathsToValidate = pathsToValidate.split(' ');
2786
2802
  }
2787
- if (Array.isArray(pathsToValidate)) {
2788
- paths = _handlePathsToValidate(paths, pathsToValidate);
2789
- } else if (pathsToSkip) {
2790
- paths = _handlePathsToSkip(paths, pathsToSkip);
2791
- }
2792
2803
 
2793
2804
  if (paths.length === 0) {
2794
2805
  return immediate(function() {
@@ -2907,12 +2918,12 @@ function _handlePathsToValidate(paths, pathsToValidate) {
2907
2918
  }
2908
2919
  }
2909
2920
 
2910
- const ret = [];
2921
+ const ret = new Set();
2911
2922
  for (const path of paths) {
2912
2923
  if (_pathsToValidate.has(path)) {
2913
- ret.push(path);
2924
+ ret.add(path);
2914
2925
  } else if (parentPaths.has(path)) {
2915
- ret.push(parentPaths.get(path));
2926
+ ret.add(parentPaths.get(path));
2916
2927
  }
2917
2928
  }
2918
2929
  return ret;
@@ -2924,8 +2935,8 @@ function _handlePathsToValidate(paths, pathsToValidate) {
2924
2935
 
2925
2936
  function _handlePathsToSkip(paths, pathsToSkip) {
2926
2937
  pathsToSkip = new Set(pathsToSkip);
2927
- paths = paths.filter(p => !pathsToSkip.has(p));
2928
- return paths;
2938
+ paths = Array.from(paths).filter(p => !pathsToSkip.has(p));
2939
+ return new Set(paths);
2929
2940
  }
2930
2941
 
2931
2942
  /**
@@ -2981,17 +2992,12 @@ Document.prototype.validateSync = function(pathsToValidate, options) {
2981
2992
  }
2982
2993
 
2983
2994
  // only validate required fields when necessary
2984
- const pathDetails = _getPathsToValidate(this);
2985
- let paths = shouldValidateModifiedOnly ?
2995
+ const pathDetails = _getPathsToValidate(this, pathsToValidate, pathsToSkip);
2996
+ const paths = shouldValidateModifiedOnly ?
2986
2997
  pathDetails[0].filter((path) => this.$isModified(path)) :
2987
2998
  pathDetails[0];
2988
2999
  const skipSchemaValidators = pathDetails[1];
2989
3000
 
2990
- if (Array.isArray(pathsToValidate)) {
2991
- paths = _handlePathsToValidate(paths, pathsToValidate);
2992
- } else if (Array.isArray(pathsToSkip)) {
2993
- paths = _handlePathsToSkip(paths, pathsToSkip);
2994
- }
2995
3001
  const validating = {};
2996
3002
 
2997
3003
  for (let i = 0, len = paths.length; i < len; ++i) {
@@ -32,7 +32,7 @@ module.exports = function applyDefaults(doc, fields, exclude, hasIncludedChildre
32
32
  }
33
33
  } else if (exclude === false && fields && !included) {
34
34
  const hasSubpaths = type.$isSingleNested || type.$isMongooseDocumentArray;
35
- if (curPath in fields || (hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) {
35
+ if (curPath in fields || (j === len - 1 && hasSubpaths && hasIncludedChildren != null && hasIncludedChildren[curPath])) {
36
36
  included = true;
37
37
  } else if (hasIncludedChildren != null && !hasIncludedChildren[curPath]) {
38
38
  break;
@@ -7,6 +7,11 @@ const handleTimestampOption = require('../schema/handleTimestampOption');
7
7
  const setDocumentTimestamps = require('./setDocumentTimestamps');
8
8
  const symbols = require('../../schema/symbols');
9
9
 
10
+ const replaceOps = new Set([
11
+ 'replaceOne',
12
+ 'findOneAndReplace'
13
+ ]);
14
+
10
15
  module.exports = function setupTimestamps(schema, timestamps) {
11
16
  const childHasTimestamp = schema.childSchemas.find(withTimestamp);
12
17
  function withTimestamp(s) {
@@ -90,7 +95,7 @@ module.exports = function setupTimestamps(schema, timestamps) {
90
95
  currentTime() :
91
96
  this.model.base.now();
92
97
  // Replacing with null update should still trigger timestamps
93
- if (this.op === 'findOneAndReplace' && this.getUpdate() == null) {
98
+ if (replaceOps.has(this.op) && this.getUpdate() == null) {
94
99
  this.setUpdate({});
95
100
  }
96
101
  applyTimestampsToUpdate(now, createdAt, updatedAt, this.getUpdate(),
package/lib/model.js CHANGED
@@ -1252,9 +1252,11 @@ for (const i in EventEmitter.prototype) {
1252
1252
  * Mongoose calls this function automatically when a model is created using
1253
1253
  * [`mongoose.model()`](/docs/api/mongoose.html#mongoose_Mongoose-model) or
1254
1254
  * [`connection.model()`](/docs/api/connection.html#connection_Connection-model), so you
1255
- * don't need to call it. This function is also idempotent, so you may call it
1256
- * to get back a promise that will resolve when your indexes are finished
1257
- * building as an alternative to [`MyModel.on('index')`](/docs/guide.html#indexes)
1255
+ * don't need to call `init()` to trigger index builds.
1256
+ *
1257
+ * However, you _may_ need to call `init()` to get back a promise that will resolve when your indexes are finished.
1258
+ * Calling `await Model.init()` is helpful if you need to wait for indexes to build before continuing.
1259
+ * For example, if you want to wait for unique indexes to build before continuing with a test case.
1258
1260
  *
1259
1261
  * #### Example:
1260
1262
  *
@@ -1263,11 +1265,8 @@ for (const i in EventEmitter.prototype) {
1263
1265
  * // `Event.init()` on your own.
1264
1266
  * const Event = mongoose.model('Event', eventSchema);
1265
1267
  *
1266
- * Event.init().then(function(Event) {
1267
- * // You can also use `Event.on('index')` if you prefer event emitters
1268
- * // over promises.
1269
- * console.log('Indexes are done building!');
1270
- * });
1268
+ * await Event.init();
1269
+ * console.log('Indexes are done building!');
1271
1270
  *
1272
1271
  * @api public
1273
1272
  * @returns {Promise}
@@ -2952,7 +2951,7 @@ Model.startSession = function() {
2952
2951
  * @param {Array|Object|*} doc(s)
2953
2952
  * @param {Object} [options] see the [mongodb driver options](https://mongodb.github.io/node-mongodb-native/4.9/classes/Collection.html#insertMany)
2954
2953
  * @param {Boolean} [options.ordered=true] if true, will fail fast on the first error encountered. If false, will insert all the documents it can and report errors later. An `insertMany()` with `ordered = false` is called an "unordered" `insertMany()`.
2955
- * @param {Boolean} [options.rawResult=false] if false, the returned promise resolves to the documents that passed mongoose document validation. If `true`, will return the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/InsertManyResult.html) with a `mongoose` property that contains `validationErrors` if this is an unordered `insertMany`.
2954
+ * @param {Boolean} [options.rawResult=false] if false, the returned promise resolves to the documents that passed mongoose document validation. If `true`, will return the [raw result from the MongoDB driver](https://mongodb.github.io/node-mongodb-native/4.9/interfaces/InsertManyResult.html) with a `mongoose` property that contains `validationErrors` and `results` if this is an unordered `insertMany`.
2956
2955
  * @param {Boolean} [options.lean=false] if `true`, skips hydrating and validating the documents. This option is useful if you need the extra performance, but Mongoose won't validate the documents before inserting.
2957
2956
  * @param {Number} [options.limit=null] this limits the number of documents being processed (validation/casting) by mongoose in parallel, this does **NOT** send the documents in batches to MongoDB. Use this option if you're processing a large number of documents and your app is running out of memory.
2958
2957
  * @param {String|Object|Array} [options.populate=null] populates the result documents. This option is a no-op if `rawResult` is set.
@@ -3009,6 +3008,7 @@ Model.$__insertMany = function(arr, options, callback) {
3009
3008
 
3010
3009
  const validationErrors = [];
3011
3010
  const validationErrorsToOriginalOrder = new Map();
3011
+ const results = ordered ? null : new Array(arr.length);
3012
3012
  const toExecute = arr.map((doc, index) =>
3013
3013
  callback => {
3014
3014
  if (!(doc instanceof _this)) {
@@ -3034,8 +3034,8 @@ Model.$__insertMany = function(arr, options, callback) {
3034
3034
  if (ordered === false) {
3035
3035
  validationErrors.push(error);
3036
3036
  validationErrorsToOriginalOrder.set(error, index);
3037
- callback(null, null);
3038
- return;
3037
+ results[index] = error;
3038
+ return callback(null, null);
3039
3039
  }
3040
3040
  callback(error);
3041
3041
  }
@@ -3108,10 +3108,17 @@ Model.$__insertMany = function(arr, options, callback) {
3108
3108
 
3109
3109
  if (rawResult) {
3110
3110
  if (ordered === false) {
3111
+ for (let i = 0; i < results.length; ++i) {
3112
+ if (results[i] === void 0) {
3113
+ results[i] = docs[i];
3114
+ }
3115
+ }
3116
+
3111
3117
  // Decorate with mongoose validation errors in case of unordered,
3112
3118
  // because then still do `insertMany()`
3113
3119
  res.mongoose = {
3114
- validationErrors: validationErrors
3120
+ validationErrors: validationErrors,
3121
+ results: results
3115
3122
  };
3116
3123
  }
3117
3124
  return callback(null, res);
@@ -3143,10 +3150,24 @@ Model.$__insertMany = function(arr, options, callback) {
3143
3150
  const erroredIndexes = new Set((error && error.writeErrors || []).map(err => err.index));
3144
3151
 
3145
3152
  for (let i = 0; i < error.writeErrors.length; ++i) {
3153
+ const originalIndex = validDocIndexToOriginalIndex.get(error.writeErrors[i].index);
3146
3154
  error.writeErrors[i] = {
3147
3155
  ...error.writeErrors[i],
3148
- index: validDocIndexToOriginalIndex.get(error.writeErrors[i].index)
3156
+ index: originalIndex
3149
3157
  };
3158
+ if (!ordered) {
3159
+ results[originalIndex] = error.writeErrors[i];
3160
+ }
3161
+ }
3162
+
3163
+ if (!ordered) {
3164
+ for (let i = 0; i < results.length; ++i) {
3165
+ if (results[i] === void 0) {
3166
+ results[i] = docs[i];
3167
+ }
3168
+ }
3169
+
3170
+ error.results = results;
3150
3171
  }
3151
3172
 
3152
3173
  let firstErroredIndex = -1;
@@ -3174,7 +3195,8 @@ Model.$__insertMany = function(arr, options, callback) {
3174
3195
 
3175
3196
  if (rawResult && ordered === false) {
3176
3197
  error.mongoose = {
3177
- validationErrors: validationErrors
3198
+ validationErrors: validationErrors,
3199
+ results: results
3178
3200
  };
3179
3201
  }
3180
3202
 
package/lib/query.js CHANGED
@@ -4319,6 +4319,10 @@ Query.prototype.exec = async function exec(op) {
4319
4319
  try {
4320
4320
  await _executePreHooks(this);
4321
4321
  res = await this[thunk]();
4322
+
4323
+ for (const fn of this._transforms) {
4324
+ res = fn(res);
4325
+ }
4322
4326
  } catch (err) {
4323
4327
  if (err instanceof Kareem.skipWrappedFunction) {
4324
4328
  res = err.args[0];
@@ -4327,10 +4331,6 @@ Query.prototype.exec = async function exec(op) {
4327
4331
  }
4328
4332
  }
4329
4333
 
4330
- for (const fn of this._transforms) {
4331
- res = fn(res);
4332
- }
4333
-
4334
4334
  res = await _executePostHooks(this, res, error);
4335
4335
 
4336
4336
  await _executePostExecHooks(this);
@@ -4482,7 +4482,8 @@ Query.prototype.finally = function(onFinally) {
4482
4482
  *
4483
4483
  * @return {String}
4484
4484
  * @api public
4485
- * @method toStringTag
4485
+ * @method [Symbol.toStringTag]
4486
+ * @memberOf Query
4486
4487
  */
4487
4488
 
4488
4489
  Query.prototype[Symbol.toStringTag] = function toString() {
@@ -5192,7 +5193,7 @@ Query.prototype.nearSphere = function() {
5192
5193
  * `Symbol.asyncIterator` is undefined, that means your Node.js version does not
5193
5194
  * support async iterators.
5194
5195
  *
5195
- * @method Symbol.asyncIterator
5196
+ * @method [Symbol.asyncIterator]
5196
5197
  * @memberOf Query
5197
5198
  * @instance
5198
5199
  * @api public
@@ -416,6 +416,8 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
416
416
 
417
417
  options = options || {};
418
418
 
419
+ const path = options.path || this.path;
420
+
419
421
  if (!Array.isArray(value)) {
420
422
  if (!init && !DocumentArrayPath.options.castNonArrays) {
421
423
  throw new CastError('DocumentArray', value, this.path, null, this);
@@ -423,7 +425,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
423
425
  // gh-2442 mark whole array as modified if we're initializing a doc from
424
426
  // the db and the path isn't an array in the document
425
427
  if (!!doc && init) {
426
- doc.markModified(this.path);
428
+ doc.markModified(path);
427
429
  }
428
430
  return this.cast([value], doc, init, prev, options);
429
431
  }
@@ -431,7 +433,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
431
433
  // We need to create a new array, otherwise change tracking will
432
434
  // update the old doc (gh-4449)
433
435
  if (!options.skipDocumentArrayCast || utils.isMongooseDocumentArray(value)) {
434
- value = new MongooseDocumentArray(value, this.path, doc);
436
+ value = new MongooseDocumentArray(value, path, doc);
435
437
  }
436
438
 
437
439
  if (prev != null) {
@@ -439,7 +441,7 @@ DocumentArrayPath.prototype.cast = function(value, doc, init, prev, options) {
439
441
  }
440
442
 
441
443
  if (options.arrayPathIndex != null) {
442
- value[arrayPathSymbol] = this.path + '.' + options.arrayPathIndex;
444
+ value[arrayPathSymbol] = path + '.' + options.arrayPathIndex;
443
445
  }
444
446
 
445
447
  const rawArray = utils.isMongooseDocumentArray(value) ? value.__array : value;
package/lib/schema.js CHANGED
@@ -734,8 +734,15 @@ Schema.prototype.add = function add(obj, prefix) {
734
734
  if (prefix) {
735
735
  this.nested[prefix.substring(0, prefix.length - 1)] = true;
736
736
  }
737
- const _schema = new Schema(_typeDef);
738
- const schemaWrappedPath = Object.assign({}, val, { type: _schema });
737
+
738
+ const childSchemaOptions = {};
739
+ if (this._userProvidedOptions.typeKey) {
740
+ childSchemaOptions.typeKey = this._userProvidedOptions.typeKey;
741
+ }
742
+
743
+ const _schema = new Schema(_typeDef, childSchemaOptions);
744
+ _schema.$implicitlyCreated = true;
745
+ const schemaWrappedPath = Object.assign({}, val, { [typeKey]: _schema });
739
746
  this.path(prefix + key, schemaWrappedPath);
740
747
  } else {
741
748
  // Either the type is non-POJO or we interpret it as Mixed anyway
@@ -1322,6 +1329,7 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
1322
1329
  } else if (Schema.Types.DocumentArray.defaultOptions._id != null) {
1323
1330
  childSchemaOptions._id = Schema.Types.DocumentArray.defaultOptions._id;
1324
1331
  }
1332
+
1325
1333
  const childSchema = new Schema(castFromTypeKey, childSchemaOptions);
1326
1334
  childSchema.$implicitlyCreated = true;
1327
1335
  return new MongooseTypes.DocumentArray(path, childSchema, obj);
@@ -1365,7 +1373,6 @@ Schema.prototype.interpretAsType = function(path, obj, options) {
1365
1373
  }
1366
1374
 
1367
1375
  if (type && type.instanceOfSchema) {
1368
-
1369
1376
  return new MongooseTypes.Subdocument(type, path, obj);
1370
1377
  }
1371
1378
 
@@ -2210,11 +2217,15 @@ Schema.prototype.virtual = function(name, options) {
2210
2217
  }
2211
2218
 
2212
2219
  // Workaround for gh-8198: if virtual is under document array, make a fake
2213
- // virtual. See gh-8210
2220
+ // virtual. See gh-8210, gh-13189
2214
2221
  const parts = name.split('.');
2215
2222
  let cur = parts[0];
2216
2223
  for (let i = 0; i < parts.length - 1; ++i) {
2217
- if (this.paths[cur] != null && this.paths[cur].$isMongooseDocumentArray) {
2224
+ if (this.paths[cur] == null) {
2225
+ continue;
2226
+ }
2227
+
2228
+ if (this.paths[cur].$isMongooseDocumentArray || this.paths[cur].$isSingleNested) {
2218
2229
  const remnant = parts.slice(i + 1).join('.');
2219
2230
  this.paths[cur].schema.virtual(remnant, options);
2220
2231
  break;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "mongoose",
3
3
  "description": "Mongoose MongoDB ODM",
4
- "version": "7.0.1",
4
+ "version": "7.0.3",
5
5
  "author": "Guillermo Rauch <guillermo@learnboost.com>",
6
6
  "keywords": [
7
7
  "mongodb",
@@ -46,6 +46,7 @@
46
46
  "dotenv": "16.0.3",
47
47
  "dox": "1.0.0",
48
48
  "eslint": "8.35.0",
49
+ "eslint-plugin-markdown": "^3.0.0",
49
50
  "eslint-plugin-mocha-no-only": "1.1.1",
50
51
  "express": "^4.18.1",
51
52
  "highlight.js": "11.7.0",
@@ -75,7 +76,7 @@
75
76
  "docs:clean:stable": "rimraf index.html && rimraf -rf ./docs/*.html && rimraf -rf ./docs/api && rimraf -rf ./docs/tutorials/*.html && rimraf -rf ./docs/typescript/*.html && rimraf -rf ./docs/*.html && rimraf -rf ./docs/source/_docs && rimraf -rf ./tmp",
76
77
  "docs:clean:5x": "rimraf index.html && rimraf -rf ./docs/5.x && rimraf -rf ./docs/source/_docs && rimraf -rf ./tmp",
77
78
  "docs:clean:6x": "rimraf index.html && rimraf -rf ./docs/6.x && rimraf -rf ./docs/source/_docs && rimraf -rf ./tmp",
78
- "docs:copy:tmp": "mkdirp ./tmp/docs/css && mkdirp ./tmp/docs/js && mkdirp ./tmp/docs/images && mkdirp ./tmp/docs/tutorials && mkdirp ./tmp/docs/typescript && ncp ./docs/css ./tmp/docs/css --filter=.css$ && ncp ./docs/js ./tmp/docs/js --filter=.js$ && ncp ./docs/images ./tmp/docs/images && ncp ./docs/tutorials ./tmp/docs/tutorials && ncp ./docs/typescript ./tmp/docs/typescript && cp index.html ./tmp && cp docs/*.html ./tmp/docs/",
79
+ "docs:copy:tmp": "mkdirp ./tmp/docs/css && mkdirp ./tmp/docs/js && mkdirp ./tmp/docs/images && mkdirp ./tmp/docs/tutorials && mkdirp ./tmp/docs/typescript && mkdirp ./tmp/docs/api && ncp ./docs/css ./tmp/docs/css --filter=.css$ && ncp ./docs/js ./tmp/docs/js --filter=.js$ && ncp ./docs/images ./tmp/docs/images && ncp ./docs/tutorials ./tmp/docs/tutorials && ncp ./docs/typescript ./tmp/docs/typescript && ncp ./docs/api ./tmp/docs/api && cp index.html ./tmp && cp docs/*.html ./tmp/docs/",
79
80
  "docs:copy:tmp:5x": "rimraf ./docs/5.x && ncp ./tmp ./docs/5.x",
80
81
  "docs:copy:tmp:6x": "rimraf ./docs/6.x && ncp ./tmp ./docs/6.x",
81
82
  "docs:checkout:gh-pages": "git checkout gh-pages",
@@ -83,6 +84,7 @@
83
84
  "docs:checkout:6x": "git checkout 6.x",
84
85
  "docs:generate": "node ./scripts/website.js",
85
86
  "docs:generate:search": "node ./scripts/generateSearch.js",
87
+ "docs:generate:sponsorData": "node ./scripts/loadSponsorData.js",
86
88
  "docs:merge:stable": "git merge master",
87
89
  "docs:merge:5x": "git merge 5.x",
88
90
  "docs:merge:6x": "git merge 6.x",
@@ -95,6 +97,7 @@
95
97
  "lint": "eslint .",
96
98
  "lint-js": "eslint . --ext .js",
97
99
  "lint-ts": "eslint . --ext .ts",
100
+ "lint-md": "eslint . --ext .md",
98
101
  "build-browser": "(rm ./dist/* || true) && node ./scripts/build-browser.js",
99
102
  "prepublishOnly": "npm run build-browser",
100
103
  "release": "git pull && git push origin master --tags && npm publish",
@@ -1,6 +1,14 @@
1
1
  'use strict';
2
2
 
3
- const config = require('../.config');
3
+ let config;
4
+ try {
5
+ config = require('../.config.js');
6
+ } finally {
7
+ if (!config || !config.uri) {
8
+ console.error('No Config or config.URI given, please create a .config.js file with those values in the root of the repository');
9
+ process.exit(-1);
10
+ }
11
+ }
4
12
  const cheerio = require('cheerio');
5
13
  const filemap = require('../docs/source');
6
14
  const fs = require('fs');
@@ -30,25 +38,27 @@ const Content = mongoose.model('Content', contentSchema, 'Content');
30
38
 
31
39
  const contents = [];
32
40
 
33
- for (const [filename, file] of Object.entries(filemap)) {
34
- if (file.api) {
35
- // API docs are special, raw content is in the `docs` property
36
- for (const _class of file.docs) {
37
- for (const prop of _class.props) {
38
- const content = new Content({
39
- title: `API: ${prop.string}`,
40
- body: prop.description,
41
- url: `api/${_class.fileName}.html#${prop.anchorId}`
42
- });
43
- const err = content.validateSync();
44
- if (err != null) {
45
- console.error(content);
46
- throw err;
47
- }
48
- contents.push(content);
49
- }
41
+ const api = require('../docs/source/api');
42
+
43
+ // API docs are special, because they are not added to the file-map individually currently and use different properties
44
+ for (const _class of api.docs) {
45
+ for (const prop of _class.props) {
46
+ const content = new Content({
47
+ title: `API: ${prop.name}`,
48
+ body: prop.description,
49
+ url: `api/${_class.fileName}.html#${prop.anchorId}`
50
+ });
51
+ const err = content.validateSync();
52
+ if (err != null) {
53
+ console.error(content);
54
+ throw err;
50
55
  }
51
- } else if (file.markdown) {
56
+ contents.push(content);
57
+ }
58
+ }
59
+
60
+ for (const [filename, file] of Object.entries(filemap)) {
61
+ if (file.markdown) {
52
62
  let text = fs.readFileSync(filename, 'utf8');
53
63
  text = markdown.parse(text);
54
64
 
@@ -120,11 +130,6 @@ run().catch(async error => {
120
130
  });
121
131
 
122
132
  async function run() {
123
- if (!config || !config.uri) {
124
- console.error('No Config or config.URI given, please create a .config.js file with those values');
125
- process.exit(-1);
126
- }
127
-
128
133
  await mongoose.connect(config.uri, { dbName: 'mongoose', serverSelectionTimeoutMS: 5000 });
129
134
 
130
135
  // wait for the index to be created
@@ -152,5 +157,7 @@ async function run() {
152
157
 
153
158
  console.log(results.map(res => res.url));
154
159
 
160
+ console.log(`Added ${contents.length} Content`);
161
+
155
162
  process.exit(0);
156
163
  }