This commit is contained in:
2020-08-20 11:44:32 +02:00
parent 4715fc1814
commit 6aceefeb2f
2891 changed files with 11239 additions and 347539 deletions

153
node_modules/mongoose/lib/document.js generated vendored
View File

@@ -30,6 +30,7 @@ const isExclusive = require('./helpers/projection/isExclusive');
const inspect = require('util').inspect;
const internalToObjectOptions = require('./options').internalToObjectOptions;
const mpath = require('mpath');
const queryhelpers = require('./queryhelpers');
const utils = require('./utils');
const isPromise = require('./helpers/isPromise');
@@ -56,7 +57,8 @@ const specialProperties = utils.specialProperties;
*
* @param {Object} obj the values to set
* @param {Object} [fields] optional object containing the fields which were selected in the query returning this document and any populated paths data
* @param {Boolean} [skipId] bool, should we auto create an ObjectId _id
* @param {Object} [options] various configuration options for the document
* @param {Boolean} [options.defaults=true] if `false`, skip applying default values to this document.
* @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
* @event `init`: Emitted on a document after it has been retrieved from the db and fully hydrated by Mongoose.
* @event `save`: Emitted when the document is successfully saved
@@ -68,7 +70,9 @@ function Document(obj, fields, skipId, options) {
options = skipId;
skipId = options.skipId;
}
options = options || {};
options = Object.assign({}, options);
const defaults = get(options, 'defaults', true);
options.defaults = defaults;
// Support `browserDocument.js` syntax
if (this.schema == null) {
@@ -127,9 +131,11 @@ function Document(obj, fields, skipId, options) {
// By default, defaults get applied **before** setting initial values
// Re: gh-6155
$__applyDefaults(this, fields, skipId, exclude, hasIncludedChildren, true, {
isNew: this.isNew
});
if (defaults) {
$__applyDefaults(this, fields, skipId, exclude, hasIncludedChildren, true, {
isNew: this.isNew
});
}
}
if (obj) {
@@ -148,13 +154,13 @@ function Document(obj, fields, skipId, options) {
// Function defaults get applied **after** setting initial values so they
// see the full doc rather than an empty one, unless they opt out.
// Re: gh-3781, gh-6155
if (options.willInit) {
if (options.willInit && defaults) {
EventEmitter.prototype.once.call(this, 'init', () => {
$__applyDefaults(this, fields, skipId, exclude, hasIncludedChildren, false, options.skipDefaults, {
isNew: this.isNew
});
});
} else {
} else if (defaults) {
$__applyDefaults(this, fields, skipId, exclude, hasIncludedChildren, false, options.skipDefaults, {
isNew: this.isNew
});
@@ -542,6 +548,16 @@ Document.prototype.$__init = function(doc, opts) {
} else {
this.populated(item.path, item._docs[id], item);
}
if (item._childDocs == null) {
continue;
}
for (const child of item._childDocs) {
if (child == null || child.$__ == null) {
continue;
}
child.$__.parent = this;
}
}
}
@@ -641,7 +657,7 @@ function init(self, obj, doc, opts, prefix) {
doc[i] = obj[i];
} else {
if (obj[i] === null) {
doc[i] = null;
doc[i] = schema._castNullish(null);
} else if (obj[i] !== undefined) {
const intCache = obj[i].$__ || {};
const wasPopulated = intCache.wasPopulated || null;
@@ -1239,6 +1255,10 @@ Document.prototype.$set = function $set(path, val, type, options) {
delete this.$__.populated[path];
}
if (schema.$isSingleNested && val != null) {
_checkImmutableSubpaths(val, schema, priorVal);
}
this.$markValid(path);
} catch (e) {
if (e instanceof MongooseError.StrictModeError && e.isImmutableError) {
@@ -2456,7 +2476,7 @@ function _handlePathsToValidate(paths, pathsToValidate) {
*
* @param {Array|string} pathsToValidate only validate the given paths
* @param {Object} [options] options for validation
* @param {Boolean} [options.validateModifiedOnly=false] if `true` mongoose validates only modified paths.
* @param {Boolean} [options.validateModifiedOnly=false] If `true`, Mongoose will only validate modified paths, as opposed to modified paths and `required` paths.
* @return {ValidationError|undefined} ValidationError if there are errors during validation, or undefined if there is no error.
* @api public
*/
@@ -2637,6 +2657,29 @@ function _markValidSubpaths(doc, path) {
}
}
/*!
* ignore
*/
function _checkImmutableSubpaths(subdoc, schematype, priorVal) {
const schema = schematype.schema;
if (schema == null) {
return;
}
for (const key of Object.keys(schema.paths)) {
const path = schema.paths[key];
if (path.$immutableSetter == null) {
continue;
}
const oldVal = priorVal == null ? void 0 : priorVal.$__getValue(key);
// Calling immutableSetter with `oldVal` even though it expects `newVal`
// is intentional. That's because `$immutableSetter` compares its param
// to the current value.
path.$immutableSetter.call(subdoc, oldVal);
}
}
/**
* Saves this document by inserting a new document into the database if [document.isNew](/docs/api.html#document_Document-isNew) is `true`,
* or sends an [updateOne](/docs/api.html#document_Document-updateOne) operation **only** with the modifications to the database, it does not replace the whole document in the latter case.
@@ -2658,7 +2701,7 @@ function _markValidSubpaths(doc, path) {
* @param {Session} [options.session=null] the [session](https://docs.mongodb.com/manual/reference/server-sessions/) associated with this save operation. If not specified, defaults to the [document's associated session](api.html#document_Document-$session).
* @param {Object} [options.safe] (DEPRECATED) overrides [schema's safe option](http://mongoosejs.com//docs/guide.html#safe). Use the `w` option instead.
* @param {Boolean} [options.validateBeforeSave] set to false to save without validating.
* @param {Boolean} [options.validateModifiedOnly=false] if `true` mongoose validates only modified paths.
* @param {Boolean} [options.validateModifiedOnly=false] If `true`, Mongoose will only validate modified paths, as opposed to modified paths and `required` paths.
* @param {Number|String} [options.w] set the [write concern](https://docs.mongodb.com/manual/reference/write-concern/#w-option). Overrides the [schema-level `writeConcern` option](/docs/guide.html#writeConcern)
* @param {Boolean} [options.j] set to true for MongoDB to wait until this `save()` has been [journaled before resolving the returned promise](https://docs.mongodb.com/manual/reference/write-concern/#j-option). Overrides the [schema-level `writeConcern` option](/docs/guide.html#writeConcern)
* @param {Number} [options.wtimeout] sets a [timeout for the write concern](https://docs.mongodb.com/manual/reference/write-concern/#wtimeout). Overrides the [schema-level `writeConcern` option](/docs/guide.html#writeConcern).
@@ -3079,6 +3122,10 @@ Document.prototype.$toObject = function(options, json) {
applySchemaTypeTransforms(this, ret);
}
if (options.useProjection) {
omitDeselectedFields(this, ret);
}
if (transform === true || (schemaOptions.toObject && transform)) {
const opts = options.json ? schemaOptions.toJSON : schemaOptions.toObject;
@@ -3114,6 +3161,7 @@ Document.prototype.$toObject = function(options, json) {
* - `depopulate` depopulate any populated paths, replacing them with their original refs, defaults to false
* - `versionKey` whether to include the version key, defaults to true
* - `flattenMaps` convert Maps to POJOs. Useful if you want to JSON.stringify() the result of toObject(), defaults to false
* - `useProjection` set to `true` to omit fields that are excluded in this document's projection. Unless you specified a projection, this will omit any field that has `select: false` in the schema.
*
* ####Getters/Virtuals
*
@@ -3238,6 +3286,7 @@ Document.prototype.$toObject = function(options, json) {
* @param {Boolean} [options.depopulate=false] if true, replace any conventionally populated paths with the original id in the output. Has no affect on virtual populated paths.
* @param {Boolean} [options.versionKey=true] if false, exclude the version key (`__v` by default) from the output
* @param {Boolean} [options.flattenMaps=false] if true, convert Maps to POJOs. Useful if you want to `JSON.stringify()` the result of `toObject()`.
* @param {Boolean} [options.useProjection=false] - If true, omits fields that are excluded in this document's projection. Unless you specified a projection, this will omit any field that has `select: false` in the schema.
* @return {Object} js object
* @see mongodb.Binary http://mongodb.github.com/node-mongodb-native/api-bson-generated/binary.html
* @api public
@@ -3441,6 +3490,37 @@ function throwErrorIfPromise(path, transformedValue) {
}
}
/*!
* ignore
*/
function omitDeselectedFields(self, json) {
const schema = self.schema;
const paths = Object.keys(schema.paths || {});
const cur = self._doc;
if (!cur) {
return json;
}
let selected = self.$__.selected;
if (selected === void 0) {
selected = {};
queryhelpers.applyPaths(selected, schema);
}
if (selected == null || Object.keys(selected).length === 0) {
return json;
}
for (const path of paths) {
if (selected[path] != null && !selected[path]) {
delete json[path];
}
}
return json;
}
/**
* The return value of this method is used in calls to JSON.stringify(doc).
*
@@ -3463,6 +3543,20 @@ Document.prototype.toJSON = function(options) {
return this.$toObject(options, true);
};
/**
* If this document is a subdocument or populated document, returns the document's
* parent. Returns `undefined` otherwise.
*
* @api public
* @method parent
* @memberOf Document
* @instance
*/
Document.prototype.parent = function() {
return this.$__.parent;
};
/**
* Helper for console.log
*
@@ -3836,6 +3930,45 @@ Document.prototype.$__fullPath = function(path) {
return path || '';
};
/**
* Returns the changes that happened to the document
* in the format that will be sent to MongoDB.
*
* ###Example:
* const userSchema = new Schema({
* name: String,
* age: Number,
* country: String
* });
* const User = mongoose.model('User', userSchema);
* const user = await User.create({
* name: 'Hafez',
* age: 25,
* country: 'Egypt'
* });
*
* // returns an empty object, no changes happened yet
* user.getChanges(); // { }
*
* user.country = undefined;
* user.age = 26;
*
* user.getChanges(); // { $set: { age: 26 }, { $unset: { country: 1 } } }
*
* await user.save();
*
* user.getChanges(); // { }
*
* @return {Object} changes
*/
Document.prototype.getChanges = function() {
const delta = this.$__delta();
const changes = delta ? delta[1] : {};
return changes;
};
/*!
* Module exports.
*/