3 changed files with 83 additions and 0 deletions
@ -0,0 +1,12 @@ |
|||||
|
import { deleteTask } from "../../../service/scheduler"; |
||||
|
import { removeTask } from "../../../scheduler/engine"; |
||||
|
|
||||
|
export default defineWrappedResponseHandler(async (event) => { |
||||
|
const id = getRouterParam(event, "id"); |
||||
|
if (!id) return R.throwError(400, "Missing id", null); |
||||
|
|
||||
|
removeTask(id); |
||||
|
await deleteTask(id); |
||||
|
|
||||
|
return R.success(null); |
||||
|
}); |
||||
@ -0,0 +1,13 @@ |
|||||
|
import { getTaskById, getRecentExecutions } from "../../../service/scheduler"; |
||||
|
|
||||
|
export default defineWrappedResponseHandler(async (event) => { |
||||
|
const id = getRouterParam(event, "id"); |
||||
|
if (!id) return R.throwError(400, "Missing id", null); |
||||
|
|
||||
|
const task = await getTaskById(id); |
||||
|
if (!task) return R.throwError(404, "Task not found", null); |
||||
|
|
||||
|
const recentExecutions = await getRecentExecutions(id, 20); |
||||
|
|
||||
|
return R.success({ task, recentExecutions }); |
||||
|
}); |
||||
@ -0,0 +1,58 @@ |
|||||
|
import { z } from "zod"; |
||||
|
import { updateTask, getTaskById } from "../../../service/scheduler"; |
||||
|
import { reloadTask } from "../../../scheduler/engine"; |
||||
|
import { Cron } from "croner"; |
||||
|
|
||||
|
const updateTaskSchema = z.object({ |
||||
|
name: z.string().min(1).optional(), |
||||
|
cronExpression: z.string().min(1).optional(), |
||||
|
type: z.enum(["function", "http"]).optional(), |
||||
|
functionName: z.string().optional().nullable(), |
||||
|
functionPayload: z.string().optional().nullable(), |
||||
|
httpMethod: z.enum(["GET", "POST", "PUT", "DELETE"]).optional().nullable(), |
||||
|
httpUrl: z.string().optional().nullable(), |
||||
|
httpHeaders: z.string().optional().nullable(), |
||||
|
httpBody: z.string().optional().nullable(), |
||||
|
catchUp: z.union([z.boolean(), z.number()]).optional(), |
||||
|
enabled: z.union([z.boolean(), z.number()]).optional(), |
||||
|
maxRetries: z.number().int().min(0).optional(), |
||||
|
retryDelaySeconds: z.number().int().min(1).optional(), |
||||
|
timeoutSeconds: z.number().int().min(1).optional(), |
||||
|
}); |
||||
|
|
||||
|
export default defineWrappedResponseHandler(async (event) => { |
||||
|
const id = getRouterParam(event, "id"); |
||||
|
if (!id) return R.throwError(400, "Missing id", null); |
||||
|
|
||||
|
const body = await readBody(event); |
||||
|
const parsed = updateTaskSchema.safeParse(body); |
||||
|
if (!parsed.success) { |
||||
|
return R.throwError(422, "Validation failed", parsed.error.issues); |
||||
|
} |
||||
|
|
||||
|
const existing = await getTaskById(id); |
||||
|
if (!existing) return R.throwError(404, "Task not found", null); |
||||
|
|
||||
|
// Validate cron if provided
|
||||
|
const cronExpr = parsed.data.cronExpression ?? existing.cronExpression; |
||||
|
try { |
||||
|
new Cron(cronExpr); |
||||
|
} catch { |
||||
|
return R.throwError(422, "Invalid cron expression", null); |
||||
|
} |
||||
|
|
||||
|
const updateData: Record<string, unknown> = { ...parsed.data }; |
||||
|
if (parsed.data.catchUp !== undefined) { |
||||
|
updateData.catchUp = parsed.data.catchUp ? 1 : 0; |
||||
|
} |
||||
|
if (parsed.data.enabled !== undefined) { |
||||
|
updateData.enabled = parsed.data.enabled ? 1 : 0; |
||||
|
} |
||||
|
|
||||
|
const task = await updateTask(id, updateData as Parameters<typeof updateTask>[1]); |
||||
|
if (task) { |
||||
|
reloadTask(task.id); |
||||
|
} |
||||
|
|
||||
|
return R.success(task); |
||||
|
}); |
||||
Loading…
Reference in new issue