-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtrack.js
More file actions
136 lines (111 loc) · 3.58 KB
/
track.js
File metadata and controls
136 lines (111 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
var _ = require('underscore');
var keystone = require('../../');
var Types = require('../fieldTypes');
/**
* List track option
*
* When enabled, it tracks when a document are created/updated,
* as well as the user who created/updated it.
*/
module.exports = function track() {
var list = this;
var options = list.get('track');
var userModel = keystone.get('user model');
var defaultOptions = {
createdAt: false,
createdBy: false,
updatedAt: false,
updatedBy: false
};
var fields = {};
// ensure track is a boolean or an object
if (!_.isBoolean(options) && !_.isObject(options) ) {
throw new Error('Invalid List "track" option for ' + list.key + '\n' +
'"track" must be a boolean or an object.\n\n' +
'See http://keystonejs.com/docs/database/#lists-options for more information.');
}
if (_.isBoolean(options)) {
// shorthand: { track: true } sets all tracked fields to true
if (options) {
options = {
createdAt: true,
createdBy: true,
updatedAt: true,
updatedBy: true
};
} else {
// otherwise user doesn't want tracking
return;
}
}
// if all track fields are set to false, then user doesn't want to track anything
if (!options.createdAt && !options.createdBy && !options.updatedAt && !options.updatedBy) {
return;
}
// merge user options with default options
options = _.extend({}, defaultOptions, options);
// validate option fields
_.each(options, function(value, key) {
var fieldName;
// make sure the key isn't already defined as a field
if (_.has(list.fields, key)) {
throw new Error('Invalid List "track" option for ' + list.key + '\n' +
'"' + key + '" is already defined in the Schema.');
}
// make sure it's a valid track option field
if (_.has(defaultOptions, key)) {
// make sure the option field value is either a boolean or a string
if (!_.isBoolean(value) && !_.isString(value)) {
throw new Error('Invalid List "track" option for ' + list.key + '\n' +
'"' + key + '" must be a boolean or a string.\n\n' +
'See http://keystonejs.com/docs/database/#lists-options for more information.');
}
if (value) {
// determine
fieldName = value === true ? key : value;
options[key] = fieldName;
list.map(key, fieldName);
switch(key) {
case 'createdAt':
case 'updatedAt':
fields[fieldName] = { type: Date, hidden: true, index: true };
break;
case 'createdBy':
case 'updatedBy':
fields[fieldName] = { type: Types.Relationship, ref: userModel, hidden: true, index: true };
break;
}
}
} else {
throw new Error('Invalid List "track" option for ' + list.key + '\n' +
'valid field options are "createdAt", "createdBy", "updatedAt", an "updatedBy".\n\n' +
'See http://keystonejs.com/docs/database/#lists-options for more information.');
}
});
// add track fields to schema
list.add(fields);
list.tracking = options;
// add the pre-save schema plugin
list.schema.pre('save', function (next) {
var now = new Date();
// set createdAt/createdBy on new docs
if (this.isNew) {
if (options.createdAt && !this.get(options.createdAt)) {
this.set(options.createdAt, now);
}
if (options.createdBy && this._req_user && !this.get(options.createdBy)) {
this.set(options.createdBy, this._req_user._id);
}
}
// set updatedAt/updatedBy when doc is modified
if (this.isNew || this.isModified()) {
if (options.updatedAt) {
this.set(options.updatedAt, now);
}
if (options.updatedBy && this._req_user) {
this.set(options.updatedBy, this._req_user._id);
}
}
next();
});
};