Spaces:
Paused
Paused
| import { z } from "zod"; | |
| import { | |
| ISSUE_PRIORITIES, | |
| ROUTINE_CATCH_UP_POLICIES, | |
| ROUTINE_CONCURRENCY_POLICIES, | |
| ROUTINE_STATUSES, | |
| ROUTINE_TRIGGER_SIGNING_MODES, | |
| ROUTINE_VARIABLE_TYPES, | |
| } from "../constants.js"; | |
| import { | |
| ISSUE_EXECUTION_WORKSPACE_PREFERENCES, | |
| issueExecutionWorkspaceSettingsSchema, | |
| } from "./issue.js"; | |
| const routineVariableValueSchema = z.union([z.string(), z.number().finite(), z.boolean()]); | |
| export const routineVariableSchema = z.object({ | |
| name: z.string().trim().regex(/^[A-Za-z][A-Za-z0-9_]*$/), | |
| label: z.string().trim().max(120).optional().nullable(), | |
| type: z.enum(ROUTINE_VARIABLE_TYPES).optional().default("text"), | |
| defaultValue: routineVariableValueSchema.optional().nullable(), | |
| required: z.boolean().optional().default(true), | |
| options: z.array(z.string().trim().min(1).max(120)).max(50).optional().default([]), | |
| }).superRefine((value, ctx) => { | |
| if (value.type === "select" && value.options.length === 0) { | |
| ctx.addIssue({ | |
| code: z.ZodIssueCode.custom, | |
| path: ["options"], | |
| message: "Select variables require at least one option", | |
| }); | |
| } | |
| if (value.type !== "select" && value.options.length > 0) { | |
| ctx.addIssue({ | |
| code: z.ZodIssueCode.custom, | |
| path: ["options"], | |
| message: "Only select variables can define options", | |
| }); | |
| } | |
| if (value.type === "select" && value.defaultValue != null) { | |
| if (typeof value.defaultValue !== "string" || !value.options.includes(value.defaultValue)) { | |
| ctx.addIssue({ | |
| code: z.ZodIssueCode.custom, | |
| path: ["defaultValue"], | |
| message: "Select variable defaults must match one of the allowed options", | |
| }); | |
| } | |
| } | |
| }); | |
| export const createRoutineSchema = z.object({ | |
| projectId: z.string().uuid(), | |
| goalId: z.string().uuid().optional().nullable(), | |
| parentIssueId: z.string().uuid().optional().nullable(), | |
| title: z.string().trim().min(1).max(200), | |
| description: z.string().optional().nullable(), | |
| assigneeAgentId: z.string().uuid(), | |
| priority: z.enum(ISSUE_PRIORITIES).optional().default("medium"), | |
| status: z.enum(ROUTINE_STATUSES).optional().default("active"), | |
| concurrencyPolicy: z.enum(ROUTINE_CONCURRENCY_POLICIES).optional().default("coalesce_if_active"), | |
| catchUpPolicy: z.enum(ROUTINE_CATCH_UP_POLICIES).optional().default("skip_missed"), | |
| variables: z.array(routineVariableSchema).optional().default([]), | |
| }); | |
| export type CreateRoutine = z.infer<typeof createRoutineSchema>; | |
| export const updateRoutineSchema = createRoutineSchema.partial(); | |
| export type UpdateRoutine = z.infer<typeof updateRoutineSchema>; | |
| const baseTriggerSchema = z.object({ | |
| label: z.string().trim().max(120).optional().nullable(), | |
| enabled: z.boolean().optional().default(true), | |
| }); | |
| export const createRoutineTriggerSchema = z.discriminatedUnion("kind", [ | |
| baseTriggerSchema.extend({ | |
| kind: z.literal("schedule"), | |
| cronExpression: z.string().trim().min(1), | |
| timezone: z.string().trim().min(1).default("UTC"), | |
| }), | |
| baseTriggerSchema.extend({ | |
| kind: z.literal("webhook"), | |
| signingMode: z.enum(ROUTINE_TRIGGER_SIGNING_MODES).optional().default("bearer"), | |
| replayWindowSec: z.number().int().min(30).max(86_400).optional().default(300), | |
| }), | |
| baseTriggerSchema.extend({ | |
| kind: z.literal("api"), | |
| }), | |
| ]); | |
| export type CreateRoutineTrigger = z.infer<typeof createRoutineTriggerSchema>; | |
| export const updateRoutineTriggerSchema = z.object({ | |
| label: z.string().trim().max(120).optional().nullable(), | |
| enabled: z.boolean().optional(), | |
| cronExpression: z.string().trim().min(1).optional().nullable(), | |
| timezone: z.string().trim().min(1).optional().nullable(), | |
| signingMode: z.enum(ROUTINE_TRIGGER_SIGNING_MODES).optional().nullable(), | |
| replayWindowSec: z.number().int().min(30).max(86_400).optional().nullable(), | |
| }); | |
| export type UpdateRoutineTrigger = z.infer<typeof updateRoutineTriggerSchema>; | |
| export const runRoutineSchema = z.object({ | |
| triggerId: z.string().uuid().optional().nullable(), | |
| payload: z.record(z.unknown()).optional().nullable(), | |
| variables: z.record(routineVariableValueSchema).optional().nullable(), | |
| idempotencyKey: z.string().trim().max(255).optional().nullable(), | |
| source: z.enum(["manual", "api"]).optional().default("manual"), | |
| executionWorkspaceId: z.string().uuid().optional().nullable(), | |
| executionWorkspacePreference: z.enum(ISSUE_EXECUTION_WORKSPACE_PREFERENCES).optional().nullable(), | |
| executionWorkspaceSettings: issueExecutionWorkspaceSettingsSchema.optional().nullable(), | |
| }); | |
| export type RunRoutine = z.infer<typeof runRoutineSchema>; | |
| export const rotateRoutineTriggerSecretSchema = z.object({}); | |
| export type RotateRoutineTriggerSecret = z.infer<typeof rotateRoutineTriggerSecretSchema>; | |