agendash 2.0.0 → 3.1.0
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/README.md +59 -22
- package/app.js +9 -5
- package/bin/agendash-standalone-fastify.js +61 -0
- package/bin/agendash-standalone-hapi.js +36 -18
- package/bin/agendash-standalone-koa.js +30 -14
- package/bin/agendash-standalone.js +44 -19
- package/lib/controllers/agendash.js +228 -110
- package/lib/csp.js +28 -0
- package/lib/middlewares/README.md +3 -1
- package/lib/middlewares/express.js +43 -17
- package/lib/middlewares/fastify.js +77 -0
- package/lib/middlewares/hapi.js +58 -33
- package/lib/middlewares/koa.js +29 -20
- package/package.json +37 -35
- package/public/app/js/confirmDelete.js +14 -13
- package/public/app/js/confirmDeleteMulti.js +14 -13
- package/public/app/js/confirmRequeue.js +14 -13
- package/public/app/js/confirmRequeueMulti.js +15 -14
- package/public/app/js/confirms.js +4 -4
- package/public/app/js/jobdetail.js +9 -9
- package/public/app/js/joblist.js +50 -43
- package/public/app/js/main.js +109 -72
- package/public/app/js/newJob.js +37 -23
- package/public/app/js/sidebar.js +51 -26
- package/public/app/js/topbar.js +15 -5
- package/.editorconfig +0 -7
- package/.idea/agendash.iml +0 -12
- package/.idea/inspectionProfiles/Project_Default.xml +0 -6
- package/.idea/jsLibraryMappings.xml +0 -6
- package/.idea/misc.xml +0 -92
- package/.idea/modules.xml +0 -8
- package/.idea/vcs.xml +0 -6
- package/.travis.yml +0 -27
- package/.vscode/launch.json +0 -15
- package/History.md +0 -106
- package/renovate.json +0 -5
- package/test/test-express.js +0 -82
- package/test/test-hapi.js +0 -106
- package/test/test-koa.js +0 -85
|
@@ -1,20 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
const semver = require(
|
|
3
|
-
const {
|
|
1
|
+
"use strict";
|
|
2
|
+
const semver = require("semver");
|
|
3
|
+
const { ObjectId } = require("mongodb"); // We rely on the Agenda's "mongodb", thus our package.json lists "*" as required version
|
|
4
4
|
|
|
5
|
-
module.exports = function(agenda, options) {
|
|
5
|
+
module.exports = function (agenda, options) {
|
|
6
6
|
options = options || {};
|
|
7
7
|
|
|
8
|
-
agenda.on(
|
|
8
|
+
agenda.on("ready", () => {
|
|
9
9
|
const collection = agenda._collection.collection || agenda._collection;
|
|
10
|
-
collection.createIndexes(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
collection.createIndexes(
|
|
11
|
+
[
|
|
12
|
+
{ key: { nextRunAt: -1, lastRunAt: -1, lastFinishedAt: -1 } },
|
|
13
|
+
{ key: { name: 1, nextRunAt: -1, lastRunAt: -1, lastFinishedAt: -1 } },
|
|
14
|
+
],
|
|
15
|
+
(error) => {
|
|
16
|
+
if (error) {
|
|
17
|
+
// Ignoring for now
|
|
18
|
+
}
|
|
16
19
|
}
|
|
17
|
-
|
|
20
|
+
);
|
|
18
21
|
|
|
19
22
|
// Mongoose internals changed at some point. This will fix crash for older versions.
|
|
20
23
|
const mdb = agenda._mdb.admin ? agenda._mdb : agenda._mdb.db;
|
|
@@ -24,14 +27,14 @@ module.exports = function(agenda, options) {
|
|
|
24
27
|
throw error;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
if (!semver.satisfies(serverInfo.version,
|
|
28
|
-
throw new Error(
|
|
30
|
+
if (!semver.satisfies(semver.coerce(serverInfo.version), ">=3.6.0")) {
|
|
31
|
+
throw new Error("MongoDB version not supported");
|
|
29
32
|
}
|
|
30
33
|
});
|
|
31
34
|
});
|
|
32
35
|
|
|
33
36
|
// Options = {query = '', property = '', isObjectId = false, limit, skip}
|
|
34
|
-
const getJobs = function(job, state, options) {
|
|
37
|
+
const getJobs = function (job, state, options) {
|
|
35
38
|
const preMatch = {};
|
|
36
39
|
if (job) {
|
|
37
40
|
preMatch.name = job;
|
|
@@ -39,11 +42,11 @@ module.exports = function(agenda, options) {
|
|
|
39
42
|
|
|
40
43
|
if (options.query && options.property) {
|
|
41
44
|
if (options.isObjectId) {
|
|
42
|
-
preMatch[options.property] =
|
|
45
|
+
preMatch[options.property] = ObjectId(options.query);
|
|
43
46
|
} else if (/^\d+$/.test(options.query)) {
|
|
44
47
|
preMatch[options.property] = Number.parseInt(options.query, 10);
|
|
45
48
|
} else {
|
|
46
|
-
preMatch[options.property] = {$regex: options.query, $options:
|
|
49
|
+
preMatch[options.property] = { $regex: options.query, $options: "i" };
|
|
47
50
|
}
|
|
48
51
|
}
|
|
49
52
|
|
|
@@ -53,82 +56,185 @@ module.exports = function(agenda, options) {
|
|
|
53
56
|
}
|
|
54
57
|
|
|
55
58
|
const collection = agenda._collection.collection || agenda._collection;
|
|
56
|
-
return collection
|
|
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
|
-
|
|
59
|
+
return collection
|
|
60
|
+
.aggregate([
|
|
61
|
+
{ $match: preMatch },
|
|
62
|
+
{
|
|
63
|
+
$sort: {
|
|
64
|
+
nextRunAt: -1,
|
|
65
|
+
lastRunAt: -1,
|
|
66
|
+
lastFinishedAt: -1,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
$project: {
|
|
71
|
+
job: "$$ROOT",
|
|
72
|
+
_id: "$$ROOT._id",
|
|
73
|
+
running: {
|
|
74
|
+
$and: ["$lastRunAt", { $gt: ["$lastRunAt", "$lastFinishedAt"] }],
|
|
75
|
+
},
|
|
76
|
+
scheduled: {
|
|
77
|
+
$and: ["$nextRunAt", { $gte: ["$nextRunAt", new Date()] }],
|
|
78
|
+
},
|
|
79
|
+
queued: {
|
|
80
|
+
$and: [
|
|
81
|
+
"$nextRunAt",
|
|
82
|
+
{ $gte: [new Date(), "$nextRunAt"] },
|
|
83
|
+
{ $gte: ["$nextRunAt", "$lastFinishedAt"] },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
completed: {
|
|
87
|
+
$and: [
|
|
88
|
+
"$lastFinishedAt",
|
|
89
|
+
{ $gt: ["$lastFinishedAt", "$failedAt"] },
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
failed: {
|
|
93
|
+
$and: [
|
|
94
|
+
"$lastFinishedAt",
|
|
95
|
+
"$failedAt",
|
|
96
|
+
{ $eq: ["$lastFinishedAt", "$failedAt"] },
|
|
97
|
+
],
|
|
98
|
+
},
|
|
99
|
+
repeating: {
|
|
100
|
+
$and: ["$repeatInterval", { $ne: ["$repeatInterval", null] }],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
{ $match: postMatch },
|
|
105
|
+
{
|
|
106
|
+
$facet: {
|
|
107
|
+
pages: [
|
|
108
|
+
{ $count: "totalMatchs" },
|
|
109
|
+
{
|
|
110
|
+
$project: {
|
|
111
|
+
totalPages: {
|
|
112
|
+
$ceil: { $divide: ["$totalMatchs", options.limit] },
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
filtered: [{ $skip: options.skip }, { $limit: options.limit }],
|
|
118
|
+
},
|
|
119
|
+
},
|
|
120
|
+
])
|
|
121
|
+
.toArray();
|
|
107
122
|
};
|
|
108
123
|
|
|
109
|
-
const getOverview = async() => {
|
|
124
|
+
const getOverview = async () => {
|
|
110
125
|
const collection = agenda._collection.collection || agenda._collection;
|
|
111
|
-
const results = await collection
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
126
|
+
const results = await collection
|
|
127
|
+
.aggregate([
|
|
128
|
+
{
|
|
129
|
+
$group: {
|
|
130
|
+
_id: "$name",
|
|
131
|
+
displayName: { $first: "$name" },
|
|
132
|
+
meta: {
|
|
133
|
+
$addToSet: {
|
|
134
|
+
type: "$type",
|
|
135
|
+
priority: "$priority",
|
|
136
|
+
repeatInterval: "$repeatInterval",
|
|
137
|
+
repeatTimezone: "$repeatTimezone",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
total: { $sum: 1 },
|
|
141
|
+
running: {
|
|
142
|
+
$sum: {
|
|
143
|
+
$cond: [
|
|
144
|
+
{
|
|
145
|
+
$and: [
|
|
146
|
+
"$lastRunAt",
|
|
147
|
+
{ $gt: ["$lastRunAt", "$lastFinishedAt"] },
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
1,
|
|
151
|
+
0,
|
|
152
|
+
],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
scheduled: {
|
|
156
|
+
$sum: {
|
|
157
|
+
$cond: [
|
|
158
|
+
{
|
|
159
|
+
$and: ["$nextRunAt", { $gte: ["$nextRunAt", new Date()] }],
|
|
160
|
+
},
|
|
161
|
+
1,
|
|
162
|
+
0,
|
|
163
|
+
],
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
queued: {
|
|
167
|
+
$sum: {
|
|
168
|
+
$cond: [
|
|
169
|
+
{
|
|
170
|
+
$and: [
|
|
171
|
+
"$nextRunAt",
|
|
172
|
+
{ $gte: [new Date(), "$nextRunAt"] },
|
|
173
|
+
{ $gte: ["$nextRunAt", "$lastFinishedAt"] },
|
|
174
|
+
],
|
|
175
|
+
},
|
|
176
|
+
1,
|
|
177
|
+
0,
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
completed: {
|
|
182
|
+
$sum: {
|
|
183
|
+
$cond: [
|
|
184
|
+
{
|
|
185
|
+
$and: [
|
|
186
|
+
"$lastFinishedAt",
|
|
187
|
+
{ $gt: ["$lastFinishedAt", "$failedAt"] },
|
|
188
|
+
],
|
|
189
|
+
},
|
|
190
|
+
1,
|
|
191
|
+
0,
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
failed: {
|
|
196
|
+
$sum: {
|
|
197
|
+
$cond: [
|
|
198
|
+
{
|
|
199
|
+
$and: [
|
|
200
|
+
"$lastFinishedAt",
|
|
201
|
+
"$failedAt",
|
|
202
|
+
{ $eq: ["$lastFinishedAt", "$failedAt"] },
|
|
203
|
+
],
|
|
204
|
+
},
|
|
205
|
+
1,
|
|
206
|
+
0,
|
|
207
|
+
],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
repeating: {
|
|
211
|
+
$sum: {
|
|
212
|
+
$cond: [
|
|
213
|
+
{
|
|
214
|
+
$and: [
|
|
215
|
+
"$repeatInterval",
|
|
216
|
+
{ $ne: ["$repeatInterval", null] },
|
|
217
|
+
],
|
|
218
|
+
},
|
|
219
|
+
1,
|
|
220
|
+
0,
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
])
|
|
227
|
+
.toArray();
|
|
228
|
+
const states = {
|
|
229
|
+
total: 0,
|
|
230
|
+
running: 0,
|
|
231
|
+
scheduled: 0,
|
|
232
|
+
queued: 0,
|
|
233
|
+
completed: 0,
|
|
234
|
+
failed: 0,
|
|
235
|
+
repeating: 0,
|
|
236
|
+
};
|
|
237
|
+
const totals = { displayName: "All Jobs", ...states };
|
|
132
238
|
|
|
133
239
|
for (const job of results) {
|
|
134
240
|
for (const state of Object.keys(states)) {
|
|
@@ -140,38 +246,49 @@ module.exports = function(agenda, options) {
|
|
|
140
246
|
return results;
|
|
141
247
|
};
|
|
142
248
|
|
|
143
|
-
const api = async function(
|
|
249
|
+
const api = async function (
|
|
250
|
+
job,
|
|
251
|
+
state,
|
|
252
|
+
{ query: q, property, isObjectId, skip, limit }
|
|
253
|
+
) {
|
|
144
254
|
if (!agenda) {
|
|
145
|
-
return Promise.reject(new Error(
|
|
255
|
+
return Promise.reject(new Error("Agenda instance is not ready"));
|
|
146
256
|
}
|
|
147
257
|
|
|
148
258
|
limit = Number.parseInt(limit, 10) || 200;
|
|
149
259
|
skip = Number.parseInt(skip, 10) || 0;
|
|
150
260
|
|
|
151
|
-
const [overview, jobs] = await Promise.all([
|
|
261
|
+
const [overview, jobs] = await Promise.all([
|
|
262
|
+
getOverview(),
|
|
263
|
+
getJobs(job, state, { query: q, property, isObjectId, skip, limit }),
|
|
264
|
+
]);
|
|
152
265
|
const apiResponse = {
|
|
153
266
|
overview,
|
|
154
267
|
jobs: jobs[0].filtered,
|
|
155
|
-
totalPages: jobs[0].pages[0] ? jobs[0].pages[0].totalPages : 0
|
|
268
|
+
totalPages: jobs[0].pages[0] ? jobs[0].pages[0].totalPages : 0,
|
|
156
269
|
};
|
|
157
|
-
apiResponse.title = options.title ||
|
|
270
|
+
apiResponse.title = options.title || "Agendash";
|
|
158
271
|
apiResponse.currentRequest = {
|
|
159
|
-
title: options.title ||
|
|
160
|
-
job: job ||
|
|
161
|
-
state
|
|
272
|
+
title: options.title || "Agendash",
|
|
273
|
+
job: job || "All Jobs",
|
|
274
|
+
state,
|
|
162
275
|
};
|
|
163
276
|
return apiResponse;
|
|
164
277
|
};
|
|
165
278
|
|
|
166
|
-
const requeueJobs = async jobIds => {
|
|
279
|
+
const requeueJobs = async (jobIds) => {
|
|
167
280
|
if (!agenda) {
|
|
168
|
-
return Promise.reject(new Error(
|
|
281
|
+
return Promise.reject(new Error("Agenda instance is not ready"));
|
|
169
282
|
}
|
|
170
283
|
|
|
171
284
|
const collection = agenda._collection.collection || agenda._collection;
|
|
172
|
-
const jobs = await collection
|
|
285
|
+
const jobs = await collection
|
|
286
|
+
.find({
|
|
287
|
+
_id: { $in: jobIds.map((jobId) => ObjectId(jobId)) },
|
|
288
|
+
})
|
|
289
|
+
.toArray();
|
|
173
290
|
if (jobs.length === 0) {
|
|
174
|
-
throw new Error(
|
|
291
|
+
throw new Error("Job not found");
|
|
175
292
|
}
|
|
176
293
|
|
|
177
294
|
for (const job of jobs) {
|
|
@@ -180,21 +297,22 @@ module.exports = function(agenda, options) {
|
|
|
180
297
|
await newJob.save();
|
|
181
298
|
}
|
|
182
299
|
|
|
183
|
-
return
|
|
300
|
+
return "Jobs create successfully";
|
|
184
301
|
};
|
|
185
302
|
|
|
186
|
-
const deleteJobs = jobIds => {
|
|
303
|
+
const deleteJobs = (jobIds) => {
|
|
187
304
|
if (!agenda) {
|
|
188
|
-
return Promise.reject(new Error(
|
|
305
|
+
return Promise.reject(new Error("Agenda instance is not ready"));
|
|
189
306
|
}
|
|
190
307
|
|
|
191
|
-
|
|
192
|
-
|
|
308
|
+
return agenda.cancel({
|
|
309
|
+
_id: { $in: jobIds.map((jobId) => ObjectId(jobId)) },
|
|
310
|
+
});
|
|
193
311
|
};
|
|
194
312
|
|
|
195
313
|
const createJob = (jobName, jobSchedule, jobRepeatEvery, jobData) => {
|
|
196
314
|
if (!agenda) {
|
|
197
|
-
return Promise.reject(new Error(
|
|
315
|
+
return Promise.reject(new Error("Agenda instance is not ready"));
|
|
198
316
|
}
|
|
199
317
|
|
|
200
318
|
// @TODO: Need to validate user input.
|
|
@@ -207,7 +325,7 @@ module.exports = function(agenda, options) {
|
|
|
207
325
|
} else if (jobRepeatEvery) {
|
|
208
326
|
job.repeatEvery(jobRepeatEvery);
|
|
209
327
|
} else {
|
|
210
|
-
return Promise.reject(new Error(
|
|
328
|
+
return Promise.reject(new Error("Jobs not created"));
|
|
211
329
|
}
|
|
212
330
|
|
|
213
331
|
return job.save();
|
|
@@ -217,6 +335,6 @@ module.exports = function(agenda, options) {
|
|
|
217
335
|
api,
|
|
218
336
|
requeueJobs,
|
|
219
337
|
deleteJobs,
|
|
220
|
-
createJob
|
|
338
|
+
createJob,
|
|
221
339
|
};
|
|
222
340
|
};
|
package/lib/csp.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const CSP = {
|
|
2
|
+
"default-src": [
|
|
3
|
+
"'self'",
|
|
4
|
+
],
|
|
5
|
+
"script-src": [
|
|
6
|
+
"https://code.jquery.com",
|
|
7
|
+
"https://cdn.jsdelivr.net",
|
|
8
|
+
"https://cdnjs.cloudflare.com",
|
|
9
|
+
"https://stackpath.bootstrapcdn.com",
|
|
10
|
+
"'unsafe-inline'",
|
|
11
|
+
"'unsafe-eval'",
|
|
12
|
+
"'self'",
|
|
13
|
+
],
|
|
14
|
+
"style-src": [
|
|
15
|
+
"https://cdn.jsdelivr.net",
|
|
16
|
+
"https://stackpath.bootstrapcdn.com",
|
|
17
|
+
"https://fonts.googleapis.com",
|
|
18
|
+
"https://unpkg.com",
|
|
19
|
+
"'self'",
|
|
20
|
+
],
|
|
21
|
+
"font-src": [
|
|
22
|
+
"https://fonts.gstatic.com",
|
|
23
|
+
],
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
module.exports = Object.entries(CSP)
|
|
27
|
+
.map(([type, values]) => `${type} ${values.join(" ")}`)
|
|
28
|
+
.join("; ")
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
Works with [Hapijs](https://hapijs.com/) >= v18
|
|
6
6
|
|
|
7
7
|
### usage
|
|
8
|
+
|
|
8
9
|
First install the dependencies in your app:
|
|
9
10
|
|
|
10
11
|
```bash
|
|
@@ -12,11 +13,12 @@ npm install @hapi/hapi @hapi/inert agenda agendash
|
|
|
12
13
|
```
|
|
13
14
|
|
|
14
15
|
Then use it as follows:
|
|
16
|
+
|
|
15
17
|
```javascript
|
|
16
18
|
'use strict';
|
|
17
19
|
|
|
18
20
|
const Hapi = require('hapi');
|
|
19
|
-
const Agenda = require('agenda');
|
|
21
|
+
const { Agenda } = require('agenda');
|
|
20
22
|
const Agendash = require('agendash');
|
|
21
23
|
|
|
22
24
|
var agenda = new Agenda({
|
|
@@ -1,25 +1,46 @@
|
|
|
1
|
-
const path = require(
|
|
2
|
-
const express = require(
|
|
3
|
-
const bodyParser = require(
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const express = require("express");
|
|
3
|
+
const bodyParser = require("body-parser");
|
|
4
|
+
const csp = require("../csp");
|
|
4
5
|
|
|
5
|
-
module.exports = agendash => {
|
|
6
|
-
const {api, requeueJobs, deleteJobs, createJob} = agendash;
|
|
6
|
+
module.exports = (agendash) => {
|
|
7
|
+
const { api, requeueJobs, deleteJobs, createJob } = agendash;
|
|
7
8
|
const app = express();
|
|
8
9
|
app.use(bodyParser.json());
|
|
9
|
-
app.use(bodyParser.urlencoded({extended: false}));
|
|
10
|
-
app.use('/', express.static(path.join(__dirname, '../../public')));
|
|
10
|
+
app.use(bodyParser.urlencoded({ extended: false }));
|
|
11
11
|
|
|
12
|
-
app.
|
|
12
|
+
app.use((req, res, next) => {
|
|
13
|
+
res.header("Content-Security-Policy", csp);
|
|
14
|
+
next();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
app.use("/", express.static(path.join(__dirname, "../../public")));
|
|
18
|
+
|
|
19
|
+
app.get("/api", async (request, response) => {
|
|
13
20
|
try {
|
|
14
|
-
const {
|
|
15
|
-
|
|
21
|
+
const {
|
|
22
|
+
job,
|
|
23
|
+
state,
|
|
24
|
+
skip,
|
|
25
|
+
limit,
|
|
26
|
+
q,
|
|
27
|
+
property,
|
|
28
|
+
isObjectId,
|
|
29
|
+
} = request.query;
|
|
30
|
+
const apiResponse = await api(job, state, {
|
|
31
|
+
query: q,
|
|
32
|
+
property,
|
|
33
|
+
isObjectId,
|
|
34
|
+
skip,
|
|
35
|
+
limit,
|
|
36
|
+
});
|
|
16
37
|
response.json(apiResponse);
|
|
17
38
|
} catch (error) {
|
|
18
39
|
response.status(400).json(error);
|
|
19
40
|
}
|
|
20
41
|
});
|
|
21
42
|
|
|
22
|
-
app.post(
|
|
43
|
+
app.post("/api/jobs/requeue", async (request, response) => {
|
|
23
44
|
try {
|
|
24
45
|
const newJobs = await requeueJobs(request.body.jobIds);
|
|
25
46
|
response.send(newJobs);
|
|
@@ -28,23 +49,28 @@ module.exports = agendash => {
|
|
|
28
49
|
}
|
|
29
50
|
});
|
|
30
51
|
|
|
31
|
-
app.post(
|
|
52
|
+
app.post("/api/jobs/delete", async (request, response) => {
|
|
32
53
|
try {
|
|
33
54
|
const deleted = await deleteJobs(request.body.jobIds);
|
|
34
55
|
if (deleted) {
|
|
35
|
-
response.json({deleted: true});
|
|
56
|
+
response.json({ deleted: true });
|
|
36
57
|
} else {
|
|
37
|
-
response.json({message:
|
|
58
|
+
response.json({ message: "Jobs not deleted" });
|
|
38
59
|
}
|
|
39
60
|
} catch (error) {
|
|
40
61
|
response.status(404).json(error);
|
|
41
62
|
}
|
|
42
63
|
});
|
|
43
64
|
|
|
44
|
-
app.post(
|
|
65
|
+
app.post("/api/jobs/create", async (request, response) => {
|
|
45
66
|
try {
|
|
46
|
-
await createJob(
|
|
47
|
-
|
|
67
|
+
await createJob(
|
|
68
|
+
request.body.jobName,
|
|
69
|
+
request.body.jobSchedule,
|
|
70
|
+
request.body.jobRepeatEvery,
|
|
71
|
+
request.body.jobData
|
|
72
|
+
);
|
|
73
|
+
response.json({ created: true });
|
|
48
74
|
} catch (error) {
|
|
49
75
|
response.status(400).json(error);
|
|
50
76
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const csp = require("../csp");
|
|
3
|
+
|
|
4
|
+
module.exports = (agendash) => (instance, opts, done) => {
|
|
5
|
+
const { api, requeueJobs, deleteJobs, createJob } = agendash;
|
|
6
|
+
|
|
7
|
+
instance.register(require("fastify-static"), {
|
|
8
|
+
root: path.join(__dirname, "../../public"),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
instance.get("/", function (req, reply) {
|
|
12
|
+
reply.header("Content-Security-Policy", csp);
|
|
13
|
+
return reply.sendFile("index.html");
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
instance.get("/api", async (request, response) => {
|
|
17
|
+
try {
|
|
18
|
+
const {
|
|
19
|
+
job,
|
|
20
|
+
state,
|
|
21
|
+
skip,
|
|
22
|
+
limit,
|
|
23
|
+
q,
|
|
24
|
+
property,
|
|
25
|
+
isObjectId,
|
|
26
|
+
} = request.query;
|
|
27
|
+
const apiResponse = await api(job, state, {
|
|
28
|
+
query: q,
|
|
29
|
+
property,
|
|
30
|
+
isObjectId,
|
|
31
|
+
skip,
|
|
32
|
+
limit,
|
|
33
|
+
});
|
|
34
|
+
response.send(apiResponse);
|
|
35
|
+
} catch (error) {
|
|
36
|
+
response.status(400).send(error);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
instance.post("/api/jobs/requeue", async (request, response) => {
|
|
41
|
+
try {
|
|
42
|
+
const newJobs = await requeueJobs(request.body.jobIds);
|
|
43
|
+
response.send(newJobs);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
response.status(404).send(error);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
instance.post("/api/jobs/delete", async (request, response) => {
|
|
50
|
+
try {
|
|
51
|
+
const deleted = await deleteJobs(request.body.jobIds);
|
|
52
|
+
if (deleted) {
|
|
53
|
+
response.send({ deleted: true });
|
|
54
|
+
} else {
|
|
55
|
+
response.send({ message: "Jobs not deleted" });
|
|
56
|
+
}
|
|
57
|
+
} catch (error) {
|
|
58
|
+
response.status(404).send(error);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
instance.post("/api/jobs/create", async (request, response) => {
|
|
63
|
+
try {
|
|
64
|
+
await createJob(
|
|
65
|
+
request.body.jobName,
|
|
66
|
+
request.body.jobSchedule,
|
|
67
|
+
request.body.jobRepeatEvery,
|
|
68
|
+
request.body.jobData
|
|
69
|
+
);
|
|
70
|
+
response.send({ created: true });
|
|
71
|
+
} catch (error) {
|
|
72
|
+
response.status(400).send(error);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
done();
|
|
77
|
+
};
|