alchemymvc 1.4.0-alpha.1 → 1.4.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -12,26 +12,49 @@ var jsondiffpatch = alchemy.use('jsondiffpatch'),
|
|
|
12
12
|
* @since 0.0.1
|
|
13
13
|
* @version 0.2.0
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
Behaviour.call(this, model, options);
|
|
17
|
-
});
|
|
15
|
+
const Revision = Function.inherits('Alchemy.Behaviour', 'RevisionBehaviour');
|
|
18
16
|
|
|
19
17
|
/**
|
|
20
|
-
* Get the Revision
|
|
18
|
+
* Get the Revision model class for the given main model
|
|
21
19
|
*
|
|
22
20
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
23
|
-
* @since 1.0
|
|
24
|
-
* @version 1.
|
|
21
|
+
* @since 1.4.0
|
|
22
|
+
* @version 1.4.0
|
|
23
|
+
*
|
|
24
|
+
* @param {Schema} schema
|
|
25
|
+
* @param {Object} options
|
|
25
26
|
*/
|
|
26
|
-
Revision.
|
|
27
|
+
Revision.setStatic(function getRevisionModel(model) {
|
|
27
28
|
|
|
28
|
-
|
|
29
|
+
if (typeof model == 'function') {
|
|
30
|
+
model = model.model_name;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (typeof model == 'string') {
|
|
34
|
+
model = Model.get(model);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!model) {
|
|
38
|
+
throw new Error('Unable to add Revision behaviour to undefined model');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let revision_model_name = model.model_name + 'DataRevision',
|
|
42
|
+
revision_model;
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
revision_model = Model.get(revision_model_name, false);
|
|
46
|
+
} catch (err) {
|
|
47
|
+
// Ignore
|
|
48
|
+
}
|
|
29
49
|
|
|
30
|
-
if (
|
|
31
|
-
return
|
|
50
|
+
if (revision_model) {
|
|
51
|
+
return revision_model;
|
|
32
52
|
}
|
|
53
|
+
|
|
54
|
+
let namespace = model.constructor.namespace,
|
|
55
|
+
class_name = model.name + 'DataRevision';
|
|
33
56
|
|
|
34
|
-
let model_class = Function.inherits('Alchemy.Model', Function.create(class_name, function DataRevision(options) {
|
|
57
|
+
let model_class = Function.inherits('Alchemy.Model', namespace, Function.create(class_name, function DataRevision(options) {
|
|
35
58
|
Model.call(this, options);
|
|
36
59
|
}));
|
|
37
60
|
|
|
@@ -48,6 +71,12 @@ Revision.setProperty(function revision_model_class() {
|
|
|
48
71
|
if (Classes.Alchemy.Model.User) {
|
|
49
72
|
this.belongsTo('User');
|
|
50
73
|
}
|
|
74
|
+
|
|
75
|
+
// Add an index on the record_id
|
|
76
|
+
this.addIndex('record_id', {
|
|
77
|
+
unique : false,
|
|
78
|
+
sparse : false,
|
|
79
|
+
});
|
|
51
80
|
});
|
|
52
81
|
|
|
53
82
|
// Force the constitutors to load now
|
|
@@ -56,6 +85,39 @@ Revision.setProperty(function revision_model_class() {
|
|
|
56
85
|
return model_class;
|
|
57
86
|
});
|
|
58
87
|
|
|
88
|
+
/**
|
|
89
|
+
* Listen to attachments to schema's
|
|
90
|
+
*
|
|
91
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
92
|
+
* @since 1.0.3
|
|
93
|
+
* @version 1.4.0
|
|
94
|
+
*
|
|
95
|
+
* @param {Schema} schema
|
|
96
|
+
* @param {Object} options
|
|
97
|
+
*/
|
|
98
|
+
Revision.setStatic(function attached(schema, new_options) {
|
|
99
|
+
|
|
100
|
+
const context = schema.model_class;
|
|
101
|
+
|
|
102
|
+
// Add the revision number to the main model
|
|
103
|
+
context.addField('__r', 'Number', {
|
|
104
|
+
title: 'Revision',
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
Revision.getRevisionModel(schema.model_class);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get the Revision Model class for the attached model
|
|
112
|
+
*
|
|
113
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
114
|
+
* @since 1.0.3
|
|
115
|
+
* @version 1.4.0
|
|
116
|
+
*/
|
|
117
|
+
Revision.setProperty(function revision_model_class() {
|
|
118
|
+
return Revision.getRevisionModel(this.model);
|
|
119
|
+
});
|
|
120
|
+
|
|
59
121
|
/**
|
|
60
122
|
* Get the revision model for the attached model
|
|
61
123
|
*
|
|
@@ -122,24 +184,6 @@ Revision.setProperty(function diff_patcher() {
|
|
|
122
184
|
return diff_patch_instance;
|
|
123
185
|
});
|
|
124
186
|
|
|
125
|
-
/**
|
|
126
|
-
* Listen to attachments to schema's
|
|
127
|
-
*
|
|
128
|
-
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
129
|
-
* @since 1.0.3
|
|
130
|
-
* @version 1.0.3
|
|
131
|
-
*
|
|
132
|
-
* @param {Schema} schema
|
|
133
|
-
* @param {Object} options
|
|
134
|
-
*/
|
|
135
|
-
Revision.setStatic(function attached(schema, new_options) {
|
|
136
|
-
|
|
137
|
-
var context = schema.model_class;
|
|
138
|
-
|
|
139
|
-
// Add the revision
|
|
140
|
-
context.addField('__r', 'Number', {title: 'Revision'});
|
|
141
|
-
});
|
|
142
|
-
|
|
143
187
|
/**
|
|
144
188
|
* Compare 2 objects
|
|
145
189
|
*
|
|
@@ -157,14 +201,14 @@ Revision.setMethod(function compare(left, right) {
|
|
|
157
201
|
*
|
|
158
202
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
159
203
|
* @since 0.0.1
|
|
160
|
-
* @version 1.0
|
|
204
|
+
* @version 1.4.0
|
|
161
205
|
*/
|
|
162
206
|
Revision.setMethod(function beforeSave(record, options, creating) {
|
|
163
207
|
|
|
164
|
-
let main = record
|
|
208
|
+
let main = record.$main;
|
|
165
209
|
|
|
166
210
|
if (!main) {
|
|
167
|
-
throw new Error('Unable to find main "' + this.model.
|
|
211
|
+
throw new Error('Unable to find main "' + this.model.model_name + '" data');
|
|
168
212
|
}
|
|
169
213
|
|
|
170
214
|
// No revision to save when creating a record
|
|
@@ -177,14 +221,12 @@ Revision.setMethod(function beforeSave(record, options, creating) {
|
|
|
177
221
|
next = this.wait('series');
|
|
178
222
|
|
|
179
223
|
// Find the original record
|
|
180
|
-
Model.get(
|
|
181
|
-
|
|
182
|
-
var ori;
|
|
224
|
+
Model.get(this.model.model_name).findById(record.$pk, async function gotRecord(err, result) {
|
|
183
225
|
|
|
184
226
|
if (result) {
|
|
185
227
|
|
|
186
228
|
// Get the original data
|
|
187
|
-
ori = await that.model.convertRecordToDatasourceFormat(result);
|
|
229
|
+
let ori = await that.model.convertRecordToDatasourceFormat(result);
|
|
188
230
|
|
|
189
231
|
// Store the original data in a weakmap for later
|
|
190
232
|
revision_before.set(options, ori);
|
|
@@ -206,17 +248,11 @@ Revision.setMethod(function beforeSave(record, options, creating) {
|
|
|
206
248
|
*
|
|
207
249
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
208
250
|
* @since 0.0.1
|
|
209
|
-
* @version 1.
|
|
251
|
+
* @version 1.4.0
|
|
210
252
|
*/
|
|
211
253
|
Revision.setMethod(function afterSave(record, options, created) {
|
|
212
254
|
|
|
213
|
-
|
|
214
|
-
earlier_data,
|
|
215
|
-
right,
|
|
216
|
-
main,
|
|
217
|
-
that,
|
|
218
|
-
left,
|
|
219
|
-
next;
|
|
255
|
+
let earlier_data;
|
|
220
256
|
|
|
221
257
|
if (created) {
|
|
222
258
|
earlier_data = {};
|
|
@@ -229,11 +265,12 @@ Revision.setMethod(function afterSave(record, options, created) {
|
|
|
229
265
|
return;
|
|
230
266
|
}
|
|
231
267
|
|
|
232
|
-
|
|
233
|
-
|
|
268
|
+
let doc = this.model.createDocument(record);
|
|
269
|
+
let next = this.wait();
|
|
270
|
+
const that = this;
|
|
234
271
|
|
|
235
272
|
// Find the complete saved item
|
|
236
|
-
Model.get(
|
|
273
|
+
Model.get(this.model.model_name).findByPk(doc.$pk, async function gotRecord(err, result) {
|
|
237
274
|
|
|
238
275
|
if (result) {
|
|
239
276
|
|
|
@@ -243,8 +280,8 @@ Revision.setMethod(function afterSave(record, options, created) {
|
|
|
243
280
|
if (new_data) {
|
|
244
281
|
|
|
245
282
|
// Convert the objects so they can be diffed properly
|
|
246
|
-
left = JSON.toDryObject(earlier_data)
|
|
247
|
-
|
|
283
|
+
let left = JSON.toDryObject(earlier_data),
|
|
284
|
+
right = JSON.toDryObject(new_data);
|
|
248
285
|
|
|
249
286
|
// Diff them
|
|
250
287
|
let delta = that.compare(left, right);
|
|
@@ -267,7 +304,7 @@ Revision.setMethod(function afterSave(record, options, created) {
|
|
|
267
304
|
|
|
268
305
|
// Add the delta information
|
|
269
306
|
revision_data = {
|
|
270
|
-
[that.revision_model.
|
|
307
|
+
[that.revision_model.model_name] : revision_data
|
|
271
308
|
};
|
|
272
309
|
|
|
273
310
|
// Save the data
|
|
@@ -659,7 +659,7 @@ Mongo.setMethod(function _remove(model, query, options, callback) {
|
|
|
659
659
|
*
|
|
660
660
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
661
661
|
* @since 0.2.0
|
|
662
|
-
* @version 1.
|
|
662
|
+
* @version 1.4.0
|
|
663
663
|
*/
|
|
664
664
|
Mongo.setMethod(function _ensureIndex(model, index, callback) {
|
|
665
665
|
|
|
@@ -696,11 +696,20 @@ Mongo.setMethod(function _ensureIndex(model, index, callback) {
|
|
|
696
696
|
|
|
697
697
|
// Check for IndexOptionsConflict
|
|
698
698
|
if (err.code === 85) {
|
|
699
|
+
let index_to_drop;
|
|
700
|
+
|
|
701
|
+
if (err.message.includes('already exists with a different name:')) {
|
|
702
|
+
index_to_drop = err.message.after('different name:').trim();
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
if (!index_to_drop) {
|
|
706
|
+
index_to_drop = options.name;
|
|
707
|
+
}
|
|
699
708
|
|
|
700
709
|
try {
|
|
701
710
|
|
|
702
711
|
// Index already exists, drop it
|
|
703
|
-
await collection.dropIndex(
|
|
712
|
+
await collection.dropIndex(index_to_drop);
|
|
704
713
|
|
|
705
714
|
// Try again
|
|
706
715
|
await collection.createIndex(index_specs, options);
|
package/lib/class/model.js
CHANGED
|
@@ -59,11 +59,6 @@ Model.postInherit(function setModelName() {
|
|
|
59
59
|
model_name = ns + '_' + model_name;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
if (model_name[0] == '_') {
|
|
63
|
-
console.log(ns, model_name)
|
|
64
|
-
throw new Error('KAK')
|
|
65
|
-
}
|
|
66
|
-
|
|
67
62
|
// The simple name of the model
|
|
68
63
|
this.model_name = model_name;
|
|
69
64
|
this.setProperty('model_name', model_name);
|
|
@@ -1186,10 +1181,6 @@ Model.setMethod(function auditRecord(document, options, callback) {
|
|
|
1186
1181
|
*/
|
|
1187
1182
|
Model.setMethod(function convertRecordToDatasourceFormat(record, options, callback) {
|
|
1188
1183
|
|
|
1189
|
-
var that = this,
|
|
1190
|
-
pledge,
|
|
1191
|
-
data;
|
|
1192
|
-
|
|
1193
1184
|
if (typeof options == 'function') {
|
|
1194
1185
|
callback = options;
|
|
1195
1186
|
options = {};
|
|
@@ -1199,12 +1190,12 @@ Model.setMethod(function convertRecordToDatasourceFormat(record, options, callba
|
|
|
1199
1190
|
options = {};
|
|
1200
1191
|
}
|
|
1201
1192
|
|
|
1202
|
-
data = record[this.
|
|
1193
|
+
let data = record.$main || record[this.model_name] || record;
|
|
1203
1194
|
|
|
1204
1195
|
// Normalize the data
|
|
1205
1196
|
data = this.compose(data, options);
|
|
1206
1197
|
|
|
1207
|
-
pledge = this.datasource.toDatasource(this, data);
|
|
1198
|
+
let pledge = this.datasource.toDatasource(this, data);
|
|
1208
1199
|
|
|
1209
1200
|
pledge.handleCallback(callback);
|
|
1210
1201
|
|
|
@@ -1041,7 +1041,7 @@ Schema.setMethod(function getFieldNames() {
|
|
|
1041
1041
|
*
|
|
1042
1042
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1043
1043
|
* @since 0.2.0
|
|
1044
|
-
* @version 1.
|
|
1044
|
+
* @version 1.4.0
|
|
1045
1045
|
*
|
|
1046
1046
|
* @param {string|FieldType} _field
|
|
1047
1047
|
* @param {Object} options
|
|
@@ -1073,13 +1073,33 @@ Schema.setMethod(function addIndex(_field, _options) {
|
|
|
1073
1073
|
// Set the default options
|
|
1074
1074
|
options = Object.assign({}, this.indexOptions, options);
|
|
1075
1075
|
|
|
1076
|
-
|
|
1077
|
-
options.name = field.name;
|
|
1076
|
+
const setIndexName = () => {
|
|
1078
1077
|
|
|
1079
|
-
if (options.
|
|
1080
|
-
|
|
1078
|
+
if (options.name) {
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
if (!this.model_name) {
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
if (options.name == null) {
|
|
1087
|
+
options.name = field.path;
|
|
1088
|
+
|
|
1089
|
+
if (options.unique) {
|
|
1090
|
+
options.name += '_uq';
|
|
1091
|
+
}
|
|
1081
1092
|
}
|
|
1082
|
-
|
|
1093
|
+
|
|
1094
|
+
if (this.indexes[options.name] == null) {
|
|
1095
|
+
// Create the index group if it doesn't exist yet.
|
|
1096
|
+
// The first time it's called will define the group options.
|
|
1097
|
+
this.indexes[options.name] = {
|
|
1098
|
+
fields: {},
|
|
1099
|
+
options: options
|
|
1100
|
+
};
|
|
1101
|
+
}
|
|
1102
|
+
};
|
|
1083
1103
|
|
|
1084
1104
|
if (typeof options.order == 'number') {
|
|
1085
1105
|
if (options.order == 'asc') {
|
|
@@ -1089,15 +1109,6 @@ Schema.setMethod(function addIndex(_field, _options) {
|
|
|
1089
1109
|
}
|
|
1090
1110
|
}
|
|
1091
1111
|
|
|
1092
|
-
if (this.indexes[options.name] == null) {
|
|
1093
|
-
// Create the index group if it doesn't exist yet.
|
|
1094
|
-
// The first time it's called will define the group options.
|
|
1095
|
-
this.indexes[options.name] = {
|
|
1096
|
-
fields: {},
|
|
1097
|
-
options: options
|
|
1098
|
-
};
|
|
1099
|
-
}
|
|
1100
|
-
|
|
1101
1112
|
// Even if an index is unique,
|
|
1102
1113
|
// it needs the 'alternate' property in order to be used
|
|
1103
1114
|
// as an alternate method of updating without _id
|
|
@@ -1105,6 +1116,9 @@ Schema.setMethod(function addIndex(_field, _options) {
|
|
|
1105
1116
|
this.has_alternates++;
|
|
1106
1117
|
}
|
|
1107
1118
|
|
|
1119
|
+
// Try to set the index name now, if possible
|
|
1120
|
+
setIndexName();
|
|
1121
|
+
|
|
1108
1122
|
const that = this;
|
|
1109
1123
|
|
|
1110
1124
|
that.getDatasource().done(function gotDs(err, datasource) {
|
|
@@ -1123,6 +1137,9 @@ Schema.setMethod(function addIndex(_field, _options) {
|
|
|
1123
1137
|
return alchemy.printLog('error', ['Unable to ensure index on this datasource', options.name], {err: new Error()});
|
|
1124
1138
|
}
|
|
1125
1139
|
|
|
1140
|
+
// Try to set the index name again, if it hasn't been done yet
|
|
1141
|
+
setIndexName();
|
|
1142
|
+
|
|
1126
1143
|
let path = field.path;
|
|
1127
1144
|
|
|
1128
1145
|
if (options.db_property) {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "alchemymvc",
|
|
3
3
|
"description": "MVC framework for Node.js",
|
|
4
|
-
"version": "1.4.0-alpha.
|
|
4
|
+
"version": "1.4.0-alpha.2",
|
|
5
5
|
"author": "Jelle De Loecker <jelle@elevenways.be>",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"alchemy",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"chokidar" : "~3.5.3",
|
|
23
23
|
"formidable" : "~3.5.1",
|
|
24
24
|
"graceful-fs" : "~4.2.11",
|
|
25
|
-
"hawkejs" : "~2.3.
|
|
25
|
+
"hawkejs" : "~2.3.17",
|
|
26
26
|
"jsondiffpatch" : "~0.5.0",
|
|
27
27
|
"mime" : "~3.0.0",
|
|
28
28
|
"minimist" : "~1.2.5",
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"mongodb" : "~6.1.0",
|
|
32
32
|
"ncp" : "~2.0.0",
|
|
33
33
|
"postcss" : "~8.4.31",
|
|
34
|
-
"protoblast" : "~0.9.
|
|
34
|
+
"protoblast" : "~0.9.1",
|
|
35
35
|
"semver" : "~7.5.4",
|
|
36
36
|
"socket.io" : "~4.7.2",
|
|
37
37
|
"@11ways/socket.io-stream" : "~0.9.2",
|