diff --git a/extensions/webhooks/src/http.ts b/extensions/webhooks/src/http.ts index 410f9aa7f577..6af0c024100e 100644 --- a/extensions/webhooks/src/http.ts +++ b/extensions/webhooks/src/http.ts @@ -21,107 +21,86 @@ import type { WebhookSecretInput } from "./config.js"; type BoundTaskFlowRuntime = ReturnType; -type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }; - -const jsonValueSchema: z.ZodType = z.lazy(() => - z.union([ - z.null(), - z.boolean(), - z.number().finite(), - z.string(), - z.array(jsonValueSchema), - z.record(z.string(), jsonValueSchema), - ]), -); +const jsonValueSchema = z.json(); +type JsonValue = z.infer; const nullableStringSchema = z.string().trim().min(1).nullable().optional(); -const createFlowRequestSchema = z - .object({ - action: z.literal("create_flow"), - controllerId: z.string().trim().min(1).optional(), - goal: z.string().trim().min(1), - status: z.enum(["queued", "running", "waiting", "blocked"]).optional(), - notifyPolicy: z.enum(["done_only", "state_changes", "silent"]).optional(), - currentStep: nullableStringSchema, - stateJson: jsonValueSchema.nullable().optional(), - waitJson: jsonValueSchema.nullable().optional(), - }) - .strict(); +const createFlowRequestSchema = z.strictObject({ + action: z.literal("create_flow"), + controllerId: z.string().trim().min(1).optional(), + goal: z.string().trim().min(1), + status: z.enum(["queued", "running", "waiting", "blocked"]).optional(), + notifyPolicy: z.enum(["done_only", "state_changes", "silent"]).optional(), + currentStep: nullableStringSchema, + stateJson: jsonValueSchema.nullable().optional(), + waitJson: jsonValueSchema.nullable().optional(), +}); -const getFlowRequestSchema = z - .object({ action: z.literal("get_flow"), flowId: z.string().trim().min(1) }) - .strict(); -const listFlowsRequestSchema = z.object({ action: z.literal("list_flows") }).strict(); -const findLatestFlowRequestSchema = z.object({ action: z.literal("find_latest_flow") }).strict(); -const resolveFlowRequestSchema = z - .object({ action: z.literal("resolve_flow"), token: z.string().trim().min(1) }) - .strict(); -const getTaskSummaryRequestSchema = z - .object({ action: z.literal("get_task_summary"), flowId: z.string().trim().min(1) }) - .strict(); +const getFlowRequestSchema = z.strictObject({ + action: z.literal("get_flow"), + flowId: z.string().trim().min(1), +}); +const listFlowsRequestSchema = z.strictObject({ action: z.literal("list_flows") }); +const findLatestFlowRequestSchema = z.strictObject({ action: z.literal("find_latest_flow") }); +const resolveFlowRequestSchema = z.strictObject({ + action: z.literal("resolve_flow"), + token: z.string().trim().min(1), +}); +const getTaskSummaryRequestSchema = z.strictObject({ + action: z.literal("get_task_summary"), + flowId: z.string().trim().min(1), +}); -const setWaitingRequestSchema = z - .object({ - action: z.literal("set_waiting"), - flowId: z.string().trim().min(1), - expectedRevision: z.number().int().nonnegative(), - currentStep: nullableStringSchema, - stateJson: jsonValueSchema.nullable().optional(), - waitJson: jsonValueSchema.nullable().optional(), - blockedTaskId: nullableStringSchema, - blockedSummary: nullableStringSchema, - }) - .strict(); +const setWaitingRequestSchema = z.strictObject({ + action: z.literal("set_waiting"), + flowId: z.string().trim().min(1), + expectedRevision: z.number().int().nonnegative(), + currentStep: nullableStringSchema, + stateJson: jsonValueSchema.nullable().optional(), + waitJson: jsonValueSchema.nullable().optional(), + blockedTaskId: nullableStringSchema, + blockedSummary: nullableStringSchema, +}); -const resumeFlowRequestSchema = z - .object({ - action: z.literal("resume_flow"), - flowId: z.string().trim().min(1), - expectedRevision: z.number().int().nonnegative(), - status: z.enum(["queued", "running"]).optional(), - currentStep: nullableStringSchema, - stateJson: jsonValueSchema.nullable().optional(), - }) - .strict(); +const resumeFlowRequestSchema = z.strictObject({ + action: z.literal("resume_flow"), + flowId: z.string().trim().min(1), + expectedRevision: z.number().int().nonnegative(), + status: z.enum(["queued", "running"]).optional(), + currentStep: nullableStringSchema, + stateJson: jsonValueSchema.nullable().optional(), +}); -const finishFlowRequestSchema = z - .object({ - action: z.literal("finish_flow"), - flowId: z.string().trim().min(1), - expectedRevision: z.number().int().nonnegative(), - stateJson: jsonValueSchema.nullable().optional(), - }) - .strict(); +const finishFlowRequestSchema = z.strictObject({ + action: z.literal("finish_flow"), + flowId: z.string().trim().min(1), + expectedRevision: z.number().int().nonnegative(), + stateJson: jsonValueSchema.nullable().optional(), +}); -const failFlowRequestSchema = z - .object({ - action: z.literal("fail_flow"), - flowId: z.string().trim().min(1), - expectedRevision: z.number().int().nonnegative(), - stateJson: jsonValueSchema.nullable().optional(), - blockedTaskId: nullableStringSchema, - blockedSummary: nullableStringSchema, - }) - .strict(); +const failFlowRequestSchema = z.strictObject({ + action: z.literal("fail_flow"), + flowId: z.string().trim().min(1), + expectedRevision: z.number().int().nonnegative(), + stateJson: jsonValueSchema.nullable().optional(), + blockedTaskId: nullableStringSchema, + blockedSummary: nullableStringSchema, +}); -const requestCancelRequestSchema = z - .object({ - action: z.literal("request_cancel"), - flowId: z.string().trim().min(1), - expectedRevision: z.number().int().nonnegative(), - }) - .strict(); +const requestCancelRequestSchema = z.strictObject({ + action: z.literal("request_cancel"), + flowId: z.string().trim().min(1), + expectedRevision: z.number().int().nonnegative(), +}); -const cancelFlowRequestSchema = z - .object({ - action: z.literal("cancel_flow"), - flowId: z.string().trim().min(1), - }) - .strict(); +const cancelFlowRequestSchema = z.strictObject({ + action: z.literal("cancel_flow"), + flowId: z.string().trim().min(1), +}); const runTaskRequestSchema = z - .object({ + .strictObject({ action: z.literal("run_task"), flowId: z.string().trim().min(1), runtime: z.enum(["subagent", "acp"]), @@ -139,7 +118,6 @@ const runTaskRequestSchema = z lastEventAt: z.number().int().nonnegative().optional(), progressSummary: nullableStringSchema, }) - .strict() .superRefine((value, ctx) => { if ( value.status !== "running" &&