You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					111 lines
				
				3.5 KiB
			
		
		
			
		
	
	
					111 lines
				
				3.5 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict';
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								const applyTimestampsToChildren = require('../update/applyTimestampsToChildren');
							 | 
						||
| 
								 | 
							
								const applyTimestampsToUpdate = require('../update/applyTimestampsToUpdate');
							 | 
						||
| 
								 | 
							
								const get = require('../get');
							 | 
						||
| 
								 | 
							
								const handleTimestampOption = require('../schema/handleTimestampOption');
							 | 
						||
| 
								 | 
							
								const symbols = require('../../schema/symbols');
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								module.exports = function setupTimestamps(schema, timestamps) {
							 | 
						||
| 
								 | 
							
								  const childHasTimestamp = schema.childSchemas.find(withTimestamp);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function withTimestamp(s) {
							 | 
						||
| 
								 | 
							
								    const ts = s.schema.options.timestamps;
							 | 
						||
| 
								 | 
							
								    return !!ts;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!timestamps && !childHasTimestamp) {
							 | 
						||
| 
								 | 
							
								    return;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const createdAt = handleTimestampOption(timestamps, 'createdAt');
							 | 
						||
| 
								 | 
							
								  const updatedAt = handleTimestampOption(timestamps, 'updatedAt');
							 | 
						||
| 
								 | 
							
								  const currentTime = timestamps != null && timestamps.hasOwnProperty('currentTime') ?
							 | 
						||
| 
								 | 
							
								    timestamps.currentTime :
							 | 
						||
| 
								 | 
							
								    null;
							 | 
						||
| 
								 | 
							
								  const schemaAdditions = {};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  schema.$timestamps = { createdAt: createdAt, updatedAt: updatedAt };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (updatedAt && !schema.paths[updatedAt]) {
							 | 
						||
| 
								 | 
							
								    schemaAdditions[updatedAt] = Date;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (createdAt && !schema.paths[createdAt]) {
							 | 
						||
| 
								 | 
							
								    schemaAdditions[createdAt] = Date;
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  schema.add(schemaAdditions);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  schema.pre('save', function(next) {
							 | 
						||
| 
								 | 
							
								    const timestampOption = get(this, '$__.saveOptions.timestamps');
							 | 
						||
| 
								 | 
							
								    if (timestampOption === false) {
							 | 
						||
| 
								 | 
							
								      return next();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const skipUpdatedAt = timestampOption != null && timestampOption.updatedAt === false;
							 | 
						||
| 
								 | 
							
								    const skipCreatedAt = timestampOption != null && timestampOption.createdAt === false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    const defaultTimestamp = currentTime != null ?
							 | 
						||
| 
								 | 
							
								      currentTime() :
							 | 
						||
| 
								 | 
							
								      (this.ownerDocument ? this.ownerDocument() : this).constructor.base.now();
							 | 
						||
| 
								 | 
							
								    const auto_id = this._id && this._id.auto;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!skipCreatedAt && this.isNew && createdAt && !this.get(createdAt) && this.$__isSelected(createdAt)) {
							 | 
						||
| 
								 | 
							
								      this.$set(createdAt, auto_id ? this._id.getTimestamp() : defaultTimestamp);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if (!skipUpdatedAt && updatedAt && (this.isNew || this.isModified())) {
							 | 
						||
| 
								 | 
							
								      let ts = defaultTimestamp;
							 | 
						||
| 
								 | 
							
								      if (this.isNew) {
							 | 
						||
| 
								 | 
							
								        if (createdAt != null) {
							 | 
						||
| 
								 | 
							
								          ts = this.$__getValue(createdAt);
							 | 
						||
| 
								 | 
							
								        } else if (auto_id) {
							 | 
						||
| 
								 | 
							
								          ts = this._id.getTimestamp();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								      }
							 | 
						||
| 
								 | 
							
								      this.$set(updatedAt, ts);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    next();
							 | 
						||
| 
								 | 
							
								  });
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  schema.methods.initializeTimestamps = function() {
							 | 
						||
| 
								 | 
							
								    const ts = currentTime != null ?
							 | 
						||
| 
								 | 
							
								      currentTime() :
							 | 
						||
| 
								 | 
							
								      this.constructor.base.now();
							 | 
						||
| 
								 | 
							
								    if (createdAt && !this.get(createdAt)) {
							 | 
						||
| 
								 | 
							
								      this.$set(createdAt, ts);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if (updatedAt && !this.get(updatedAt)) {
							 | 
						||
| 
								 | 
							
								      this.$set(updatedAt, ts);
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    return this;
							 | 
						||
| 
								 | 
							
								  };
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  _setTimestampsOnUpdate[symbols.builtInMiddleware] = true;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  const opts = { query: true, model: false };
							 | 
						||
| 
								 | 
							
								  schema.pre('findOneAndReplace', opts, _setTimestampsOnUpdate);
							 | 
						||
| 
								 | 
							
								  schema.pre('findOneAndUpdate', opts, _setTimestampsOnUpdate);
							 | 
						||
| 
								 | 
							
								  schema.pre('replaceOne', opts, _setTimestampsOnUpdate);
							 | 
						||
| 
								 | 
							
								  schema.pre('update', opts, _setTimestampsOnUpdate);
							 | 
						||
| 
								 | 
							
								  schema.pre('updateOne', opts, _setTimestampsOnUpdate);
							 | 
						||
| 
								 | 
							
								  schema.pre('updateMany', opts, _setTimestampsOnUpdate);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  function _setTimestampsOnUpdate(next) {
							 | 
						||
| 
								 | 
							
								    const now = currentTime != null ?
							 | 
						||
| 
								 | 
							
								      currentTime() :
							 | 
						||
| 
								 | 
							
								      this.model.base.now();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    // Replacing with null update should still trigger timestamps
							 | 
						||
| 
								 | 
							
								    if (this.op === 'findOneAndReplace' && this.getUpdate() == null) {
							 | 
						||
| 
								 | 
							
								      this.setUpdate({});
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    applyTimestampsToUpdate(now, createdAt, updatedAt, this.getUpdate(),
							 | 
						||
| 
								 | 
							
								      this.options, this.schema);
							 | 
						||
| 
								 | 
							
								    applyTimestampsToChildren(now, this.getUpdate(), this.model.schema);
							 | 
						||
| 
								 | 
							
								    next();
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								};
							 |