Spaces:
Paused
Paused
| import type { CronJobCreate, CronJobPatch } from "../../cron/types.js"; | |
| import type { GatewayRequestHandlers } from "./types.js"; | |
| import { normalizeCronJobCreate, normalizeCronJobPatch } from "../../cron/normalize.js"; | |
| import { readCronRunLogEntries, resolveCronRunLogPath } from "../../cron/run-log.js"; | |
| import { | |
| ErrorCodes, | |
| errorShape, | |
| formatValidationErrors, | |
| validateCronAddParams, | |
| validateCronListParams, | |
| validateCronRemoveParams, | |
| validateCronRunParams, | |
| validateCronRunsParams, | |
| validateCronStatusParams, | |
| validateCronUpdateParams, | |
| validateWakeParams, | |
| } from "../protocol/index.js"; | |
| export const cronHandlers: GatewayRequestHandlers = { | |
| wake: ({ params, respond, context }) => { | |
| if (!validateWakeParams(params)) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape( | |
| ErrorCodes.INVALID_REQUEST, | |
| `invalid wake params: ${formatValidationErrors(validateWakeParams.errors)}`, | |
| ), | |
| ); | |
| return; | |
| } | |
| const p = params as { | |
| mode: "now" | "next-heartbeat"; | |
| text: string; | |
| }; | |
| const result = context.cron.wake({ mode: p.mode, text: p.text }); | |
| respond(true, result, undefined); | |
| }, | |
| "cron.list": async ({ params, respond, context }) => { | |
| if (!validateCronListParams(params)) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape( | |
| ErrorCodes.INVALID_REQUEST, | |
| `invalid cron.list params: ${formatValidationErrors(validateCronListParams.errors)}`, | |
| ), | |
| ); | |
| return; | |
| } | |
| const p = params as { includeDisabled?: boolean }; | |
| const jobs = await context.cron.list({ | |
| includeDisabled: p.includeDisabled, | |
| }); | |
| respond(true, { jobs }, undefined); | |
| }, | |
| "cron.status": async ({ params, respond, context }) => { | |
| if (!validateCronStatusParams(params)) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape( | |
| ErrorCodes.INVALID_REQUEST, | |
| `invalid cron.status params: ${formatValidationErrors(validateCronStatusParams.errors)}`, | |
| ), | |
| ); | |
| return; | |
| } | |
| const status = await context.cron.status(); | |
| respond(true, status, undefined); | |
| }, | |
| "cron.add": async ({ params, respond, context }) => { | |
| const normalized = normalizeCronJobCreate(params) ?? params; | |
| if (!validateCronAddParams(normalized)) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape( | |
| ErrorCodes.INVALID_REQUEST, | |
| `invalid cron.add params: ${formatValidationErrors(validateCronAddParams.errors)}`, | |
| ), | |
| ); | |
| return; | |
| } | |
| const job = await context.cron.add(normalized as unknown as CronJobCreate); | |
| respond(true, job, undefined); | |
| }, | |
| "cron.update": async ({ params, respond, context }) => { | |
| const normalizedPatch = normalizeCronJobPatch((params as { patch?: unknown } | null)?.patch); | |
| const candidate = | |
| normalizedPatch && typeof params === "object" && params !== null | |
| ? { ...params, patch: normalizedPatch } | |
| : params; | |
| if (!validateCronUpdateParams(candidate)) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape( | |
| ErrorCodes.INVALID_REQUEST, | |
| `invalid cron.update params: ${formatValidationErrors(validateCronUpdateParams.errors)}`, | |
| ), | |
| ); | |
| return; | |
| } | |
| const p = candidate as { | |
| id?: string; | |
| jobId?: string; | |
| patch: Record<string, unknown>; | |
| }; | |
| const jobId = p.id ?? p.jobId; | |
| if (!jobId) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape(ErrorCodes.INVALID_REQUEST, "invalid cron.update params: missing id"), | |
| ); | |
| return; | |
| } | |
| const job = await context.cron.update(jobId, p.patch as unknown as CronJobPatch); | |
| respond(true, job, undefined); | |
| }, | |
| "cron.remove": async ({ params, respond, context }) => { | |
| if (!validateCronRemoveParams(params)) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape( | |
| ErrorCodes.INVALID_REQUEST, | |
| `invalid cron.remove params: ${formatValidationErrors(validateCronRemoveParams.errors)}`, | |
| ), | |
| ); | |
| return; | |
| } | |
| const p = params as { id?: string; jobId?: string }; | |
| const jobId = p.id ?? p.jobId; | |
| if (!jobId) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape(ErrorCodes.INVALID_REQUEST, "invalid cron.remove params: missing id"), | |
| ); | |
| return; | |
| } | |
| const result = await context.cron.remove(jobId); | |
| respond(true, result, undefined); | |
| }, | |
| "cron.run": async ({ params, respond, context }) => { | |
| if (!validateCronRunParams(params)) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape( | |
| ErrorCodes.INVALID_REQUEST, | |
| `invalid cron.run params: ${formatValidationErrors(validateCronRunParams.errors)}`, | |
| ), | |
| ); | |
| return; | |
| } | |
| const p = params as { id?: string; jobId?: string; mode?: "due" | "force" }; | |
| const jobId = p.id ?? p.jobId; | |
| if (!jobId) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape(ErrorCodes.INVALID_REQUEST, "invalid cron.run params: missing id"), | |
| ); | |
| return; | |
| } | |
| const result = await context.cron.run(jobId, p.mode); | |
| respond(true, result, undefined); | |
| }, | |
| "cron.runs": async ({ params, respond, context }) => { | |
| if (!validateCronRunsParams(params)) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape( | |
| ErrorCodes.INVALID_REQUEST, | |
| `invalid cron.runs params: ${formatValidationErrors(validateCronRunsParams.errors)}`, | |
| ), | |
| ); | |
| return; | |
| } | |
| const p = params as { id?: string; jobId?: string; limit?: number }; | |
| const jobId = p.id ?? p.jobId; | |
| if (!jobId) { | |
| respond( | |
| false, | |
| undefined, | |
| errorShape(ErrorCodes.INVALID_REQUEST, "invalid cron.runs params: missing id"), | |
| ); | |
| return; | |
| } | |
| const logPath = resolveCronRunLogPath({ | |
| storePath: context.cronStorePath, | |
| jobId, | |
| }); | |
| const entries = await readCronRunLogEntries(logPath, { | |
| limit: p.limit, | |
| jobId, | |
| }); | |
| respond(true, { entries }, undefined); | |
| }, | |
| }; | |