diff --git a/.changeset/zod-4-support.md b/.changeset/zod-4-support.md new file mode 100644 index 00000000000..292c759d7cb --- /dev/null +++ b/.changeset/zod-4-support.md @@ -0,0 +1,9 @@ +--- +"@trigger.dev/core": patch +"@trigger.dev/sdk": patch +"trigger.dev": patch +"@trigger.dev/redis-worker": patch +"@trigger.dev/schema-to-json": patch +--- + +Add zod v4 compatibility. The `zod` peer dependency is widened to `^3.25.0 || ^4.0.0`, so projects can use zod 3.25+ or zod 4. Internal code was updated for zod v4 API changes (`ZodError.errors` → `.issues`, single-arg `z.record` → keyed, unified `error` option, `z.ZodSchema`/`z.AnyZodObject` → `z.ZodType`/`z.ZodObject`, `z.any()` object fields made `.optional()` to preserve v3 inference). No runtime behavior change for existing zod 3 users. diff --git a/.server-changes/conform-v1.md b/.server-changes/conform-v1.md new file mode 100644 index 00000000000..5e187829460 --- /dev/null +++ b/.server-changes/conform-v1.md @@ -0,0 +1,6 @@ +--- +area: webapp +type: improvement +--- + +Upgrade the dashboard form layer from `@conform-to` 0.9 to 1.x. conform 1.x supports both zod 3 and zod 4, which unblocks the upcoming zod 4 upgrade. diff --git a/apps/supervisor/package.json b/apps/supervisor/package.json index 2725fe2b729..d4555061708 100644 --- a/apps/supervisor/package.json +++ b/apps/supervisor/package.json @@ -23,7 +23,7 @@ "prom-client": "^15.1.0", "socket.io": "4.7.4", "std-env": "^3.8.0", - "zod": "3.25.76" + "zod": "4.4.3" }, "devDependencies": { "@internal/testcontainers": "workspace:*", diff --git a/apps/webapp/app/components/Feedback.tsx b/apps/webapp/app/components/Feedback.tsx index 0848359e219..fc34d398980 100644 --- a/apps/webapp/app/components/Feedback.tsx +++ b/apps/webapp/app/components/Feedback.tsx @@ -1,5 +1,5 @@ -import { conform, useForm } from "@conform-to/react"; -import { parse } from "@conform-to/zod"; +import { getFormProps, getSelectProps, getInputProps, getTextareaProps, useForm } from "@conform-to/react"; +import { parseWithZod } from "@conform-to/zod/v4"; import { InformationCircleIcon, ArrowUpCircleIcon } from "@heroicons/react/20/solid"; import { EnvelopeIcon, ShieldCheckIcon } from "@heroicons/react/24/solid"; import { Form, useActionData, useLocation, useNavigation, useSearchParams } from "@remix-run/react"; @@ -34,11 +34,11 @@ export function Feedback({ button, defaultValue = "bug", onOpenChange }: Feedbac const navigation = useNavigation(); const [type, setType] = useState(defaultValue); - const [form, { path, feedbackType, message }] = useForm({ + const [form, fields] = useForm({ id: "accept-invite", - lastSubmission: lastSubmission as any, + lastResult: lastSubmission as any, onValidate({ formData }) { - return parse(formData, { schema }); + return parseWithZod(formData, { schema }); }, shouldRevalidate: "onInput", }); @@ -47,8 +47,7 @@ export function Feedback({ button, defaultValue = "bug", onOpenChange }: Feedbac if ( navigation.formAction === "/resources/feedback" && navigation.state === "loading" && - form.error === undefined && - form.errors.length === 0 + (form.errors === undefined || form.errors.length === 0) ) { setOpen(false); } @@ -90,9 +89,9 @@ export function Feedback({ button, defaultValue = "bug", onOpenChange }: Feedbac type === "concurrency" || type === "hipaa" ) &&
} -
+
- + {type === "feature" && ( )} - {feedbackType.error} + {fields.feedbackType.errors} -