alchemymvc 1.3.16 → 1.3.17
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.
- package/lib/app/datasource/mongo_datasource.js +51 -29
- package/lib/app/element/time_ago.js +19 -36
- package/lib/app/helper/alchemy_helper.js +2 -2
- package/lib/app/helper/cron.js +1502 -0
- package/lib/app/helper_model/document.js +1 -0
- package/lib/app/model/alchemy_task_history_model.js +109 -0
- package/lib/app/model/alchemy_task_model.js +141 -18
- package/lib/bootstrap.js +3 -0
- package/lib/class/conduit.js +36 -12
- package/lib/class/model.js +24 -0
- package/lib/class/schema_client.js +8 -11
- package/lib/class/session.js +14 -3
- package/lib/class/task.js +297 -145
- package/lib/class/task_service.js +933 -0
- package/lib/core/base.js +23 -1
- package/lib/core/middleware.js +2 -2
- package/lib/init/alchemy.js +82 -4
- package/package.json +2 -2
|
@@ -1277,6 +1277,7 @@ Document.setMethod(function hasChanged(name) {
|
|
|
1277
1277
|
|
|
1278
1278
|
for (key in this.$attributes.original_record) {
|
|
1279
1279
|
if (!Object.alike(this.$attributes.original_record[key], this[key])) {
|
|
1280
|
+
// @TODO: some special fields always end up being different
|
|
1280
1281
|
result = true;
|
|
1281
1282
|
break;
|
|
1282
1283
|
}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Alchemy Task History model:
|
|
3
|
+
* keep track of all the tasks that have been run
|
|
4
|
+
*
|
|
5
|
+
* @constructor
|
|
6
|
+
*
|
|
7
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
8
|
+
* @since 0.5.0
|
|
9
|
+
* @version 0.5.0
|
|
10
|
+
*/
|
|
11
|
+
const AlchemyTaskHistory = Function.inherits('Alchemy.Model.App', 'AlchemyTaskHistory');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Constitute the class wide schema
|
|
15
|
+
*
|
|
16
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
17
|
+
* @since 0.5.0
|
|
18
|
+
* @version 1.3.17
|
|
19
|
+
*/
|
|
20
|
+
AlchemyTaskHistory.constitute(function addTaskFields() {
|
|
21
|
+
|
|
22
|
+
this.belongsTo('AlchemyTask', {
|
|
23
|
+
description : 'The original AlchemyTask document it belonged to',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// The timestamp this was scheduled for
|
|
27
|
+
this.addField('scheduled_at', 'Date', {
|
|
28
|
+
description : 'The original date this was scheduled for',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this.addField('process_id', 'Integer', {
|
|
32
|
+
description : 'The process ID of the task',
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
// The type of Task that is running
|
|
36
|
+
this.addField('type', 'Enum', {
|
|
37
|
+
values: Classes.Alchemy.Task.Task.getLiveDescendantsMap(),
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// The payload/settings of the task
|
|
41
|
+
this.addField('settings', 'Schema', {
|
|
42
|
+
description : 'The settings of the task at the time it ran',
|
|
43
|
+
schema: 'type'
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.addField('had_error', 'Boolean', {
|
|
47
|
+
description : 'Did this task run into an error?'
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
this.addField('error_message', 'String', {
|
|
51
|
+
description : 'The main error message'
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
this.addField('error_stack', 'Text', {
|
|
55
|
+
description : 'The error stack trace'
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
this.addField('is_running', 'Boolean', {
|
|
59
|
+
description : 'Is this task still running?',
|
|
60
|
+
default : false,
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
this.addField('started_at', 'Datetime', {
|
|
64
|
+
description : 'The datetime this task actually started running',
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
this.addField('ended_at', 'Datetime', {
|
|
68
|
+
description : 'The datetime this task actually ended',
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
this.addIndex('type');
|
|
72
|
+
this.addIndex('is_running');
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Configure the default chimera fieldsets
|
|
77
|
+
*
|
|
78
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
79
|
+
* @since 1.3.17
|
|
80
|
+
* @version 1.3.17
|
|
81
|
+
*/
|
|
82
|
+
AlchemyTaskHistory.constitute(function chimeraConfig() {
|
|
83
|
+
|
|
84
|
+
if (!this.chimera) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Get the list group
|
|
89
|
+
let list = this.chimera.getActionFields('list');
|
|
90
|
+
|
|
91
|
+
list.addField('created');
|
|
92
|
+
list.addField('type');
|
|
93
|
+
list.addField('process_id');
|
|
94
|
+
list.addField('scheduled_at');
|
|
95
|
+
list.addField('started_at');
|
|
96
|
+
list.addField('ended_at');
|
|
97
|
+
list.addField('had_error');
|
|
98
|
+
|
|
99
|
+
// Get the edit group
|
|
100
|
+
let edit = this.chimera.getActionFields('edit');
|
|
101
|
+
|
|
102
|
+
edit.addField('type');
|
|
103
|
+
edit.addField('settings');
|
|
104
|
+
edit.addField('had_error');
|
|
105
|
+
edit.addField('error_message');
|
|
106
|
+
edit.addField('error_stack');
|
|
107
|
+
edit.addField('started_at');
|
|
108
|
+
edit.addField('ended_at');
|
|
109
|
+
});
|
|
@@ -1,34 +1,157 @@
|
|
|
1
|
-
var all_task_types = alchemy.getClassGroup('task');
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* The Alchemy Task
|
|
2
|
+
* The Alchemy Task model:
|
|
3
|
+
*
|
|
5
4
|
*
|
|
6
5
|
* @constructor
|
|
7
6
|
*
|
|
8
|
-
* @author Jelle De Loecker <jelle@
|
|
9
|
-
* @since
|
|
10
|
-
* @version
|
|
7
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
8
|
+
* @since 1.3.17
|
|
9
|
+
* @version 1.3.17
|
|
10
|
+
*/
|
|
11
|
+
const AlchemyTask = Function.inherits('Alchemy.Model.App', 'AlchemyTask');
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Constitute the class wide schema
|
|
15
|
+
*
|
|
16
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
17
|
+
* @since 1.3.17
|
|
18
|
+
* @version 1.3.17
|
|
11
19
|
*/
|
|
12
|
-
|
|
20
|
+
AlchemyTask.constitute(function addTaskFields() {
|
|
21
|
+
|
|
22
|
+
this.addField('title', 'String', {
|
|
23
|
+
description : 'The title of the task',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
this.addField('type', 'Enum', {
|
|
27
|
+
values : Classes.Alchemy.Task.Task.getLiveDescendantsMap(),
|
|
28
|
+
description : 'The type of task to run',
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this.addField('settings', 'Schema', {
|
|
32
|
+
description : 'The settings to use for running the task',
|
|
33
|
+
schema: 'type'
|
|
34
|
+
});
|
|
13
35
|
|
|
14
|
-
|
|
36
|
+
this.addField('enabled', 'Boolean', {
|
|
37
|
+
description : 'Is this task enabled?',
|
|
38
|
+
default : true,
|
|
39
|
+
});
|
|
15
40
|
|
|
16
|
-
|
|
41
|
+
this.addField('frequency', 'String', {
|
|
42
|
+
description : 'The frequency this task should run at (CRON syntax)',
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
this.addField('comment', 'Text', {
|
|
46
|
+
description : 'A comment about this task',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
this.addField('schedule_type', 'Enum', {
|
|
50
|
+
values: {
|
|
51
|
+
user : 'User',
|
|
52
|
+
system_forced : 'System (forced)',
|
|
53
|
+
system_fallback : 'System (fallback)',
|
|
54
|
+
},
|
|
55
|
+
default: 'user',
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
this.addField('forced_schedule_checksum', 'String', {
|
|
59
|
+
description : 'Checksum of the cron syntax and settings, set only for tasks originating from forced schedules',
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
this.addIndex('forced_schedule_checksum', {
|
|
63
|
+
unique : true,
|
|
64
|
+
sparse : true,
|
|
65
|
+
});
|
|
17
66
|
});
|
|
18
67
|
|
|
19
68
|
/**
|
|
20
|
-
*
|
|
69
|
+
* Configure the default chimera fieldsets
|
|
21
70
|
*
|
|
22
|
-
* @author Jelle De Loecker
|
|
23
|
-
* @since
|
|
24
|
-
* @version
|
|
71
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
72
|
+
* @since 1.3.17
|
|
73
|
+
* @version 1.3.17
|
|
25
74
|
*/
|
|
26
|
-
AlchemyTask.constitute(function
|
|
75
|
+
AlchemyTask.constitute(function chimeraConfig() {
|
|
76
|
+
|
|
77
|
+
if (!this.chimera) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Get the list group
|
|
82
|
+
let list = this.chimera.getActionFields('list');
|
|
83
|
+
|
|
84
|
+
list.addField('title');
|
|
85
|
+
list.addField('type');
|
|
86
|
+
list.addField('enabled');
|
|
87
|
+
list.addField('frequency');
|
|
88
|
+
list.addField('schedule_type');
|
|
89
|
+
|
|
90
|
+
// Get the edit group
|
|
91
|
+
let edit = this.chimera.getActionFields('edit');
|
|
92
|
+
|
|
93
|
+
edit.addField('title');
|
|
94
|
+
edit.addField('frequency')
|
|
95
|
+
edit.addField('enabled');
|
|
96
|
+
edit.addField('type');
|
|
97
|
+
edit.addField('settings');
|
|
98
|
+
edit.addField('comment');
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Do something before saving the record
|
|
103
|
+
*
|
|
104
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
105
|
+
* @since 1.3.17
|
|
106
|
+
* @version 1.3.17
|
|
107
|
+
*
|
|
108
|
+
* @param {Document.AlchemyTask} doc
|
|
109
|
+
*/
|
|
110
|
+
AlchemyTask.setMethod(function beforeSave(doc) {
|
|
111
|
+
|
|
112
|
+
if (!doc.schedule_type) {
|
|
113
|
+
doc.schedule_type = 'user';
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (doc.enabled == null) {
|
|
117
|
+
doc.enabled = false;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!doc.title) {
|
|
121
|
+
let title = '';
|
|
122
|
+
|
|
123
|
+
if (doc.schedule_type == 'system_forced') {
|
|
124
|
+
title += 'System forced: ';
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (doc.schedule_type == 'system_fallback') {
|
|
128
|
+
title += 'System fallback: ';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
title += doc.type;
|
|
132
|
+
doc.title = title;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Update the schedules after saving
|
|
138
|
+
*
|
|
139
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
140
|
+
* @since 1.3.17
|
|
141
|
+
* @version 1.3.17
|
|
142
|
+
*
|
|
143
|
+
* @param {Object} main
|
|
144
|
+
* @param {Object} info
|
|
145
|
+
*/
|
|
146
|
+
AlchemyTask.setMethod(function afterSave(main, info) {
|
|
27
147
|
|
|
28
|
-
|
|
29
|
-
|
|
148
|
+
if (!main.type) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
30
151
|
|
|
31
|
-
|
|
32
|
-
|
|
152
|
+
if (!alchemy.task_service.has_loaded) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
33
155
|
|
|
156
|
+
alchemy.task_service.rescheduleTasksOfType(main.type);
|
|
34
157
|
});
|
package/lib/bootstrap.js
CHANGED
|
@@ -312,6 +312,9 @@ Alchemy.setMethod(function start(options, callback) {
|
|
|
312
312
|
// Make sure Blast has executed everything that's still waiting
|
|
313
313
|
Blast.doLoaded();
|
|
314
314
|
|
|
315
|
+
// Call the `afterStart` method
|
|
316
|
+
this.ready(() => this.afterStart());
|
|
317
|
+
|
|
315
318
|
// Schedule the callback
|
|
316
319
|
return this.ready(callback);
|
|
317
320
|
});
|
package/lib/class/conduit.js
CHANGED
|
@@ -490,9 +490,9 @@ Conduit.setMethod(function time() {
|
|
|
490
490
|
/**
|
|
491
491
|
* Parse the request, get information from the url
|
|
492
492
|
*
|
|
493
|
-
* @author Jelle De Loecker <jelle@
|
|
493
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
494
494
|
* @since 0.2.0
|
|
495
|
-
* @version 1.
|
|
495
|
+
* @version 1.3.17
|
|
496
496
|
*
|
|
497
497
|
* @param {IncomingMessage} req
|
|
498
498
|
* @param {ServerResponse} res
|
|
@@ -555,6 +555,11 @@ Conduit.setMethod(async function parseRequest() {
|
|
|
555
555
|
// Set the host
|
|
556
556
|
this.url.hostname = this.headers.host;
|
|
557
557
|
|
|
558
|
+
// If no URL was set, use the first requests URL (without the path)
|
|
559
|
+
if (!alchemy.settings.url && this.headers.host) {
|
|
560
|
+
alchemy.settings.url = this.url+'';
|
|
561
|
+
}
|
|
562
|
+
|
|
558
563
|
let path = this.path;
|
|
559
564
|
|
|
560
565
|
if (this.prefix) {
|
|
@@ -569,9 +574,9 @@ Conduit.setMethod(async function parseRequest() {
|
|
|
569
574
|
/**
|
|
570
575
|
* Parse the headers for shortcuts
|
|
571
576
|
*
|
|
572
|
-
* @author Jelle De Loecker <jelle@
|
|
577
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
573
578
|
* @since 0.2.0
|
|
574
|
-
* @version
|
|
579
|
+
* @version 1.3.17
|
|
575
580
|
*/
|
|
576
581
|
Conduit.setMethod(function parseShortcuts() {
|
|
577
582
|
|
|
@@ -597,6 +602,10 @@ Conduit.setMethod(function parseShortcuts() {
|
|
|
597
602
|
this.ajax = headers['x-requested-with'] === 'XMLHttpRequest';
|
|
598
603
|
}
|
|
599
604
|
|
|
605
|
+
// Is this request coming from a webview?
|
|
606
|
+
if (this.in_webview == null) {
|
|
607
|
+
this.in_webview = headers['x-protoblast-webview'] === 'true';
|
|
608
|
+
}
|
|
600
609
|
});
|
|
601
610
|
|
|
602
611
|
/**
|
|
@@ -1161,6 +1170,8 @@ Conduit.setMethod(async function callMiddleware() {
|
|
|
1161
1170
|
middleDebug.mark('Preparing viewrender');
|
|
1162
1171
|
}
|
|
1163
1172
|
|
|
1173
|
+
// An action will be called,
|
|
1174
|
+
// so we can already prepare the viewrender now.
|
|
1164
1175
|
that.prepareViewRender();
|
|
1165
1176
|
|
|
1166
1177
|
if (middleDebug) {
|
|
@@ -1184,10 +1195,14 @@ Conduit.setMethod(async function callMiddleware() {
|
|
|
1184
1195
|
*
|
|
1185
1196
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1186
1197
|
* @since 0.2.0
|
|
1187
|
-
* @version 1.
|
|
1198
|
+
* @version 1.3.17
|
|
1188
1199
|
*/
|
|
1189
1200
|
Conduit.setMethod(function prepareViewRender() {
|
|
1190
1201
|
|
|
1202
|
+
if (this.renderer.conduit) {
|
|
1203
|
+
return;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1191
1206
|
// Add a link to this conduit
|
|
1192
1207
|
this.renderer.conduit = this;
|
|
1193
1208
|
this.renderer.server_var('conduit', this);
|
|
@@ -1410,7 +1425,7 @@ Conduit.setMethod(function setResponseUrl(new_url) {
|
|
|
1410
1425
|
*
|
|
1411
1426
|
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1412
1427
|
* @since 0.2.0
|
|
1413
|
-
* @version 1.3.
|
|
1428
|
+
* @version 1.3.17
|
|
1414
1429
|
*
|
|
1415
1430
|
* @param {Number} status 3xx redirection codes. 302 (temporary redirect) by default
|
|
1416
1431
|
* @param {String|Object} options Options or url
|
|
@@ -1508,13 +1523,18 @@ Conduit.setMethod(function redirect(status, options) {
|
|
|
1508
1523
|
}
|
|
1509
1524
|
}
|
|
1510
1525
|
|
|
1511
|
-
if (
|
|
1512
|
-
this.setHeader('x-hawkejs-
|
|
1526
|
+
if (options?.popup) {
|
|
1527
|
+
this.setHeader('x-hawkejs-popup', options.popup);
|
|
1513
1528
|
|
|
1514
|
-
if (options
|
|
1515
|
-
this.setHeader('x-hawkejs-popup', options.
|
|
1529
|
+
if (options.popup_url) {
|
|
1530
|
+
this.setHeader('x-hawkejs-popup-url', options.popup_url);
|
|
1516
1531
|
}
|
|
1517
1532
|
|
|
1533
|
+
hard_refresh = true;
|
|
1534
|
+
}
|
|
1535
|
+
|
|
1536
|
+
if (hard_refresh && this.headers['x-hawkejs-request']) {
|
|
1537
|
+
this.setHeader('x-hawkejs-navigate', url);
|
|
1518
1538
|
} else {
|
|
1519
1539
|
this.setHeader('Location', url);
|
|
1520
1540
|
}
|
|
@@ -1921,11 +1941,11 @@ Conduit.setMethod(function createScene() {
|
|
|
1921
1941
|
*
|
|
1922
1942
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
1923
1943
|
* @since 0.2.0
|
|
1924
|
-
* @version 1.
|
|
1944
|
+
* @version 1.3.17
|
|
1925
1945
|
*/
|
|
1926
1946
|
Conduit.setMethod(function render(template_name, options, callback) {
|
|
1927
1947
|
|
|
1928
|
-
|
|
1948
|
+
let that = this,
|
|
1929
1949
|
templates;
|
|
1930
1950
|
|
|
1931
1951
|
if (typeof options == 'function') {
|
|
@@ -1935,6 +1955,10 @@ Conduit.setMethod(function render(template_name, options, callback) {
|
|
|
1935
1955
|
options = {};
|
|
1936
1956
|
}
|
|
1937
1957
|
|
|
1958
|
+
// Make sure the viewrender is prepared
|
|
1959
|
+
// (Fallback)
|
|
1960
|
+
this.prepareViewRender();
|
|
1961
|
+
|
|
1938
1962
|
if (template_name) {
|
|
1939
1963
|
templates = [template_name];
|
|
1940
1964
|
}
|
package/lib/class/model.js
CHANGED
|
@@ -1246,6 +1246,30 @@ Model.setMethod(function nukeCache(associated, parent) {
|
|
|
1246
1246
|
}
|
|
1247
1247
|
});
|
|
1248
1248
|
|
|
1249
|
+
/**
|
|
1250
|
+
* Perform a MongoDB pipeline
|
|
1251
|
+
*
|
|
1252
|
+
* @author Jelle De Loecker <jelle@elevenways.be>
|
|
1253
|
+
* @since 1.3.17
|
|
1254
|
+
* @version 1.3.17
|
|
1255
|
+
*
|
|
1256
|
+
* @param {Array} pipeline
|
|
1257
|
+
*
|
|
1258
|
+
* @return {Promise}
|
|
1259
|
+
*/
|
|
1260
|
+
Model.setMethod(async function executeMongoPipeline(pipeline) {
|
|
1261
|
+
|
|
1262
|
+
if (typeof this.datasource.collection != 'function') {
|
|
1263
|
+
throw new Error('The `' + this.model_name + '` model does not seem to use MongoDB, unable to perform pipeline');
|
|
1264
|
+
}
|
|
1265
|
+
|
|
1266
|
+
let collection = await this.datasource.collection(this.table);
|
|
1267
|
+
let cursor = await collection.aggregate(pipeline);
|
|
1268
|
+
let result = await cursor.toArray();
|
|
1269
|
+
|
|
1270
|
+
return result;
|
|
1271
|
+
});
|
|
1272
|
+
|
|
1249
1273
|
/**
|
|
1250
1274
|
* Delete the given record id
|
|
1251
1275
|
*
|
|
@@ -892,7 +892,7 @@ Schema.setMethod(function getFieldNames() {
|
|
|
892
892
|
*
|
|
893
893
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
894
894
|
* @since 0.2.0
|
|
895
|
-
* @version 1.3.
|
|
895
|
+
* @version 1.3.17
|
|
896
896
|
*
|
|
897
897
|
* @param {String|FieldType} _field
|
|
898
898
|
* @param {Object} options
|
|
@@ -901,24 +901,19 @@ Schema.setMethod(function getFieldNames() {
|
|
|
901
901
|
*/
|
|
902
902
|
Schema.setMethod(function addIndex(_field, _options) {
|
|
903
903
|
|
|
904
|
-
var that = this,
|
|
905
|
-
datasource,
|
|
906
|
-
options,
|
|
907
|
-
order,
|
|
908
|
-
field,
|
|
909
|
-
path;
|
|
910
|
-
|
|
911
904
|
// `Schema` is the `Client.Schema` class in this scope
|
|
912
905
|
if (Blast.isNode && this.constructor == Schema) {
|
|
913
906
|
return;
|
|
914
907
|
}
|
|
915
908
|
|
|
916
|
-
field = this.getField(_field);
|
|
909
|
+
let field = this.getField(_field);
|
|
917
910
|
|
|
918
911
|
if (!field) {
|
|
919
912
|
throw new Error('Could not find field "' + _field + '"');
|
|
920
913
|
}
|
|
921
914
|
|
|
915
|
+
let options;
|
|
916
|
+
|
|
922
917
|
if (typeof _options === 'string') {
|
|
923
918
|
options = {};
|
|
924
919
|
options[_options] = true;
|
|
@@ -961,6 +956,8 @@ Schema.setMethod(function addIndex(_field, _options) {
|
|
|
961
956
|
this.has_alternates++;
|
|
962
957
|
}
|
|
963
958
|
|
|
959
|
+
const that = this;
|
|
960
|
+
|
|
964
961
|
that.getDatasource().done(function gotDs(err, datasource) {
|
|
965
962
|
|
|
966
963
|
if (err) {
|
|
@@ -977,7 +974,7 @@ Schema.setMethod(function addIndex(_field, _options) {
|
|
|
977
974
|
return alchemy.printLog('error', ['Unable to ensure index on this datasource', options.name], {err: new Error()});
|
|
978
975
|
}
|
|
979
976
|
|
|
980
|
-
path = field.path;
|
|
977
|
+
let path = field.path;
|
|
981
978
|
|
|
982
979
|
if (options.db_property) {
|
|
983
980
|
path += '.' + options.db_property;
|
|
@@ -990,7 +987,7 @@ Schema.setMethod(function addIndex(_field, _options) {
|
|
|
990
987
|
datasource.ensureIndex(that.model_class, that.indexes[options.name], function ensuredIndex(err, result) {
|
|
991
988
|
|
|
992
989
|
if (err) {
|
|
993
|
-
alchemy.printLog('error', ['Error ensuring index', options.name], {err: err});
|
|
990
|
+
alchemy.printLog('error', ['Error ensuring index', options.name, 'in model', that.model_name], {err: err});
|
|
994
991
|
}
|
|
995
992
|
});
|
|
996
993
|
});
|
package/lib/class/session.js
CHANGED
|
@@ -63,7 +63,7 @@ var Session = Function.inherits('Alchemy.Base', function ClientSession(conduit)
|
|
|
63
63
|
*
|
|
64
64
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
65
65
|
* @since 1.1.0
|
|
66
|
-
* @version 1.
|
|
66
|
+
* @version 1.3.17
|
|
67
67
|
*
|
|
68
68
|
* @type {Number}
|
|
69
69
|
*/
|
|
@@ -75,6 +75,10 @@ Session.enforceProperty(function request_count(amount) {
|
|
|
75
75
|
|
|
76
76
|
this.last_activity_date = new Date();
|
|
77
77
|
|
|
78
|
+
if (this.menu_item) {
|
|
79
|
+
this.menu_item.setWeight(this.last_activity_date.getTime());
|
|
80
|
+
}
|
|
81
|
+
|
|
78
82
|
return amount;
|
|
79
83
|
});
|
|
80
84
|
|
|
@@ -167,7 +171,7 @@ Session.setMethod(function hasAlreadyQueued() {
|
|
|
167
171
|
*
|
|
168
172
|
* @author Jelle De Loecker <jelle@develry.be>
|
|
169
173
|
* @since 0.2.0
|
|
170
|
-
* @version
|
|
174
|
+
* @version 1.3.17
|
|
171
175
|
*
|
|
172
176
|
* @param {Conduit} conduit The conduit to postpone
|
|
173
177
|
*
|
|
@@ -187,7 +191,14 @@ Session.setMethod(function createMenuItem(conduit) {
|
|
|
187
191
|
|
|
188
192
|
browser += ': ' + conduit.ip;
|
|
189
193
|
|
|
190
|
-
|
|
194
|
+
let options = {
|
|
195
|
+
title : browser,
|
|
196
|
+
weight : this.last_activity_date.getTime(),
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
this.menu_item = alchemy.Janeway.session_menu.addItem(options, () => {
|
|
200
|
+
console.log('Clicked on session', this, this.id);
|
|
201
|
+
});
|
|
191
202
|
});
|
|
192
203
|
|
|
193
204
|
/**
|