@terreno/jobs 57.4.0 → 57.6.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.
@@ -1,103 +1,18 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- var __rest = (this && this.__rest) || function (s, e) {
50
- var t = {};
51
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
52
- t[p] = s[p];
53
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
54
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
55
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
56
- t[p[i]] = s[p[i]];
57
- }
58
- return t;
59
- };
60
- var __values = (this && this.__values) || function(o) {
61
- var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
62
- if (m) return m.call(o);
63
- if (o && typeof o.length === "number") return {
64
- next: function () {
65
- if (o && i >= o.length) o = void 0;
66
- return { value: o && o[i++], done: !o };
67
- }
68
- };
69
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
70
- };
71
- var __read = (this && this.__read) || function (o, n) {
72
- var m = typeof Symbol === "function" && o[Symbol.iterator];
73
- if (!m) return o;
74
- var i = m.call(o), r, ar = [], e;
75
- try {
76
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
77
- }
78
- catch (error) { e = { error: error }; }
79
- finally {
80
- try {
81
- if (r && !r.done && (m = i["return"])) m.call(i);
82
- }
83
- finally { if (e) throw e.error; }
84
- }
85
- return ar;
86
- };
87
2
  var __importDefault = (this && this.__importDefault) || function (mod) {
88
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
89
4
  };
90
5
  Object.defineProperty(exports, "__esModule", { value: true });
91
6
  exports.registerJobsAdminRoutes = void 0;
