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(); | ||
|  |   } | ||
|  | }; |