express-post-task-scheduler
Version:
A lightweight npm package to create and manage scheduled tasks using Express middleware. Configure tasks via POST requests and execute them at specified times seamlessly.
159 lines (158 loc) • 6.04 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.taskRoutes = void 0;
const express_1 = require("express");
const routes_1 = require("../@types/routes");
const http_status_codes_1 = require("http-status-codes");
const tasks_1 = require("../tasks");
const logger_1 = require("../utils/logger");
const db_1 = require("../utils/db");
const data_1 = require("../utils/data");
const filter_1 = require("../utils/filter");
const dayjs_1 = __importDefault(require("dayjs"));
const time_1 = require("../utils/time");
const scheduleJobs_1 = require("../scheduleJobs");
const scheduler_1 = require("../scheduler");
exports.taskRoutes = (0, express_1.Router)();
const db = db_1.DB.init();
// Schedule a task via post request
exports.taskRoutes.post(routes_1.IRoutes.task, async (req, _res) => {
const { taskName, taskDescription, data, executeTime } = req.body;
const res = _res;
let errorMessage;
const { isValid, error } = (0, data_1.dataValidator)(data);
if (isValid) {
const availableTasks = tasks_1.tasks.map((task) => task.taskName);
if (availableTasks.includes(taskName)) {
// Execotor function of a task, the param is the each item of data array
const executor = tasks_1.tasks.find((task) => task.taskName === taskName).executor;
const { isValid, error, formattedTime, dayjsObject } = (0, time_1.timeConvertor)(executeTime);
if (isValid) {
try {
// Write the created task into db
const newTask = await db.createTask(taskName, taskDescription, formattedTime, JSON.stringify(data));
(0, scheduler_1.scheduleTask)(dayjsObject?.toDate(), data, executor, newTask.id);
logger_1.logger.info(`[Task] ${formattedTime}`);
res.jr({
code: 200,
message: `[Task] ${formattedTime}`,
});
}
catch (e) {
logger_1.logger.error(e);
res.jr({
code: http_status_codes_1.StatusCodes.BAD_REQUEST,
message: `[Error] Store task failed, name: ${taskName}`,
});
}
}
else {
errorMessage = `[Error] ${error}`;
logger_1.logger.error(errorMessage);
res.jr({
code: http_status_codes_1.StatusCodes.BAD_REQUEST,
error: errorMessage,
});
}
}
else {
errorMessage = `[Error] Task not exists, name: ${taskName}`;
logger_1.logger.error(errorMessage);
res.jr({
code: http_status_codes_1.StatusCodes.BAD_REQUEST,
error: errorMessage,
});
}
}
else {
logger_1.logger.error(`[Error] error`);
res.jr({
code: http_status_codes_1.StatusCodes.BAD_REQUEST,
error: error,
});
}
});
// List tasks filtered by conditions
exports.taskRoutes.get(routes_1.IRoutes.task, async (req, _res) => {
const res = _res;
const filter = (0, filter_1.taskFilter)(req.query?.filter?.toString() || "{}");
const tasks = (await db.getTasks(filter)).map((task) => {
return {
...task,
executeTime: (0, dayjs_1.default)(task.executeTime).format("YYYY-MM-DD HH:mm:ss"),
startTime: task.startTime
? (0, dayjs_1.default)(task.startTime).format("YYYY-MM-DD HH:mm:ss")
: null,
finishTime: task.finishTime
? (0, dayjs_1.default)(task.finishTime).format("YYYY-MM-DD HH:mm:ss")
: null,
};
});
res.jr({
code: 200,
data: tasks,
});
});
// Delete task by id
exports.taskRoutes.delete(routes_1.IRoutes.task_id, async (req, _res) => {
const res = _res;
const id = parseInt(req.params.id);
if (!isNaN(id)) {
const db = db_1.DB.init();
const jobs = scheduleJobs_1.ScheduleJobs.init();
const deletedTask = await db.deleteTaskById(id);
const activatedJob = jobs.jobList.find((job) => job.taskId === id);
if (activatedJob) {
activatedJob.jobInstance.cancel();
}
res.jr({
code: 200,
data: deletedTask,
});
}
else {
res.jr({
code: http_status_codes_1.StatusCodes.BAD_REQUEST,
error: "Task id is incorrect",
});
}
});
// Reschedule waiting state task
exports.taskRoutes.put(routes_1.IRoutes.task, async (req, _res) => {
let errorMessage;
const res = _res;
const { taskId, executeTime } = req.body;
if (!isNaN(parseInt(taskId))) {
const { isValid, error, dayjsObject, formattedTime } = (0, time_1.timeConvertor)(executeTime);
if (isValid) {
const rescheduleResult = await db.rescheduleTask(taskId, dayjsObject.toDate());
if (rescheduleResult.isSuccessful) {
logger_1.logger.info(`[Reschedule] task: ${taskId}, time: ${formattedTime}`);
}
res.jr({
code: 200,
message: `Rescheduled task ${taskId}`,
data: rescheduleResult,
});
}
else {
errorMessage = `[Error] ${error}`;
logger_1.logger.error(errorMessage);
res.jr({
code: http_status_codes_1.StatusCodes.BAD_REQUEST,
error: errorMessage,
});
}
}
else {
errorMessage = `[Error] Incorrect task id`;
logger_1.logger.error(errorMessage);
res.jr({
code: http_status_codes_1.StatusCodes.BAD_REQUEST,
error: errorMessage,
});
}
});