92
- var api_1 = require("@terreno/api");
93
- var luxon_1 = require("luxon");
94
- var mongoose_1 = __importDefault(require("mongoose"));
95
- var job_1 = require("../models/job");
96
- var jobSchedule_1 = require("../models/jobSchedule");
97
- var DEFAULT_LIMIT = 50;
98
- var MAX_LIMIT = 200;
99
- var MAX_Q_LENGTH = 200;
100
- var VALID_JOB_STATUSES = new Set([
7
+ const api_1 = require("@terreno/api");
8
+ const luxon_1 = require("luxon");
9
+ const mongoose_1 = __importDefault(require("mongoose"));
10
+ const job_1 = require("../models/job");
11
+ const jobSchedule_1 = require("../models/jobSchedule");
12
+ const DEFAULT_LIMIT = 50;
13
+ const MAX_LIMIT = 200;
14
+ const MAX_Q_LENGTH = 200;
15
+ const VALID_JOB_STATUSES = new Set([
101
16
  "cancelled",
102
17
  "completed",
103
18
  "dead",
@@ -106,14 +21,14 @@ var VALID_JOB_STATUSES = new Set([
106
21
  "running",
107
22
  "scheduled",
108
23
  ]);
109
- var JOB_ADMIN_ITEM_SCHEMA = {
24
+ const JOB_ADMIN_ITEM_SCHEMA = {
110
25
  _id: { type: "string" },
111
26
  attemptCount: { type: "number" },
112
27
  id: { type: "string" },
113
28
  name: { type: "string" },
114
29
  status: { type: "string" },
115
30
  };
116
- var SCHEDULE_ADMIN_ITEM_SCHEMA = {
31
+ const SCHEDULE_ADMIN_ITEM_SCHEMA = {
117
32
  cron: { type: "string" },
118
33
  enabled: { type: "boolean" },
119
34
  handlerName: { type: "string" },
@@ -122,21 +37,21 @@ var SCHEDULE_ADMIN_ITEM_SCHEMA = {
122
37
  nextRunAt: { format: "date-time", type: "string" },
123
38
  timezone: { type: "string" },
124
39
  };
125
- var pathParam = function (value) {
40
+ const pathParam = (value) => {
126
41
  if (Array.isArray(value)) {
127
42
  return value[0];
128
43
  }
129
44
  return value;
130
45
  };
131
- var readString = function (value) {
46
+ const readString = (value) => {
132
47
  if (typeof value !== "string") {
133
48
  return undefined;
134
49
  }
135
- var trimmed = value.trim();
50
+ const trimmed = value.trim();
136
51
  return trimmed.length > 0 ? trimmed : undefined;
137
52
  };
138
- var readPositiveInt = function (value, fallback, max) {
139
- var parsed = typeof value === "number"
53
+ const readPositiveInt = (value, fallback, max) => {
54
+ const parsed = typeof value === "number"
140
55
  ? value
141
56
  : typeof value === "string" && value.trim().length > 0
142
57
  ? Number(value)
@@ -146,20 +61,20 @@ var readPositiveInt = function (value, fallback, max) {
146
61
  }
147
62
  return Math.min(Math.floor(parsed), max);
148
63
  };
149
- var escapeRegexLiteral = function (value) { return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); };
150
- var parseIsoDate = function (value, label) {
151
- var raw = readString(value);
64
+ const escapeRegexLiteral = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
65
+ const parseIsoDate = (value, label) => {
66
+ const raw = readString(value);
152
67
  if (!raw) {
153
68
  return undefined;
154
69
  }
155
- var parsed = luxon_1.DateTime.fromISO(raw, { zone: "utc" });
70
+ const parsed = luxon_1.DateTime.fromISO(raw, { zone: "utc" });
156
71
  if (!parsed.isValid) {
157
- throw new api_1.APIError({ status: 400, title: "Invalid ".concat(label) });
72
+ throw new api_1.APIError({ status: 400, title: `Invalid ${label}` });
158
73
  }
159
74
  return parsed.toJSDate();
160
75
  };
161
- var parseSearchQuery = function (value) {
162
- var raw = readString(value);
76
+ const parseSearchQuery = (value) => {
77
+ const raw = readString(value);
163
78
  if (!raw) {
164
79
  return undefined;
165
80
  }
@@ -168,8 +83,8 @@ var parseSearchQuery = function (value) {
168
83
  }
169
84
  return escapeRegexLiteral(raw);
170
85
  };
171
- var parseStatusFilter = function (value) {
172
- var status = readString(value);
86
+ const parseStatusFilter = (value) => {
87
+ const status = readString(value);
173
88
  if (!status) {
174
89
  return undefined;
175
90
  }
@@ -178,15 +93,15 @@ var parseStatusFilter = function (value) {
178
93
  }
179
94
  return status;
180
95
  };
181
- var parseListFilters = function (query) { return ({
96
+ const parseListFilters = (query) => ({
182
97
  end: parseIsoDate(query.end, "end date"),
183
98
  name: readString(query.name),
184
99
  q: parseSearchQuery(query.q),
185
100
  scheduleId: readString(query.scheduleId),
186
101
  start: parseIsoDate(query.start, "start date"),
187
102
  status: parseStatusFilter(query.status),
188
- }); };
189
- var EMPTY_STATUS_COUNTS = {
103
+ });
104
+ const EMPTY_STATUS_COUNTS = {
190
105
  cancelled: 0,
191
106
  completed: 0,
192
107
  dead: 0,
@@ -195,31 +110,20 @@ var EMPTY_STATUS_COUNTS = {
195
110
  running: 0,
196
111
  scheduled: 0,
197
112
  };
198
- var buildStatusCounts = function (grouped) {
199
- var e_1, _a;
200
- var byStatus = __assign({}, EMPTY_STATUS_COUNTS);
201
- var total = 0;
202
- try {
203
- for (var grouped_1 = __values(grouped), grouped_1_1 = grouped_1.next(); !grouped_1_1.done; grouped_1_1 = grouped_1.next()) {
204
- var row = grouped_1_1.value;
205
- if (!VALID_JOB_STATUSES.has(row._id)) {
206
- continue;
207
- }
208
- byStatus[row._id] = row.count;
209
- total += row.count;
210
- }
211
- }
212
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
213
- finally {
214
- try {
215
- if (grouped_1_1 && !grouped_1_1.done && (_a = grouped_1.return)) _a.call(grouped_1);
113
+ const buildStatusCounts = (grouped) => {
114
+ const byStatus = { ...EMPTY_STATUS_COUNTS };
115
+ let total = 0;
116
+ for (const row of grouped) {
117
+ if (!VALID_JOB_STATUSES.has(row._id)) {
118
+ continue;
216
119
  }
217
- finally { if (e_1) throw e_1.error; }
120
+ byStatus[row._id] = row.count;
121
+ total += row.count;
218
122
  }
219
- return { byStatus: byStatus, total: total };
123
+ return { byStatus, total };
220
124
  };
221
- var buildListMatch = function (filters) {
222
- var match = {};
125
+ const buildListMatch = (filters) => {
126
+ const match = {};
223
127
  if (filters.name) {
224
128
  match.name = filters.name;
225
129
  }
@@ -233,7 +137,7 @@ var buildListMatch = function (filters) {
233
137
  match.scheduleId = new mongoose_1.default.Types.ObjectId(filters.scheduleId);
234
138
  }
235
139
  if (filters.start || filters.end) {
236
- var created = {};
140
+ const created = {};
237
141
  if (filters.start) {
238
142
  created.$gte = filters.start;
239
143
  }
@@ -250,7 +154,7 @@ var buildListMatch = function (filters) {
250
154
  }
251
155
  return match;
252
156
  };
253
- var projectAdminPayload = function (job, redactPayload) {
157
+ const projectAdminPayload = (job, redactPayload) => {
254
158
  if (job.payloadRedacted) {
255
159
  return undefined;
256
160
  }
@@ -263,70 +167,66 @@ var projectAdminPayload = function (job, redactPayload) {
263
167
  payloadRedacted: job.payloadRedacted,
264
168
  });
265
169
  };
266
- var serializeJob = function (job, redactPayload) {
267
- var json = job.toJSON();
268
- var _storedPayload = json.payload, rest = __rest(json, ["payload"]);
269
- var projectedPayload = projectAdminPayload(job, redactPayload);
170
+ const serializeJob = (job, redactPayload) => {
171
+ const json = job.toJSON();
172
+ const { payload: _storedPayload, ...rest } = json;
173
+ const projectedPayload = projectAdminPayload(job, redactPayload);
270
174
  if (projectedPayload === undefined) {
271
- return __assign(__assign({}, rest), { id: job._id.toString() });
175
+ return {
176
+ ...rest,
177
+ id: job._id.toString(),
178
+ };
272
179
  }
273
- return __assign(__assign({}, rest), { id: job._id.toString(), payload: projectedPayload });
180
+ return {
181
+ ...rest,
182
+ id: job._id.toString(),
183
+ payload: projectedPayload,
184
+ };
274
185
  };
275
- var serializeSchedule = function (schedule) {
276
- var json = schedule.toJSON();
277
- return __assign(__assign({}, json), { id: schedule._id.toString() });
186
+ const serializeSchedule = (schedule) => {
187
+ const json = schedule.toJSON();
188
+ return {
189
+ ...json,
190
+ id: schedule._id.toString(),
191
+ };
278
192
  };
279
- var createRequireJobsAdmin = function (accessControl) {
280
- return function (req) { return __awaiter(void 0, void 0, void 0, function () {
281
- var user, result;
282
- return __generator(this, function (_a) {
283
- switch (_a.label) {
284
- case 0:
285
- user = req.user;
286
- if (!user) {
287
- throw new api_1.UnauthorizedError("Authentication required");
288
- }
289
- if (!accessControl) return [3 /*break*/, 2];
290
- return [4 /*yield*/, accessControl.can({
291
- permissions: { admin: [api_1.ADMIN_PAGE_ACTION, "jobs"] },
292
- user: user,
293
- })];
294
- case 1:
295
- result = _a.sent();
296
- if (!result.allowed) {
297
- throw new api_1.ForbiddenError({
298
- detail: result.reason,
299
- title: "Jobs admin access required",
300
- });
301
- }
302
- return [2 /*return*/];
303
- case 2:
304
- if (!user.admin) {
305
- throw new api_1.ForbiddenError("Admin access required");
306
- }
307
- return [2 /*return*/];
308
- }
193
+ const createRequireJobsAdmin = (accessControl) => async (req) => {
194
+ const user = req.user;
195
+ if (!user) {
196
+ throw new api_1.UnauthorizedError("Authentication required");
197
+ }
198
+ if (accessControl) {
199
+ const result = await accessControl.can({
200
+ permissions: { admin: [api_1.ADMIN_PAGE_ACTION, "jobs"] },
201
+ user: user,
309
202
  });
310
- }); };
311
- };
312
- var listQueryParameters = function (builder) {
313
- return builder
314
- .withQueryParameter("page", { type: "number" }, { required: false })
315
- .withQueryParameter("limit", { type: "number" }, { required: false })
316
- .withQueryParameter("name", { type: "string" }, { required: false })
317
- .withQueryParameter("status", { type: "string" }, { required: false })
318
- .withQueryParameter("scheduleId", { type: "string" }, { required: false })
319
- .withQueryParameter("start", { type: "string" }, { required: false })
320
- .withQueryParameter("end", { type: "string" }, { required: false })
321
- .withQueryParameter("q", { type: "string" }, { required: false });
203
+ if (!result.allowed) {
204
+ throw new api_1.ForbiddenError({
205
+ detail: result.reason,
206
+ title: "Jobs admin access required",
207
+ });
208
+ }
209
+ return;
210
+ }
211
+ if (!user.admin) {
212
+ throw new api_1.ForbiddenError("Admin access required");
213
+ }
322
214
  };
323
- var registerJobsAdminRoutes = function (_a) {
324
- var app = _a.app, options = _a.options;
325
- var routeOpenApi = options.openApi ? { openApi: options.openApi } : {};
326
- var requireJobsAdmin = createRequireJobsAdmin(options.accessControl);
327
- var basePath = options.basePath;
328
- var jobsService = options.jobsService, redactPayload = options.redactPayload;
329
- app.get("".concat(basePath, "/schedules"), [
215
+ const listQueryParameters = (builder) => builder
216
+ .withQueryParameter("page", { type: "number" }, { required: false })
217
+ .withQueryParameter("limit", { type: "number" }, { required: false })
218
+ .withQueryParameter("name", { type: "string" }, { required: false })
219
+ .withQueryParameter("status", { type: "string" }, { required: false })
220
+ .withQueryParameter("scheduleId", { type: "string" }, { required: false })
221
+ .withQueryParameter("start", { type: "string" }, { required: false })
222
+ .withQueryParameter("end", { type: "string" }, { required: false })
223
+ .withQueryParameter("q", { type: "string" }, { required: false });
224
+ const registerJobsAdminRoutes = ({ app, options, }) => {
225
+ const routeOpenApi = options.openApi ? { openApi: options.openApi } : {};
226
+ const requireJobsAdmin = createRequireJobsAdmin(options.accessControl);
227
+ const basePath = options.basePath;
228
+ const { jobsService, redactPayload } = options;
229
+ app.get(`${basePath}/schedules`, [
330
230
  (0, api_1.authenticateMiddleware)(),
331
231
  (0, api_1.createOpenApiBuilder)(routeOpenApi)
332
232
  .withTags(["admin", "jobs"])
@@ -341,21 +241,12 @@ var registerJobsAdminRoutes = function (_a) {
341
241
  },
342
242
  })
343
243
  .build(),
344
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
345
- var schedules;
346
- return __generator(this, function (_a) {
347
- switch (_a.label) {
348
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
349
- case 1:
350
- _a.sent();
351
- return [4 /*yield*/, jobSchedule_1.JobSchedule.find({}).sort("name")];
352
- case 2:
353
- schedules = _a.sent();
354
- return [2 /*return*/, res.json({ data: schedules.map(function (schedule) { return serializeSchedule(schedule); }) })];
355
- }
356
- });
357
- }); }));
358
- app.post("".concat(basePath, "/schedules/:name/pause"), [
244
+ ], (0, api_1.asyncHandler)(async (req, res) => {
245
+ await requireJobsAdmin(req);
246
+ const schedules = await jobSchedule_1.JobSchedule.find({}).sort("name");
247
+ return res.json({ data: schedules.map((schedule) => serializeSchedule(schedule)) });
248
+ }));
249
+ app.post(`${basePath}/schedules/:name/pause`, [
359
250
  (0, api_1.authenticateMiddleware)(),
360
251
  (0, api_1.createOpenApiBuilder)(routeOpenApi)
361
252
  .withTags(["admin", "jobs"])
@@ -363,25 +254,16 @@ var registerJobsAdminRoutes = function (_a) {
363
254
  .withPathParameter("name", { type: "string" })
364
255
  .withResponse(200, { data: { type: "object" } })
365
256
  .build(),
366
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
367
- var name, schedule;
368
- return __generator(this, function (_a) {
369
- switch (_a.label) {
370
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
371
- case 1:
372
- _a.sent();
373
- name = pathParam(req.params.name);
374
- if (!name) {
375
- throw new api_1.NotFoundError("Schedule not found");
376
- }
377
- return [4 /*yield*/, jobsService.pauseSchedule(name)];
378
- case 2:
379
- schedule = _a.sent();
380
- return [2 /*return*/, res.json({ data: serializeSchedule(schedule) })];
381
- }
382
- });
383
- }); }));
384
- app.post("".concat(basePath, "/schedules/:name/resume"), [
257
+ ], (0, api_1.asyncHandler)(async (req, res) => {
258
+ await requireJobsAdmin(req);
259
+ const name = pathParam(req.params.name);
260
+ if (!name) {
261
+ throw new api_1.NotFoundError("Schedule not found");
262
+ }
263
+ const schedule = await jobsService.pauseSchedule(name);
264
+ return res.json({ data: serializeSchedule(schedule) });
265
+ }));
266
+ app.post(`${basePath}/schedules/:name/resume`, [
385
267
  (0, api_1.authenticateMiddleware)(),
386
268
  (0, api_1.createOpenApiBuilder)(routeOpenApi)
387
269
  .withTags(["admin", "jobs"])
@@ -389,24 +271,15 @@ var registerJobsAdminRoutes = function (_a) {
389
271
  .withPathParameter("name", { type: "string" })
390
272
  .withResponse(200, { data: { type: "object" } })
391
273
  .build(),
392
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
393
- var name, schedule;
394
- return __generator(this, function (_a) {
395
- switch (_a.label) {
396
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
397
- case 1:
398
- _a.sent();
399
- name = pathParam(req.params.name);
400
- if (!name) {
401
- throw new api_1.NotFoundError("Schedule not found");
402
- }
403
- return [4 /*yield*/, jobsService.resumeSchedule(name)];
404
- case 2:
405
- schedule = _a.sent();
406
- return [2 /*return*/, res.json({ data: serializeSchedule(schedule) })];
407
- }
408
- });
409
- }); }));
274
+ ], (0, api_1.asyncHandler)(async (req, res) => {
275
+ await requireJobsAdmin(req);
276
+ const name = pathParam(req.params.name);
277
+ if (!name) {
278
+ throw new api_1.NotFoundError("Schedule not found");
279
+ }
280
+ const schedule = await jobsService.resumeSchedule(name);
281
+ return res.json({ data: serializeSchedule(schedule) });
282
+ }));
410
283
  app.get(basePath, [
411
284
  (0, api_1.authenticateMiddleware)(),
412
285
  listQueryParameters((0, api_1.createOpenApiBuilder)(routeOpenApi)
@@ -426,35 +299,26 @@ var registerJobsAdminRoutes = function (_a) {
426
299
  total: { type: "number" },
427
300
  })
428
301
  .build(),
429
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
430
- var filters, page, limit, skip, match, _a, jobs, total;
431
- return __generator(this, function (_b) {
432
- switch (_b.label) {
433
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
434
- case 1:
435
- _b.sent();
436
- filters = parseListFilters(req.query);
437
- page = readPositiveInt(req.query.page, 1, Number.MAX_SAFE_INTEGER);
438
- limit = readPositiveInt(req.query.limit, DEFAULT_LIMIT, MAX_LIMIT);
439
- skip = (page - 1) * limit;
440
- match = buildListMatch(filters);
441
- return [4 /*yield*/, Promise.all([
442
- job_1.Job.find(match).sort("-created").skip(skip).limit(limit),
443
- job_1.Job.countDocuments(match),
444
- ])];
445
- case 2:
446
- _a = __read.apply(void 0, [_b.sent(), 2]), jobs = _a[0], total = _a[1];
447
- return [2 /*return*/, res.json({
448
- data: jobs.map(function (job) { return serializeJob(job, redactPayload); }),
449
- limit: limit,
450
- more: skip + limit < total,
451
- page: page,
452
- total: total,
453
- })];
454
- }
302
+ ], (0, api_1.asyncHandler)(async (req, res) => {
303
+ await requireJobsAdmin(req);
304
+ const filters = parseListFilters(req.query);
305
+ const page = readPositiveInt(req.query.page, 1, Number.MAX_SAFE_INTEGER);
306
+ const limit = readPositiveInt(req.query.limit, DEFAULT_LIMIT, MAX_LIMIT);
307
+ const skip = (page - 1) * limit;
308
+ const match = buildListMatch(filters);
309
+ const [jobs, total] = await Promise.all([
310
+ job_1.Job.find(match).sort("-created").skip(skip).limit(limit),
311
+ job_1.Job.countDocuments(match),
312
+ ]);
313
+ return res.json({
314
+ data: jobs.map((job) => serializeJob(job, redactPayload)),
315
+ limit,
316
+ more: skip + limit < total,
317
+ page,
318
+ total,
455
319
  });
456
- }); }));
457
- app.get("".concat(basePath, "/stats"), [
320
+ }));
321
+ app.get(`${basePath}/stats`, [
458
322
  (0, api_1.authenticateMiddleware)(),
459
323
  (0, api_1.createOpenApiBuilder)(routeOpenApi)
460
324
  .withTags(["admin", "jobs"])
@@ -469,23 +333,14 @@ var registerJobsAdminRoutes = function (_a) {
469
333
  },
470
334
  })
471
335
  .build(),
472
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
473
- var grouped;
474
- return __generator(this, function (_a) {
475
- switch (_a.label) {
476
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
477
- case 1:
478
- _a.sent();
479
- return [4 /*yield*/, job_1.Job.aggregate([
480
- { $group: { _id: "$status", count: { $sum: 1 } } },
481
- ])];
482
- case 2:
483
- grouped = _a.sent();
484
- return [2 /*return*/, res.json({ data: buildStatusCounts(grouped) })];
485
- }
486
- });
487
- }); }));
488
- app.get("".concat(basePath, "/:id"), [
336
+ ], (0, api_1.asyncHandler)(async (req, res) => {
337
+ await requireJobsAdmin(req);
338
+ const grouped = await job_1.Job.aggregate([
339
+ { $group: { _id: "$status", count: { $sum: 1 } } },
340
+ ]);
341
+ return res.json({ data: buildStatusCounts(grouped) });
342
+ }));
343
+ app.get(`${basePath}/:id`, [
489
344
  (0, api_1.authenticateMiddleware)(),
490
345
  (0, api_1.createOpenApiBuilder)(routeOpenApi)
491
346
  .withTags(["admin", "jobs"])
@@ -493,28 +348,19 @@ var registerJobsAdminRoutes = function (_a) {
493
348
  .withPathParameter("id", { type: "string" })
494
349
  .withResponse(200, { data: { type: "object" } })
495
350
  .build(),
496
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
497
- var id, job;
498
- return __generator(this, function (_a) {
499
- switch (_a.label) {
500
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
501
- case 1:
502
- _a.sent();
503
- id = pathParam(req.params.id);
504
- if (!id || !mongoose_1.default.isValidObjectId(id)) {
505
- throw new api_1.NotFoundError("Job not found");
506
- }
507
- return [4 /*yield*/, job_1.Job.findOneOrNone({ _id: id })];
508
- case 2:
509
- job = _a.sent();
510
- if (!job) {
511
- throw new api_1.NotFoundError("Job not found");
512
- }
513
- return [2 /*return*/, res.json({ data: serializeJob(job, redactPayload) })];
514
- }
515
- });
516
- }); }));
517
- app.post("".concat(basePath, "/:id/retry"), [
351
+ ], (0, api_1.asyncHandler)(async (req, res) => {
352
+ await requireJobsAdmin(req);
353
+ const id = pathParam(req.params.id);
354
+ if (!id || !mongoose_1.default.isValidObjectId(id)) {
355
+ throw new api_1.NotFoundError("Job not found");
356
+ }
357
+ const job = await job_1.Job.findOneOrNone({ _id: id });
358
+ if (!job) {
359
+ throw new api_1.NotFoundError("Job not found");
360
+ }
361
+ return res.json({ data: serializeJob(job, redactPayload) });
362
+ }));
363
+ app.post(`${basePath}/:id/retry`, [
518
364
  (0, api_1.authenticateMiddleware)(),
519
365
  (0, api_1.createOpenApiBuilder)(routeOpenApi)
520
366
  .withTags(["admin", "jobs"])
@@ -522,25 +368,16 @@ var registerJobsAdminRoutes = function (_a) {
522
368
  .withPathParameter("id", { type: "string" })
523
369
  .withResponse(200, { data: { type: "object" } })
524
370
  .build(),
525
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
526
- var id, retry;
527
- return __generator(this, function (_a) {
528
- switch (_a.label) {
529
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
530
- case 1:
531
- _a.sent();
532
- id = pathParam(req.params.id);
533
- if (!id || !mongoose_1.default.isValidObjectId(id)) {
534
- throw new api_1.NotFoundError("Job not found");
535
- }
536
- return [4 /*yield*/, jobsService.adminRetryJob(id)];
537
- case 2:
538
- retry = (_a.sent()).retry;
539
- return [2 /*return*/, res.json({ data: serializeJob(retry, redactPayload) })];
540
- }
541
- });
542
- }); }));
543
- app.post("".concat(basePath, "/:id/requeue"), [
371
+ ], (0, api_1.asyncHandler)(async (req, res) => {
372
+ await requireJobsAdmin(req);
373
+ const id = pathParam(req.params.id);
374
+ if (!id || !mongoose_1.default.isValidObjectId(id)) {
375
+ throw new api_1.NotFoundError("Job not found");
376
+ }
377
+ const { retry } = await jobsService.adminRetryJob(id);
378
+ return res.json({ data: serializeJob(retry, redactPayload) });
379
+ }));
380
+ app.post(`${basePath}/:id/requeue`, [
544
381
  (0, api_1.authenticateMiddleware)(),
545
382
  (0, api_1.createOpenApiBuilder)(routeOpenApi)
546
383
  .withTags(["admin", "jobs"])
@@ -548,25 +385,16 @@ var registerJobsAdminRoutes = function (_a) {
548
385
  .withPathParameter("id", { type: "string" })
549
386
  .withResponse(200, { data: { type: "object" } })
550
387
  .build(),
551
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
552
- var id, job;
553
- return __generator(this, function (_a) {
554
- switch (_a.label) {
555
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
556
- case 1:
557
- _a.sent();
558
- id = pathParam(req.params.id);
559
- if (!id || !mongoose_1.default.isValidObjectId(id)) {
560
- throw new api_1.NotFoundError("Job not found");
561
- }
562
- return [4 /*yield*/, jobsService.adminRequeueJob(id)];
563
- case 2:
564
- job = _a.sent();
565
- return [2 /*return*/, res.json({ data: serializeJob(job, redactPayload) })];
566
- }
567
- });
568
- }); }));
569
- app.post("".concat(basePath, "/:id/cancel"), [
388
+ ], (0, api_1.asyncHandler)(async (req, res) => {
389
+ await requireJobsAdmin(req);
390
+ const id = pathParam(req.params.id);
391
+ if (!id || !mongoose_1.default.isValidObjectId(id)) {
392
+ throw new api_1.NotFoundError("Job not found");
393
+ }
394
+ const job = await jobsService.adminRequeueJob(id);
395
+ return res.json({ data: serializeJob(job, redactPayload) });
396
+ }));
397
+ app.post(`${basePath}/:id/cancel`, [
570
398
  (0, api_1.authenticateMiddleware)(),
571
399
  (0, api_1.createOpenApiBuilder)(routeOpenApi)
572
400
  .withTags(["admin", "jobs"])
@@ -574,23 +402,14 @@ var registerJobsAdminRoutes = function (_a) {
574
402
  .withPathParameter("id", { type: "string" })
575
403
  .withResponse(200, { data: { type: "object" } })
576
404
  .build(),
577
- ], (0, api_1.asyncHandler)(function (req, res) { return __awaiter(void 0, void 0, void 0, function () {
578
- var id, job;
579
- return __generator(this, function (_a) {
580
- switch (_a.label) {
581
- case 0: return [4 /*yield*/, requireJobsAdmin(req)];
582
- case 1:
583
- _a.sent();
584
- id = pathParam(req.params.id);
585
- if (!id || !mongoose_1.default.isValidObjectId(id)) {
586
- throw new api_1.NotFoundError("Job not found");
587
- }
588
- return [4 /*yield*/, jobsService.adminCancelJob(id)];
589
- case 2:
590
- job = _a.sent();
591
- return [2 /*return*/, res.json({ data: serializeJob(job, redactPayload) })];
592
- }
593
- });
594
- }); }));
405
+ ], (0, api_1.asyncHandler)(async (req, res) => {
406
+ await requireJobsAdmin(req);
407
+ const id = pathParam(req.params.id);
408
+ if (!id || !mongoose_1.default.isValidObjectId(id)) {
409
+ throw new api_1.NotFoundError("Job not found");
410
+ }
411
+ const job = await jobsService.adminCancelJob(id);
412
+ return res.json({ data: serializeJob(job, redactPayload) });
413
+ }));
595
414
  };
596
415
  exports.registerJobsAdminRoutes = registerJobsAdminRoutes;