123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105 |
- '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]) {
- const baseImmutableCreatedAt = schema.base.get('timestamps.createdAt.immutable');
- const immutable = baseImmutableCreatedAt != null ? baseImmutableCreatedAt : true;
- schemaAdditions[createdAt] = { [schema.options.typeKey || 'type']: Date, immutable };
- }
- 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().constructor.base.now();
- if (!skipCreatedAt && (this.isNew || this.$isSubdocument) && createdAt && !this.$__getValue(createdAt) && this.$__isSelected(createdAt)) {
- this.$set(createdAt, defaultTimestamp, undefined, { overwriteImmutable: true });
- }
- if (!skipUpdatedAt && updatedAt && (this.isNew || this.$isModified())) {
- let ts = defaultTimestamp;
- if (this.isNew && createdAt != null) {
- ts = this.$__getValue(createdAt);
- }
- 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();
- }
- };
|