summaryrefslogtreecommitdiffstats
path: root/common/src/main/webapp/usageguide/appserver/node_modules/mongoose/lib/schema.js
diff options
context:
space:
mode:
Diffstat (limited to 'common/src/main/webapp/usageguide/appserver/node_modules/mongoose/lib/schema.js')
-rw-r--r--common/src/main/webapp/usageguide/appserver/node_modules/mongoose/lib/schema.js1768
1 files changed, 0 insertions, 1768 deletions
diff --git a/common/src/main/webapp/usageguide/appserver/node_modules/mongoose/lib/schema.js b/common/src/main/webapp/usageguide/appserver/node_modules/mongoose/lib/schema.js
deleted file mode 100644
index 7e28f58..0000000
--- a/common/src/main/webapp/usageguide/appserver/node_modules/mongoose/lib/schema.js
+++ /dev/null
@@ -1,1768 +0,0 @@
-/*!
- * Module dependencies.
- */
-
-var readPref = require('./drivers').ReadPreference;
-var EventEmitter = require('events').EventEmitter;
-var VirtualType = require('./virtualtype');
-var utils = require('./utils');
-var MongooseTypes;
-var Kareem = require('kareem');
-var each = require('async/each');
-var SchemaType = require('./schematype');
-
-var IS_KAREEM_HOOK = {
- count: true,
- find: true,
- findOne: true,
- findOneAndUpdate: true,
- findOneAndRemove: true,
- insertMany: true,
- update: true
-};
-
-/**
- * Schema constructor.
- *
- * ####Example:
- *
- * var child = new Schema({ name: String });
- * var schema = new Schema({ name: String, age: Number, children: [child] });
- * var Tree = mongoose.model('Tree', schema);
- *
- * // setting schema options
- * new Schema({ name: String }, { _id: false, autoIndex: false })
- *
- * ####Options:
- *
- * - [autoIndex](/docs/guide.html#autoIndex): bool - defaults to null (which means use the connection's autoIndex option)
- * - [bufferCommands](/docs/guide.html#bufferCommands): bool - defaults to true
- * - [capped](/docs/guide.html#capped): bool - defaults to false
- * - [collection](/docs/guide.html#collection): string - no default
- * - [emitIndexErrors](/docs/guide.html#emitIndexErrors): bool - defaults to false.
- * - [id](/docs/guide.html#id): bool - defaults to true
- * - [_id](/docs/guide.html#_id): bool - defaults to true
- * - `minimize`: bool - controls [document#toObject](#document_Document-toObject) behavior when called manually - defaults to true
- * - [read](/docs/guide.html#read): string
- * - [safe](/docs/guide.html#safe): bool - defaults to true.
- * - [shardKey](/docs/guide.html#shardKey): bool - defaults to `null`
- * - [strict](/docs/guide.html#strict): bool - defaults to true
- * - [toJSON](/docs/guide.html#toJSON) - object - no default
- * - [toObject](/docs/guide.html#toObject) - object - no default
- * - [typeKey](/docs/guide.html#typeKey) - string - defaults to 'type'
- * - [useNestedStrict](/docs/guide.html#useNestedStrict) - boolean - defaults to false
- * - [validateBeforeSave](/docs/guide.html#validateBeforeSave) - bool - defaults to `true`
- * - [versionKey](/docs/guide.html#versionKey): string - defaults to "__v"
- *
- * ####Note:
- *
- * _When nesting schemas, (`children` in the example above), always declare the child schema first before passing it into its parent._
- *
- * @param {Object} definition
- * @param {Object} [options]
- * @inherits NodeJS EventEmitter http://nodejs.org/api/events.html#events_class_events_eventemitter
- * @event `init`: Emitted after the schema is compiled into a `Model`.
- * @api public
- */
-
-function Schema(obj, options) {
- if (!(this instanceof Schema)) {
- return new Schema(obj, options);
- }
-
- this.obj = obj;
- this.paths = {};
- this.subpaths = {};
- this.virtuals = {};
- this.singleNestedPaths = {};
- this.nested = {};
- this.inherits = {};
- this.callQueue = [];
- this._indexes = [];
- this.methods = {};
- this.statics = {};
- this.tree = {};
- this._requiredpaths = undefined;
- this.discriminatorMapping = undefined;
- this._indexedpaths = undefined;
- this.query = {};
- this.childSchemas = [];
-
- this.s = {
- hooks: new Kareem(),
- kareemHooks: IS_KAREEM_HOOK
- };
-
- this.options = this.defaultOptions(options);
-
- // build paths
- if (obj) {
- this.add(obj);
- }
-
- // check if _id's value is a subdocument (gh-2276)
- var _idSubDoc = obj && obj._id && utils.isObject(obj._id);
-
- // ensure the documents get an auto _id unless disabled
- var auto_id = !this.paths['_id'] &&
- (!this.options.noId && this.options._id) && !_idSubDoc;
-
- if (auto_id) {
- obj = {_id: {auto: true}};
- obj._id[this.options.typeKey] = Schema.ObjectId;
- this.add(obj);
- }
-
- // ensure the documents receive an id getter unless disabled
- var autoid = !this.paths['id'] &&
- (!this.options.noVirtualId && this.options.id);
- if (autoid) {
- this.virtual('id').get(idGetter);
- }
-
- for (var i = 0; i < this._defaultMiddleware.length; ++i) {
- var m = this._defaultMiddleware[i];
- this[m.kind](m.hook, !!m.isAsync, m.fn);
- }
-
- if (this.options.timestamps) {
- this.setupTimestamp(this.options.timestamps);
- }
-}
-
-/*!
- * Returns this documents _id cast to a string.
- */
-
-function idGetter() {
- if (this.$__._id) {
- return this.$__._id;
- }
-
- this.$__._id = this._id == null
- ? null
- : String(this._id);
- return this.$__._id;
-}
-
-/*!
- * Inherit from EventEmitter.
- */
-Schema.prototype = Object.create(EventEmitter.prototype);
-Schema.prototype.constructor = Schema;
-Schema.prototype.instanceOfSchema = true;
-
-/**
- * Default middleware attached to a schema. Cannot be changed.
- *
- * This field is used to make sure discriminators don't get multiple copies of
- * built-in middleware. Declared as a constant because changing this at runtime
- * may lead to instability with Model.prototype.discriminator().
- *
- * @api private
- * @property _defaultMiddleware
- */
-Object.defineProperty(Schema.prototype, '_defaultMiddleware', {
- configurable: false,
- enumerable: false,
- writable: false,
- value: [
- {
- kind: 'pre',
- hook: 'save',
- fn: function(next, options) {
- var _this = this;
- // Nested docs have their own presave
- if (this.ownerDocument) {
- return next();
- }
-
- var hasValidateBeforeSaveOption = options &&
- (typeof options === 'object') &&
- ('validateBeforeSave' in options);
-
- var shouldValidate;
- if (hasValidateBeforeSaveOption) {
- shouldValidate = !!options.validateBeforeSave;
- } else {
- shouldValidate = this.schema.options.validateBeforeSave;
- }
-
- // Validate
- if (shouldValidate) {
- // HACK: use $__original_validate to avoid promises so bluebird doesn't
- // complain
- if (this.$__original_validate) {
- this.$__original_validate({__noPromise: true}, function(error) {
- return _this.schema.s.hooks.execPost('save:error', _this, [_this], { error: error }, function(error) {
- next(error);
- });
- });
- } else {
- this.validate({__noPromise: true}, function(error) {
- return _this.schema.s.hooks.execPost('save:error', _this, [ _this], { error: error }, function(error) {
- next(error);
- });
- });
- }
- } else {
- next();
- }
- }
- },
- {
- kind: 'pre',
- hook: 'save',
- isAsync: true,
- fn: function(next, done) {
- var _this = this;
- var subdocs = this.$__getAllSubdocs();
-
- if (!subdocs.length || this.$__preSavingFromParent) {
- done();
- next();
- return;
- }
-
- each(subdocs, function(subdoc, cb) {
- subdoc.$__preSavingFromParent = true;
- subdoc.save(function(err) {
- cb(err);
- });
- }, function(error) {
- for (var i = 0; i < subdocs.length; ++i) {
- delete subdocs[i].$__preSavingFromParent;
- }
- if (error) {
- return _this.schema.s.hooks.execPost('save:error', _this, [_this], { error: error }, function(error) {
- done(error);
- });
- }
- next();
- done();
- });
- }
- },
- {
- kind: 'pre',
- hook: 'validate',
- isAsync: true,
- fn: function(next, done) {
- // Hack to ensure that we always wrap validate() in a promise
- next();
- done();
- }
- },
- {
- kind: 'pre',
- hook: 'remove',
- isAsync: true,
- fn: function(next, done) {
- if (this.ownerDocument) {
- done();
- next();
- return;
- }
-
- var subdocs = this.$__getAllSubdocs();
-
- if (!subdocs.length || this.$__preSavingFromParent) {
- done();
- next();
- return;
- }
-
- each(subdocs, function(subdoc, cb) {
- subdoc.remove({ noop: true }, function(err) {
- cb(err);
- });
- }, function(error) {
- if (error) {
- done(error);
- return;
- }
- next();
- done();
- });
- }
- }
- ]
-});
-
-
-/**
- * The original object passed to the schema constructor
- *
- * ####Example:
- *
- * var schema = new Schema({ a: String }).add({ b: String });
- * schema.obj; // { a: String }
- *
- * @api public
- * @property obj
- */
-
-Schema.prototype.obj;
-
-/**
- * Schema as flat paths
- *
- * ####Example:
- * {
- * '_id' : SchemaType,
- * , 'nested.key' : SchemaType,
- * }
- *
- * @api private
- * @property paths
- */
-
-Schema.prototype.paths;
-
-/**
- * Schema as a tree
- *
- * ####Example:
- * {
- * '_id' : ObjectId
- * , 'nested' : {
- * 'key' : String
- * }
- * }
- *
- * @api private
- * @property tree
- */
-
-Schema.prototype.tree;
-
-/**
- * Returns default options for this schema, merged with `options`.
- *
- * @param {Object} options
- * @return {Object}
- * @api private
- */
-
-Schema.prototype.defaultOptions = function(options) {
- if (options && options.safe === false) {
- options.safe = {w: 0};
- }
-
- if (options && options.safe && options.safe.w === 0) {
- // if you turn off safe writes, then versioning goes off as well
- options.versionKey = false;
- }
-
- options = utils.options({
- strict: true,
- bufferCommands: true,
- capped: false, // { size, max, autoIndexId }
- versionKey: '__v',
- discriminatorKey: '__t',
- minimize: true,
- autoIndex: null,
- shardKey: null,
- read: null,
- validateBeforeSave: true,
- // the following are only applied at construction time
- noId: false, // deprecated, use { _id: false }
- _id: true,
- noVirtualId: false, // deprecated, use { id: false }
- id: true,
- typeKey: 'type',
- retainKeyOrder: false
- }, options);
-
- if (options.read) {
- options.read = readPref(options.read);
- }
-
- return options;
-};
-
-/**
- * Adds key path / schema type pairs to this schema.
- *
- * ####Example:
- *
- * var ToySchema = new Schema;
- * ToySchema.add({ name: 'string', color: 'string', price: 'number' });
- *
- * @param {Object} obj
- * @param {String} prefix
- * @api public
- */
-
-Schema.prototype.add = function add(obj, prefix) {
- prefix = prefix || '';
- var keys = Object.keys(obj);
-
- for (var i = 0; i < keys.length; ++i) {
- var key = keys[i];
-
- if (obj[key] == null) {
- throw new TypeError('Invalid value for schema path `' + prefix + key + '`');
- }
-
- if (Array.isArray(obj[key]) && obj[key].length === 1 && obj[key][0] == null) {
- throw new TypeError('Invalid value for schema Array path `' + prefix + key + '`');
- }
-
- if (utils.isObject(obj[key]) &&
- (!obj[key].constructor || utils.getFunctionName(obj[key].constructor) === 'Object') &&
- (!obj[key][this.options.typeKey] || (this.options.typeKey === 'type' && obj[key].type.type))) {
- if (Object.keys(obj[key]).length) {
- // nested object { last: { name: String }}
- this.nested[prefix + key] = true;
- this.add(obj[key], prefix + key + '.');
- } else {
- if (prefix) {
- this.nested[prefix.substr(0, prefix.length - 1)] = true;
- }
- this.path(prefix + key, obj[key]); // mixed type
- }
- } else {
- if (prefix) {
- this.nested[prefix.substr(0, prefix.length - 1)] = true;
- }
- this.path(prefix + key, obj[key]);
- }
- }
-};
-
-/**
- * Reserved document keys.
- *
- * Keys in this object are names that are rejected in schema declarations b/c they conflict with mongoose functionality. Using these key name will throw an error.
- *
- * on, emit, _events, db, get, set, init, isNew, errors, schema, options, modelName, collection, _pres, _posts, toObject
- *
- * _NOTE:_ Use of these terms as method names is permitted, but play at your own risk, as they may be existing mongoose document methods you are stomping on.
- *
- * var schema = new Schema(..);
- * schema.methods.init = function () {} // potentially breaking
- */
-
-Schema.reserved = Object.create(null);
-var reserved = Schema.reserved;
-// Core object
-reserved['prototype'] =
-// EventEmitter
-reserved.emit =
-reserved.on =
-reserved.once =
-reserved.listeners =
-reserved.removeListener =
-// document properties and functions
-reserved.collection =
-reserved.db =
-reserved.errors =
-reserved.init =
-reserved.isModified =
-reserved.isNew =
-reserved.get =
-reserved.modelName =
-reserved.save =
-reserved.schema =
-reserved.set =
-reserved.toObject =
-reserved.validate =
-// hooks.js
-reserved._pres = reserved._posts = 1;
-
-/*!
- * Document keys to print warnings for
- */
-
-var warnings = {};
-warnings.increment = '`increment` should not be used as a schema path name ' +
- 'unless you have disabled versioning.';
-
-/**
- * Gets/sets schema paths.
- *
- * Sets a path (if arity 2)
- * Gets a path (if arity 1)
- *
- * ####Example
- *
- * schema.path('name') // returns a SchemaType
- * schema.path('name', Number) // changes the schemaType of `name` to Number
- *
- * @param {String} path
- * @param {Object} constructor
- * @api public
- */
-
-Schema.prototype.path = function(path, obj) {
- if (obj === undefined) {
- if (this.paths[path]) {
- return this.paths[path];
- }
- if (this.subpaths[path]) {
- return this.subpaths[path];
- }
- if (this.singleNestedPaths[path]) {
- return this.singleNestedPaths[path];
- }
-
- // subpaths?
- return /\.\d+\.?.*$/.test(path)
- ? getPositionalPath(this, path)
- : undefined;
- }
-
- // some path names conflict with document methods
- if (reserved[path]) {
- throw new Error('`' + path + '` may not be used as a schema pathname');
- }
-
- if (warnings[path]) {
- console.log('WARN: ' + warnings[path]);
- }
-
- // update the tree
- var subpaths = path.split(/\./),
- last = subpaths.pop(),
- branch = this.tree;
-
- subpaths.forEach(function(sub, i) {
- if (!branch[sub]) {
- branch[sub] = {};
- }
- if (typeof branch[sub] !== 'object') {
- var msg = 'Cannot set nested path `' + path + '`. '
- + 'Parent path `'
- + subpaths.slice(0, i).concat([sub]).join('.')
- + '` already set to type ' + branch[sub].name
- + '.';
- throw new Error(msg);
- }
- branch = branch[sub];
- });
-
- branch[last] = utils.clone(obj);
-
- this.paths[path] = Schema.interpretAsType(path, obj, this.options);
-
- if (this.paths[path].$isSingleNested) {
- for (var key in this.paths[path].schema.paths) {
- this.singleNestedPaths[path + '.' + key] =
- this.paths[path].schema.paths[key];
- }
- for (key in this.paths[path].schema.singleNestedPaths) {
- this.singleNestedPaths[path + '.' + key] =
- this.paths[path].schema.singleNestedPaths[key];
- }
-
- this.childSchemas.push(this.paths[path].schema);
- } else if (this.paths[path].$isMongooseDocumentArray) {
- this.childSchemas.push(this.paths[path].schema);
- }
- return this;
-};
-
-/**
- * Converts type arguments into Mongoose Types.
- *
- * @param {String} path
- * @param {Object} obj constructor
- * @api private
- */
-
-Schema.interpretAsType = function(path, obj, options) {
- if (obj.constructor) {
- var constructorName = utils.getFunctionName(obj.constructor);
- if (constructorName !== 'Object') {
- var oldObj = obj;
- obj = {};
- obj[options.typeKey] = oldObj;
- }
- }
-
- // Get the type making sure to allow keys named "type"
- // and default to mixed if not specified.
- // { type: { type: String, default: 'freshcut' } }
- var type = obj[options.typeKey] && (options.typeKey !== 'type' || !obj.type.type)
- ? obj[options.typeKey]
- : {};
-
- if (utils.getFunctionName(type.constructor) === 'Object' || type === 'mixed') {
- return new MongooseTypes.Mixed(path, obj);
- }
-
- if (Array.isArray(type) || Array === type || type === 'array') {
- // if it was specified through { type } look for `cast`
- var cast = (Array === type || type === 'array')
- ? obj.cast
- : type[0];
-
- if (cast && cast.instanceOfSchema) {
- return new MongooseTypes.DocumentArray(path, cast, obj);
- }
-
- if (Array.isArray(cast)) {
- return new MongooseTypes.Array(path, Schema.interpretAsType(path, cast, options), obj);
- }
-
- if (typeof cast === 'string') {
- cast = MongooseTypes[cast.charAt(0).toUpperCase() + cast.substring(1)];
- } else if (cast && (!cast[options.typeKey] || (options.typeKey === 'type' && cast.type.type))
- && utils.getFunctionName(cast.constructor) === 'Object') {
- if (Object.keys(cast).length) {
- // The `minimize` and `typeKey` options propagate to child schemas
- // declared inline, like `{ arr: [{ val: { $type: String } }] }`.
- // See gh-3560
- var childSchemaOptions = {minimize: options.minimize};
- if (options.typeKey) {
- childSchemaOptions.typeKey = options.typeKey;
- }
- var childSchema = new Schema(cast, childSchemaOptions);
- childSchema.$implicitlyCreated = true;
- return new MongooseTypes.DocumentArray(path, childSchema, obj);
- } else {
- // Special case: empty object becomes mixed
- return new MongooseTypes.Array(path, MongooseTypes.Mixed, obj);
- }
- }
-
- if (cast) {
- type = cast[options.typeKey] && (options.typeKey !== 'type' || !cast.type.type)
- ? cast[options.typeKey]
- : cast;
-
- name = typeof type === 'string'
- ? type
- : type.schemaName || utils.getFunctionName(type);
-
- if (!(name in MongooseTypes)) {
- throw new TypeError('Undefined type `' + name + '` at array `' + path +
- '`');
- }
- }
-
- return new MongooseTypes.Array(path, cast || MongooseTypes.Mixed, obj, options);
- }
-
- if (type && type.instanceOfSchema) {
- return new MongooseTypes.Embedded(type, path, obj);
- }
-
- var name;
- if (Buffer.isBuffer(type)) {
- name = 'Buffer';
- } else {
- name = typeof type === 'string'
- ? type
- // If not string, `type` is a function. Outside of IE, function.name
- // gives you the function name. In IE, you need to compute it
- : type.schemaName || utils.getFunctionName(type);
- }
-
- if (name) {
- name = name.charAt(0).toUpperCase() + name.substring(1);
- }
-
- if (undefined == MongooseTypes[name]) {
- throw new TypeError('Undefined type `' + name + '` at `' + path +
- '`\n Did you try nesting Schemas? ' +
- 'You can only nest using refs or arrays.');
- }
-
- return new MongooseTypes[name](path, obj);
-};
-
-/**
- * Iterates the schemas paths similar to Array#forEach.
- *
- * The callback is passed the pathname and schemaType as arguments on each iteration.
- *
- * @param {Function} fn callback function
- * @return {Schema} this
- * @api public
- */
-
-Schema.prototype.eachPath = function(fn) {
- var keys = Object.keys(this.paths),
- len = keys.length;
-
- for (var i = 0; i < len; ++i) {
- fn(keys[i], this.paths[keys[i]]);
- }
-
- return this;
-};
-
-/**
- * Returns an Array of path strings that are required by this schema.
- *
- * @api public
- * @param {Boolean} invalidate refresh the cache
- * @return {Array}
- */
-
-Schema.prototype.requiredPaths = function requiredPaths(invalidate) {
- if (this._requiredpaths && !invalidate) {
- return this._requiredpaths;
- }
-
- var paths = Object.keys(this.paths),
- i = paths.length,
- ret = [];
-
- while (i--) {
- var path = paths[i];
- if (this.paths[path].isRequired) {
- ret.push(path);
- }
- }
- this._requiredpaths = ret;
- return this._requiredpaths;
-};
-
-/**
- * Returns indexes from fields and schema-level indexes (cached).
- *
- * @api private
- * @return {Array}
- */
-
-Schema.prototype.indexedPaths = function indexedPaths() {
- if (this._indexedpaths) {
- return this._indexedpaths;
- }
- this._indexedpaths = this.indexes();
- return this._indexedpaths;
-};
-
-/**
- * Returns the pathType of `path` for this schema.
- *
- * Given a path, returns whether it is a real, virtual, nested, or ad-hoc/undefined path.
- *
- * @param {String} path
- * @return {String}
- * @api public
- */
-
-Schema.prototype.pathType = function(path) {
- if (path in this.paths) {
- return 'real';
- }
- if (path in this.virtuals) {
- return 'virtual';
- }
- if (path in this.nested) {
- return 'nested';
- }
- if (path in this.subpaths) {
- return 'real';
- }
- if (path in this.singleNestedPaths) {
- return 'real';
- }
-
- if (/\.\d+\.|\.\d+$/.test(path)) {
- return getPositionalPathType(this, path);
- }
- return 'adhocOrUndefined';
-};
-
-/**
- * Returns true iff this path is a child of a mixed schema.
- *
- * @param {String} path
- * @return {Boolean}
- * @api private
- */
-
-Schema.prototype.hasMixedParent = function(path) {
- var subpaths = path.split(/\./g);
- path = '';
- for (var i = 0; i < subpaths.length; ++i) {
- path = i > 0 ? path + '.' + subpaths[i] : subpaths[i];
- if (path in this.paths &&
- this.paths[path] instanceof MongooseTypes.Mixed) {
- return true;
- }
- }
-
- return false;
-};
-
-/**
- * Setup updatedAt and createdAt timestamps to documents if enabled
- *
- * @param {Boolean|Object} timestamps timestamps options
- * @api private
- */
-Schema.prototype.setupTimestamp = function(timestamps) {
- if (timestamps) {
- var createdAt = timestamps.createdAt || 'createdAt';
- var updatedAt = timestamps.updatedAt || 'updatedAt';
- var schemaAdditions = {};
-
- schemaAdditions[updatedAt] = Date;
-
- if (!this.paths[createdAt]) {
- schemaAdditions[createdAt] = Date;
- }
-
- this.add(schemaAdditions);
-
- this.pre('save', function(next) {
- var defaultTimestamp = new Date();
- var auto_id = this._id && this._id.auto;
-
- if (!this[createdAt] && this.isSelected(createdAt)) {
- this[createdAt] = auto_id ? this._id.getTimestamp() : defaultTimestamp;
- }
-
- if (this.isNew || this.isModified()) {
- this[updatedAt] = this.isNew ? this[createdAt] : defaultTimestamp;
- }
-
- next();
- });
-
- var genUpdates = function(overwrite) {
- var now = new Date();
- var updates = {};
- if (overwrite) {
- updates[updatedAt] = now;
- updates[createdAt] = now;
- return updates;
- }
- updates = { $set: {}, $setOnInsert: {} };
- updates.$set[updatedAt] = now;
- updates.$setOnInsert[createdAt] = now;
-
- return updates;
- };
-
- this.methods.initializeTimestamps = function() {
- if (!this[createdAt]) {
- this[createdAt] = new Date();
- }
- if (!this[updatedAt]) {
- this[updatedAt] = new Date();
- }
- return this;
- };
-
- this.pre('findOneAndUpdate', function(next) {
- var overwrite = this.options.overwrite;
- this.findOneAndUpdate({}, genUpdates(overwrite), { overwrite: overwrite });
- applyTimestampsToChildren(this);
- next();
- });
-
- this.pre('update', function(next) {
- var overwrite = this.options.overwrite;
- this.update({}, genUpdates(overwrite), { overwrite: overwrite });
- applyTimestampsToChildren(this);
- next();
- });
- }
-};
-
-/*!
- * ignore
- */
-
-function applyTimestampsToChildren(query) {
- var now = new Date();
- var update = query.getUpdate();
- var keys = Object.keys(update);
- var key;
- var schema = query.model.schema;
- var len;
- var createdAt;
- var updatedAt;
- var timestamps;
- var path;
-
- var hasDollarKey = keys.length && keys[0].charAt(0) === '$';
-
- if (hasDollarKey) {
- if (update.$push) {
- for (key in update.$push) {
- var $path = schema.path(key);
- if (update.$push[key] &&
- $path &&
- $path.$isMongooseDocumentArray &&
- $path.schema.options.timestamps) {
- timestamps = $path.schema.options.timestamps;
- createdAt = timestamps.createdAt || 'createdAt';
- updatedAt = timestamps.updatedAt || 'updatedAt';
- update.$push[key][updatedAt] = now;
- update.$push[key][createdAt] = now;
- }
- }
- }
- if (update.$set) {
- for (key in update.$set) {
- path = schema.path(key);
- if (!path) {
- continue;
- }
- if (Array.isArray(update.$set[key]) && path.$isMongooseDocumentArray) {
- len = update.$set[key].length;
- timestamps = schema.path(key).schema.options.timestamps;
- if (timestamps) {
- createdAt = timestamps.createdAt || 'createdAt';
- updatedAt = timestamps.updatedAt || 'updatedAt';
- for (var i = 0; i < len; ++i) {
- update.$set[key][i][updatedAt] = now;
- update.$set[key][i][createdAt] = now;
- }
- }
- } else if (update.$set[key] && path.$isSingleNested) {
- timestamps = schema.path(key).schema.options.timestamps;
- if (timestamps) {
- createdAt = timestamps.createdAt || 'createdAt';
- updatedAt = timestamps.updatedAt || 'updatedAt';
- update.$set[key][updatedAt] = now;
- update.$set[key][createdAt] = now;
- }
- }
- }
- }
- }
-}
-
-/*!
- * ignore
- */
-
-function getPositionalPathType(self, path) {
- var subpaths = path.split(/\.(\d+)\.|\.(\d+)$/).filter(Boolean);
- if (subpaths.length < 2) {
- return self.paths[subpaths[0]];
- }
-
- var val = self.path(subpaths[0]);
- var isNested = false;
- if (!val) {
- return val;
- }
-
- var last = subpaths.length - 1,
- subpath,
- i = 1;
-
- for (; i < subpaths.length; ++i) {
- isNested = false;
- subpath = subpaths[i];
-
- if (i === last && val && !/\D/.test(subpath)) {
- if (val.$isMongooseDocumentArray) {
- var oldVal = val;
- val = new SchemaType(subpath);
- val.cast = function(value, doc, init) {
- return oldVal.cast(value, doc, init)[0];
- };
- val.caster = oldVal.caster;
- val.schema = oldVal.schema;
- } else if (val instanceof MongooseTypes.Array) {
- // StringSchema, NumberSchema, etc
- val = val.caster;
- } else {
- val = undefined;
- }
- break;
- }
-
- // ignore if its just a position segment: path.0.subpath
- if (!/\D/.test(subpath)) {
- continue;
- }
-
- if (!(val && val.schema)) {
- val = undefined;
- break;
- }
-
- var type = val.schema.pathType(subpath);
- isNested = (type === 'nested');
- val = val.schema.path(subpath);
- }
-
- self.subpaths[path] = val;
- if (val) {
- return 'real';
- }
- if (isNested) {
- return 'nested';
- }
- return 'adhocOrUndefined';
-}
-
-
-/*!
- * ignore
- */
-
-function getPositionalPath(self, path) {
- getPositionalPathType(self, path);
- return self.subpaths[path];
-}
-
-/**
- * Adds a method call to the queue.
- *
- * @param {String} name name of the document method to call later
- * @param {Array} args arguments to pass to the method
- * @api public
- */
-
-Schema.prototype.queue = function(name, args) {
- this.callQueue.push([name, args]);
- return this;
-};
-
-/**
- * Defines a pre hook for the document.
- *
- * ####Example
- *
- * var toySchema = new Schema(..);
- *
- * toySchema.pre('save', function (next) {
- * if (!this.created) this.created = new Date;
- * next();
- * })
- *
- * toySchema.pre('validate', function (next) {
- * if (this.name !== 'Woody') this.name = 'Woody';
- * next();
- * })
- *
- * @param {String} method
- * @param {Function} callback
- * @see hooks.js https://github.com/bnoguchi/hooks-js/tree/31ec571cef0332e21121ee7157e0cf9728572cc3
- * @api public
- */
-
-Schema.prototype.pre = function() {
- var name = arguments[0];
- if (IS_KAREEM_HOOK[name]) {
- this.s.hooks.pre.apply(this.s.hooks, arguments);
- return this;
- }
- return this.queue('pre', arguments);
-};
-
-/**
- * Defines a post hook for the document
- *
- * var schema = new Schema(..);
- * schema.post('save', function (doc) {
- * console.log('this fired after a document was saved');
- * });
- *
- * shema.post('find', function(docs) {
- * console.log('this fired after you run a find query');
- * });
- *
- * var Model = mongoose.model('Model', schema);
- *
- * var m = new Model(..);
- * m.save(function(err) {
- * console.log('this fires after the `post` hook');
- * });
- *
- * m.find(function(err, docs) {
- * console.log('this fires after the post find hook');
- * });
- *
- * @param {String} method name of the method to hook
- * @param {Function} fn callback
- * @see middleware http://mongoosejs.com/docs/middleware.html
- * @see hooks.js https://www.npmjs.com/package/hooks-fixed
- * @see kareem http://npmjs.org/package/kareem
- * @api public
- */
-
-Schema.prototype.post = function(method, fn) {
- if (IS_KAREEM_HOOK[method]) {
- this.s.hooks.post.apply(this.s.hooks, arguments);
- return this;
- }
- // assuming that all callbacks with arity < 2 are synchronous post hooks
- if (fn.length < 2) {
- return this.queue('on', [arguments[0], function(doc) {
- return fn.call(doc, doc);
- }]);
- }
-
- if (fn.length === 3) {
- this.s.hooks.post(method + ':error', fn);
- return this;
- }
-
- return this.queue('post', [arguments[0], function(next) {
- // wrap original function so that the callback goes last,
- // for compatibility with old code that is using synchronous post hooks
- var _this = this;
- var args = Array.prototype.slice.call(arguments, 1);
- fn.call(this, this, function(err) {
- return next.apply(_this, [err].concat(args));
- });
- }]);
-};
-
-/**
- * Registers a plugin for this schema.
- *
- * @param {Function} plugin callback
- * @param {Object} [opts]
- * @see plugins
- * @api public
- */
-
-Schema.prototype.plugin = function(fn, opts) {
- fn(this, opts);
- return this;
-};
-
-/**
- * Adds an instance method to documents constructed from Models compiled from this schema.
- *
- * ####Example
- *
- * var schema = kittySchema = new Schema(..);
- *
- * schema.method('meow', function () {
- * console.log('meeeeeoooooooooooow');
- * })
- *
- * var Kitty = mongoose.model('Kitty', schema);
- *
- * var fizz = new Kitty;
- * fizz.meow(); // meeeeeooooooooooooow
- *
- * If a hash of name/fn pairs is passed as the only argument, each name/fn pair will be added as methods.
- *
- * schema.method({
- * purr: function () {}
- * , scratch: function () {}
- * });
- *
- * // later
- * fizz.purr();
- * fizz.scratch();
- *
- * @param {String|Object} method name
- * @param {Function} [fn]
- * @api public
- */
-
-Schema.prototype.method = function(name, fn) {
- if (typeof name !== 'string') {
- for (var i in name) {
- this.methods[i] = name[i];
- }
- } else {
- this.methods[name] = fn;
- }
- return this;
-};
-
-/**
- * Adds static "class" methods to Models compiled from this schema.
- *
- * ####Example
- *
- * var schema = new Schema(..);
- * schema.static('findByName', function (name, callback) {
- * return this.find({ name: name }, callback);
- * });
- *
- * var Drink = mongoose.model('Drink', schema);
- * Drink.findByName('sanpellegrino', function (err, drinks) {
- * //
- * });
- *
- * If a hash of name/fn pairs is passed as the only argument, each name/fn pair will be added as statics.
- *
- * @param {String|Object} name
- * @param {Function} [fn]
- * @api public
- */
-
-Schema.prototype.static = function(name, fn) {
- if (typeof name !== 'string') {
- for (var i in name) {
- this.statics[i] = name[i];
- }
- } else {
- this.statics[name] = fn;
- }
- return this;
-};
-
-/**
- * Defines an index (most likely compound) for this schema.
- *
- * ####Example
- *
- * schema.index({ first: 1, last: -1 })
- *
- * @param {Object} fields
- * @param {Object} [options] Options to pass to [MongoDB driver's `createIndex()` function](http://mongodb.github.io/node-mongodb-native/2.0/api/Collection.html#createIndex)
- * @param {String} [options.expires=null] Mongoose-specific syntactic sugar, uses [ms](https://www.npmjs.com/package/ms) to convert `expires` option into seconds for the `expireAfterSeconds` in the above link.
- * @api public
- */
-
-Schema.prototype.index = function(fields, options) {
- options || (options = {});
-
- if (options.expires) {
- utils.expires(options);
- }
-
- this._indexes.push([fields, options]);
- return this;
-};
-
-/**
- * Sets/gets a schema option.
- *
- * ####Example
- *
- * schema.set('strict'); // 'true' by default
- * schema.set('strict', false); // Sets 'strict' to false
- * schema.set('strict'); // 'false'
- *
- * @param {String} key option name
- * @param {Object} [value] if not passed, the current option value is returned
- * @see Schema ./
- * @api public
- */
-
-Schema.prototype.set = function(key, value, _tags) {
- if (arguments.length === 1) {
- return this.options[key];
- }
-
- switch (key) {
- case 'read':
- this.options[key] = readPref(value, _tags);
- break;
- case 'safe':
- this.options[key] = value === false
- ? {w: 0}
- : value;
- break;
- case 'timestamps':
- this.setupTimestamp(value);
- this.options[key] = value;
- break;
- default:
- this.options[key] = value;
- }
-
- return this;
-};
-
-/**
- * Gets a schema option.
- *
- * @param {String} key option name
- * @api public
- */
-
-Schema.prototype.get = function(key) {
- return this.options[key];
-};
-
-/**
- * The allowed index types
- *
- * @static indexTypes
- * @receiver Schema
- * @api public
- */
-
-var indexTypes = '2d 2dsphere hashed text'.split(' ');
-
-Object.defineProperty(Schema, 'indexTypes', {
- get: function() {
- return indexTypes;
- },
- set: function() {
- throw new Error('Cannot overwrite Schema.indexTypes');
- }
-});
-
-/**
- * Compiles indexes from fields and schema-level indexes
- *
- * @api public
- */
-
-Schema.prototype.indexes = function() {
- 'use strict';
-
- var indexes = [];
- var seenPrefix = {};
-
- var collectIndexes = function(schema, prefix) {
- if (seenPrefix[prefix]) {
- return;
- }
- seenPrefix[prefix] = true;
-
- prefix = prefix || '';
- var key, path, index, field, isObject, options, type;
- var keys = Object.keys(schema.paths);
-
- for (var i = 0; i < keys.length; ++i) {
- key = keys[i];
- path = schema.paths[key];
-
- if ((path instanceof MongooseTypes.DocumentArray) || path.$isSingleNested) {
- collectIndexes(path.schema, key + '.');
- } else {
- index = path._index;
-
- if (index !== false && index !== null && index !== undefined) {
- field = {};
- isObject = utils.isObject(index);
- options = isObject ? index : {};
- type = typeof index === 'string' ? index :
- isObject ? index.type :
- false;
-
- if (type && ~Schema.indexTypes.indexOf(type)) {
- field[prefix + key] = type;
- } else if (options.text) {
- field[prefix + key] = 'text';
- delete options.text;
- } else {
- field[prefix + key] = 1;
- }
-
- delete options.type;
- if (!('background' in options)) {
- options.background = true;
- }
-
- indexes.push([field, options]);
- }
- }
- }
-
- if (prefix) {
- fixSubIndexPaths(schema, prefix);
- } else {
- schema._indexes.forEach(function(index) {
- if (!('background' in index[1])) {
- index[1].background = true;
- }
- });
- indexes = indexes.concat(schema._indexes);
- }
- };
-
- collectIndexes(this);
- return indexes;
-
- /*!
- * Checks for indexes added to subdocs using Schema.index().
- * These indexes need their paths prefixed properly.
- *
- * schema._indexes = [ [indexObj, options], [indexObj, options] ..]
- */
-
- function fixSubIndexPaths(schema, prefix) {
- var subindexes = schema._indexes,
- len = subindexes.length,
- indexObj,
- newindex,
- klen,
- keys,
- key,
- i = 0,
- j;
-
- for (i = 0; i < len; ++i) {
- indexObj = subindexes[i][0];
- keys = Object.keys(indexObj);
- klen = keys.length;
- newindex = {};
-
- // use forward iteration, order matters
- for (j = 0; j < klen; ++j) {
- key = keys[j];
- newindex[prefix + key] = indexObj[key];
- }
-
- indexes.push([newindex, subindexes[i][1]]);
- }
- }
-};
-
-/**
- * Creates a virtual type with the given name.
- *
- * @param {String} name
- * @param {Object} [options]
- * @return {VirtualType}
- */
-
-Schema.prototype.virtual = function(name, options) {
- if (options && options.ref) {
- if (!options.localField) {
- throw new Error('Reference virtuals require `localField` option');
- }
-
- if (!options.foreignField) {
- throw new Error('Reference virtuals require `foreignField` option');
- }
-
- this.pre('init', function(next, obj) {
- if (name in obj) {
- if (!this.$$populatedVirtuals) {
- this.$$populatedVirtuals = {};
- }
-
- if (options.justOne) {
- this.$$populatedVirtuals[name] = Array.isArray(obj[name]) ?
- obj[name][0] :
- obj[name];
- } else {
- this.$$populatedVirtuals[name] = Array.isArray(obj[name]) ?
- obj[name] :
- obj[name] == null ? [] : [obj[name]];
- }
-
- delete obj[name];
- }
- if (this.ownerDocument) {
- next();
- return obj;
- } else {
- next();
- }
- });
-
- var virtual = this.virtual(name);
- virtual.options = options;
- return virtual.
- get(function() {
- if (!this.$$populatedVirtuals) {
- this.$$populatedVirtuals = {};
- }
- if (name in this.$$populatedVirtuals) {
- return this.$$populatedVirtuals[name];
- }
- return null;
- }).
- set(function(v) {
- if (!this.$$populatedVirtuals) {
- this.$$populatedVirtuals = {};
- }
- this.$$populatedVirtuals[name] = v;
- });
- }
-
- var virtuals = this.virtuals;
- var parts = name.split('.');
-
- if (this.pathType(name) === 'real') {
- throw new Error('Virtual path "' + name + '"' +
- ' conflicts with a real path in the schema');
- }
-
- virtuals[name] = parts.reduce(function(mem, part, i) {
- mem[part] || (mem[part] = (i === parts.length - 1)
- ? new VirtualType(options, name)
- : {});
- return mem[part];
- }, this.tree);
-
- return virtuals[name];
-};
-
-/*!
- * ignore
- */
-
-Schema.prototype._getVirtual = function(name) {
- return _getVirtual(this, name);
-};
-
-/*!
- * ignore
- */
-
-function _getVirtual(schema, name) {
- var parts = name.split('.');
- var cur = '';
- var nestedSchemaPath = '';
- for (var i = 0; i < parts.length; ++i) {
- cur += (cur.length > 0 ? '.' : '') + parts[i];
- if (schema.virtuals[cur]) {
- if (i === parts.length - 1) {
- schema.virtuals[cur].$nestedSchemaPath = nestedSchemaPath;
- return schema.virtuals[cur];
- }
- continue;
- } else if (schema.paths[cur] && schema.paths[cur].schema) {
- schema = schema.paths[cur].schema;
- nestedSchemaPath += (nestedSchemaPath.length > 0 ? '.' : '') + cur;
- cur = '';
- } else {
- return null;
- }
- }
-}
-
-/**
- * Returns the virtual type with the given `name`.
- *
- * @param {String} name
- * @return {VirtualType}
- */
-
-Schema.prototype.virtualpath = function(name) {
- return this.virtuals[name];
-};
-
-/**
- * Removes the given `path` (or [`paths`]).
- *
- * @param {String|Array} path
- *
- * @api public
- */
-Schema.prototype.remove = function(path) {
- if (typeof path === 'string') {
- path = [path];
- }
- if (Array.isArray(path)) {
- path.forEach(function(name) {
- if (this.path(name)) {
- delete this.paths[name];
-
- var pieces = name.split('.');
- var last = pieces.pop();
- var branch = this.tree;
- for (var i = 0; i < pieces.length; ++i) {
- branch = branch[pieces[i]];
- }
- delete branch[last];
- }
- }, this);
- }
-};
-
-/**
- * Loads an ES6 class into a schema. Maps setters + getters, static methods, and instance methods to schema virtuals, statics, and methods.
- *
- * @param {Function} model
- */
-Schema.prototype.loadClass = function(model, virtualsOnly) {
- if (model === Object.prototype || model === Function.prototype) {
- return this;
- }
-
- // Add static methods
- if (!virtualsOnly) {
- Object.getOwnPropertyNames(model).forEach(function(name) {
- if (name.match(/^(length|name|prototype)$/)) {
- return;
- }
- var method = Object.getOwnPropertyDescriptor(model, name);
- if (typeof method.value === 'function') this.static(name, method.value);
- }, this);
- }
-
- // Add methods and virtuals
- Object.getOwnPropertyNames(model.prototype).forEach(function(name) {
- if (name.match(/^(constructor)$/)) {
- return;
- }
- var method = Object.getOwnPropertyDescriptor(model.prototype, name);
- if (!virtualsOnly) {
- if (typeof method.value === 'function') {
- this.method(name, method.value);
- }
- }
- if (typeof method.get === 'function') {
- this.virtual(name).get(method.get);
- }
- if (typeof method.set === 'function') {
- this.virtual(name).set(method.set);
- }
- }, this);
-
- return (this.loadClass(Object.getPrototypeOf(model)));
-};
-
-/*!
- * ignore
- */
-
-Schema.prototype._getSchema = function(path) {
- var _this = this;
- var pathschema = _this.path(path);
- var resultPath = [];
-
- if (pathschema) {
- pathschema.$fullPath = path;
- return pathschema;
- }
-
- function search(parts, schema) {
- var p = parts.length + 1,
- foundschema,
- trypath;
-
- while (p--) {
- trypath = parts.slice(0, p).join('.');
- foundschema = schema.path(trypath);
- if (foundschema) {
- resultPath.push(trypath);
-
- if (foundschema.caster) {
- // array of Mixed?
- if (foundschema.caster instanceof MongooseTypes.Mixed) {
- foundschema.caster.$fullPath = resultPath.join('.');
- return foundschema.caster;
- }
-
- // Now that we found the array, we need to check if there
- // are remaining document paths to look up for casting.
- // Also we need to handle array.$.path since schema.path
- // doesn't work for that.
- // If there is no foundschema.schema we are dealing with
- // a path like array.$
- if (p !== parts.length && foundschema.schema) {
- if (parts[p] === '$') {
- // comments.$.comments.$.title
- return search(parts.slice(p + 1), foundschema.schema);
- }
- // this is the last path of the selector
- return search(parts.slice(p), foundschema.schema);
- }
- }
-
- foundschema.$fullPath = resultPath.join('.');
-
- return foundschema;
- }
- }
- }
-
- // look for arrays
- return search(path.split('.'), _this);
-};
-
-/*!
- * ignore
- */
-
-Schema.prototype._getPathType = function(path) {
- var _this = this;
- var pathschema = _this.path(path);
-
- if (pathschema) {
- return 'real';
- }
-
- function search(parts, schema) {
- var p = parts.length + 1,
- foundschema,
- trypath;
-
- while (p--) {
- trypath = parts.slice(0, p).join('.');
- foundschema = schema.path(trypath);
- if (foundschema) {
- if (foundschema.caster) {
- // array of Mixed?
- if (foundschema.caster instanceof MongooseTypes.Mixed) {
- return { schema: foundschema, pathType: 'mixed' };
- }
-
- // Now that we found the array, we need to check if there
- // are remaining document paths to look up for casting.
- // Also we need to handle array.$.path since schema.path
- // doesn't work for that.
- // If there is no foundschema.schema we are dealing with
- // a path like array.$
- if (p !== parts.length && foundschema.schema) {
- if (parts[p] === '$') {
- if (p === parts.length - 1) {
- return { schema: foundschema, pathType: 'nested' };
- }
- // comments.$.comments.$.title
- return search(parts.slice(p + 1), foundschema.schema);
- }
- // this is the last path of the selector
- return search(parts.slice(p), foundschema.schema);
- }
- return {
- schema: foundschema,
- pathType: foundschema.$isSingleNested ? 'nested' : 'array'
- };
- }
- return { schema: foundschema, pathType: 'real' };
- } else if (p === parts.length && schema.nested[trypath]) {
- return { schema: schema, pathType: 'nested' };
- }
- }
- return { schema: foundschema || schema, pathType: 'undefined' };
- }
-
- // look for arrays
- return search(path.split('.'), _this);
-};
-
-
-/*!
- * Module exports.
- */
-
-module.exports = exports = Schema;
-
-// require down here because of reference issues
-
-/**
- * The various built-in Mongoose Schema Types.
- *
- * ####Example:
- *
- * var mongoose = require('mongoose');
- * var ObjectId = mongoose.Schema.Types.ObjectId;
- *
- * ####Types:
- *
- * - [String](#schema-string-js)
- * - [Number](#schema-number-js)
- * - [Boolean](#schema-boolean-js) | Bool
- * - [Array](#schema-array-js)
- * - [Buffer](#schema-buffer-js)
- * - [Date](#schema-date-js)
- * - [ObjectId](#schema-objectid-js) | Oid
- * - [Mixed](#schema-mixed-js)
- *
- * Using this exposed access to the `Mixed` SchemaType, we can use them in our schema.
- *
- * var Mixed = mongoose.Schema.Types.Mixed;
- * new mongoose.Schema({ _user: Mixed })
- *
- * @api public
- */
-
-Schema.Types = MongooseTypes = require('./schema/index');
-
-/*!
- * ignore
- */
-
-exports.ObjectId = MongooseTypes.ObjectId;