diff --git a/apps/dashboard/next-env.d.ts b/apps/dashboard/next-env.d.ts index c4b7818fb..9edff1c7c 100644 --- a/apps/dashboard/next-env.d.ts +++ b/apps/dashboard/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/dashboard/package.json b/apps/dashboard/package.json index 5354ed0eb..095590f32 100644 --- a/apps/dashboard/package.json +++ b/apps/dashboard/package.json @@ -19,7 +19,7 @@ "@dnd-kit/sortable": "10.0.0", "@dnd-kit/utilities": "3.2.2", "@hookform/devtools": "4.4.0", - "@hookform/resolvers": "4.1.3", + "@hookform/resolvers": "5.1.0", "@libsql/client": "0.15.15", "@openpanel/nextjs": "1.0.8", "@openstatus/analytics": "workspace:*", @@ -100,7 +100,7 @@ "superjson": "2.2.2", "tailwind-merge": "3.3.1", "unified": "11.0.5", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@tailwindcss/postcss": "4.1.11", diff --git a/apps/dashboard/src/components/forms/maintenance/form.tsx b/apps/dashboard/src/components/forms/maintenance/form.tsx index 0e76d1ba8..70805090e 100644 --- a/apps/dashboard/src/components/forms/maintenance/form.tsx +++ b/apps/dashboard/src/components/forms/maintenance/form.tsx @@ -56,7 +56,7 @@ const schema = z notifySubscribers: z.boolean().optional(), }) .refine((data) => data.endDate > data.startDate, { - message: "End date cannot be earlier than start date.", + error: "End date cannot be earlier than start date.", path: ["endDate"], }); diff --git a/apps/dashboard/src/components/forms/monitor/form-follow-redirect.tsx b/apps/dashboard/src/components/forms/monitor/form-follow-redirect.tsx index d1c1592b8..9fadbf654 100644 --- a/apps/dashboard/src/components/forms/monitor/form-follow-redirect.tsx +++ b/apps/dashboard/src/components/forms/monitor/form-follow-redirect.tsx @@ -29,10 +29,10 @@ import { z } from "zod"; export const FOLLOW_REDIRECTS_DEFAULT = true; const schema = z.object({ - followRedirects: z.boolean().default(true), + followRedirects: z.boolean().prefault(true), }); -type FormValues = z.infer; +type FormValues = z.input; export function FormFollowRedirect({ defaultValues, diff --git a/apps/dashboard/src/components/forms/monitor/form-general.tsx b/apps/dashboard/src/components/forms/monitor/form-general.tsx index 7a86ef83b..bc8301fce 100644 --- a/apps/dashboard/src/components/forms/monitor/form-general.tsx +++ b/apps/dashboard/src/components/forms/monitor/form-general.tsx @@ -83,7 +83,7 @@ const schema = z.object({ value: z.string(), }), ), - active: z.boolean().optional().default(true), + active: z.boolean().optional().prefault(true), assertions: z.array( z.discriminatedUnion("type", [ statusAssertion, @@ -94,11 +94,11 @@ const schema = z.object({ ]), ), body: z.string().optional(), - skipCheck: z.boolean().optional().default(false), - saveCheck: z.boolean().optional().default(false), + skipCheck: z.boolean().optional().prefault(false), + saveCheck: z.boolean().optional().prefault(false), }); -type FormValues = z.infer; +type FormValues = z.input; export function FormGeneral({ defaultValues, @@ -554,6 +554,7 @@ export function FormGeneral({ placeholder="Header key" className="w-full" {...field} + value={field.value as string} /> @@ -777,7 +778,7 @@ export function FormGeneral({ render={({ field }) => ( { - const newHeaders = [...field.value]; + const newHeaders = [...(field.value ?? [])]; newHeaders[index] = { ...newHeaders[index], key: e.target.value, @@ -132,7 +132,7 @@ export function FormOtel({ value={header.value} disabled={locked} onChange={(e) => { - const newHeaders = [...field.value]; + const newHeaders = [...(field.value ?? [])]; newHeaders[index] = { ...newHeaders[index], value: e.target.value, @@ -144,7 +144,7 @@ export function FormOtel({ size="icon" variant="ghost" onClick={() => { - const newHeaders = field.value.filter( + const newHeaders = field.value?.filter( (_, i) => i !== index, ); field.onChange(newHeaders); @@ -162,7 +162,7 @@ export function FormOtel({ disabled={locked} onClick={() => { field.onChange([ - ...field.value, + ...(field.value ?? []), { key: "", value: "" }, ]); }} diff --git a/apps/dashboard/src/components/forms/monitor/form-response-time.tsx b/apps/dashboard/src/components/forms/monitor/form-response-time.tsx index 80841529b..0d10377ff 100644 --- a/apps/dashboard/src/components/forms/monitor/form-response-time.tsx +++ b/apps/dashboard/src/components/forms/monitor/form-response-time.tsx @@ -30,11 +30,11 @@ const DEGRADED = 30_000; const TIMEOUT = 45_000; const schema = z.object({ - degradedAfter: z.coerce.number().optional(), - timeout: z.coerce.number(), + degradedAfter: z.coerce.number().optional(), + timeout: z.coerce.number(), }); -type FormValues = z.infer; +type FormValues = z.input; export function FormResponseTime({ defaultValues, diff --git a/apps/dashboard/src/components/forms/monitor/form-retry.tsx b/apps/dashboard/src/components/forms/monitor/form-retry.tsx index 6496dd419..84113b0a6 100644 --- a/apps/dashboard/src/components/forms/monitor/form-retry.tsx +++ b/apps/dashboard/src/components/forms/monitor/form-retry.tsx @@ -32,10 +32,14 @@ const RETRY_MAX = 10; export const RETRY_DEFAULT = 3; const schema = z.object({ - retry: z.coerce.number().min(RETRY_MIN).max(RETRY_MAX).default(RETRY_DEFAULT), + retry: z.coerce + .number() + .min(RETRY_MIN) + .max(RETRY_MAX) + .prefault(RETRY_DEFAULT), }); -type FormValues = z.infer; +type FormValues = z.input; export function FormRetry({ defaultValues, diff --git a/apps/dashboard/src/components/forms/monitor/update.tsx b/apps/dashboard/src/components/forms/monitor/update.tsx index fdc7242c0..f18bb990b 100644 --- a/apps/dashboard/src/components/forms/monitor/update.tsx +++ b/apps/dashboard/src/components/forms/monitor/update.tsx @@ -6,7 +6,10 @@ import { deserialize } from "@openstatus/assertions"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { useParams, useRouter } from "next/navigation"; import { FormDangerZone } from "./form-danger-zone"; -import { FormFollowRedirect } from "./form-follow-redirect"; +import { + FOLLOW_REDIRECTS_DEFAULT, + FormFollowRedirect, +} from "./form-follow-redirect"; import { FormGeneral } from "./form-general"; import { FormNotifiers } from "./form-notifiers"; import { FormOtel } from "./form-otel"; @@ -226,20 +229,20 @@ export function FormMonitorUpdate() { onSubmit={async (values) => await updateRetryMutation.mutateAsync({ id: Number.parseInt(id), - retry: values.retry, + retry: values.retry ?? RETRY_DEFAULT, }) } /> { + onSubmit={async (values) => await updateFollowRedirectsMutation.mutateAsync({ id: Number.parseInt(id), - followRedirects: values.followRedirects, - }); - }} + followRedirects: values.followRedirects ?? FOLLOW_REDIRECTS_DEFAULT, + }) + } /> { + if (isTRPCClientError(error)) { + return error.message; + } if (error instanceof Error) { return error.message; } diff --git a/apps/dashboard/src/components/forms/onboarding/create-monitor.tsx b/apps/dashboard/src/components/forms/onboarding/create-monitor.tsx index b13339fc5..52bcd8efb 100644 --- a/apps/dashboard/src/components/forms/onboarding/create-monitor.tsx +++ b/apps/dashboard/src/components/forms/onboarding/create-monitor.tsx @@ -18,7 +18,7 @@ import { toast } from "sonner"; import { z } from "zod"; const schema = z.object({ - url: z.string().url(), + url: z.url(), }); export type FormValues = z.infer; diff --git a/apps/dashboard/src/components/forms/settings/form-members.tsx b/apps/dashboard/src/components/forms/settings/form-members.tsx index 2a256ff21..6da0c1d9e 100644 --- a/apps/dashboard/src/components/forms/settings/form-members.tsx +++ b/apps/dashboard/src/components/forms/settings/form-members.tsx @@ -37,7 +37,7 @@ import { toast } from "sonner"; import { z } from "zod"; const schema = z.object({ - email: z.string().email(), + email: z.email(), role: z.enum(["member"]), }); diff --git a/apps/dashboard/src/components/forms/status-page/form-configuration.tsx b/apps/dashboard/src/components/forms/status-page/form-configuration.tsx index 8ad2f8cc0..b118f9a40 100644 --- a/apps/dashboard/src/components/forms/status-page/form-configuration.tsx +++ b/apps/dashboard/src/components/forms/status-page/form-configuration.tsx @@ -67,7 +67,7 @@ const configurationSchema = z return true; }, { - message: "Value must be manual when type is manual", + error: "Value must be manual when type is manual", path: ["value"], }, ); diff --git a/apps/dashboard/src/components/forms/status-page/form-monitors.tsx b/apps/dashboard/src/components/forms/status-page/form-monitors.tsx index f760f4bdb..ec8231e15 100644 --- a/apps/dashboard/src/components/forms/status-page/form-monitors.tsx +++ b/apps/dashboard/src/components/forms/status-page/form-monitors.tsx @@ -103,9 +103,9 @@ const schema = z.object({ id: z.number(), order: z.number(), name: z.string(), - monitors: z - .array(monitorSchema) - .min(1, { message: "At least one monitor is required" }), + monitors: z.array(monitorSchema).min(1, { + error: "At least one monitor is required", + }), }), ), }); diff --git a/apps/dashboard/src/components/forms/support-contact/form.tsx b/apps/dashboard/src/components/forms/support-contact/form.tsx index a8ae3762a..95992d2d3 100644 --- a/apps/dashboard/src/components/forms/support-contact/form.tsx +++ b/apps/dashboard/src/components/forms/support-contact/form.tsx @@ -49,10 +49,16 @@ export const types = [ ]; export const schema = z.object({ - name: z.string().min(1, { message: "Name is required" }), + name: z.string().min(1, { + error: "Name is required", + }), type: z.enum(["bug", "demo", "feature", "security", "question"]), - email: z.string().email({ message: "Invalid email address" }), - message: z.string().min(1, { message: "Message is required" }), + email: z.email({ + error: "Invalid email address", + }), + message: z.string().min(1, { + error: "Message is required", + }), blocker: z.boolean(), }); diff --git a/apps/screenshot-service/package.json b/apps/screenshot-service/package.json index 123174745..a4fa68c6d 100644 --- a/apps/screenshot-service/package.json +++ b/apps/screenshot-service/package.json @@ -14,7 +14,7 @@ "@upstash/qstash": "2.6.2", "hono": "4.5.3", "playwright": "1.46.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/apps/screenshot-service/src/index.ts b/apps/screenshot-service/src/index.ts index 19f764e26..d5f0b98be 100644 --- a/apps/screenshot-service/src/index.ts +++ b/apps/screenshot-service/src/index.ts @@ -35,7 +35,7 @@ app.post( zValidator( "json", z.object({ - url: z.string().url(), + url: z.url(), incidentId: z.number(), kind: z.enum(["incident", "recovery"]), }), diff --git a/apps/server/package.json b/apps/server/package.json index 9cd4c47c7..93ded7050 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@hono/sentry": "1.2.2", - "@hono/zod-openapi": "0.15.1", + "@hono/zod-openapi": "1.1.5", "@hono/zod-validator": "0.2.2", "@logtape/logtape": "1.1.2", "@logtape/sentry": "1.1.2", @@ -35,7 +35,7 @@ "nanoid": "5.0.7", "percentile": "1.6.0", "validator": "13.12.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/apps/server/src/env.ts b/apps/server/src/env.ts index 081df5371..0eaf21557 100644 --- a/apps/server/src/env.ts +++ b/apps/server/src/env.ts @@ -13,7 +13,7 @@ export const env = createEnv({ CRON_SECRET: z.string(), SCREENSHOT_SERVICE_URL: z.string(), QSTASH_TOKEN: z.string(), - NODE_ENV: z.string().default("development"), + NODE_ENV: z.string().prefault("development"), SUPER_ADMIN_TOKEN: z.string(), RESEND_API_KEY: z.string(), }, diff --git a/apps/server/src/routes/v1/check/http/schema.ts b/apps/server/src/routes/v1/check/http/schema.ts index 6c1dbddc7..92e0eea97 100644 --- a/apps/server/src/routes/v1/check/http/schema.ts +++ b/apps/server/src/routes/v1/check/http/schema.ts @@ -13,7 +13,7 @@ export const CheckSchema = MonitorSchema.pick({ .number() .max(5) .optional() - .default(1) + .prefault(1) .openapi({ description: "The number of times to run the check" }), aggregated: z .boolean() @@ -87,7 +87,7 @@ export const ResponseSchema = z.object({ .optional() .openapi({ description: "The body of the response" }), headers: z - .record(z.string()) + .record(z.string(), z.string()) .optional() .openapi({ description: "The headers of the response" }), timing: TimingSchema.openapi({ @@ -131,7 +131,7 @@ export const AggregatedResult = z.object({ }); export const CheckPostResponseSchema = z.object({ - id: z.number().int().openapi({ description: "The id of the check" }), + id: z.int().openapi({ description: "The id of the check" }), raw: z.array(TimingSchema).openapi({ description: "The raw data of the check", }), diff --git a/apps/server/src/routes/v1/incidents/put.test.ts b/apps/server/src/routes/v1/incidents/put.test.ts index 676be424e..9fe37cdb0 100644 --- a/apps/server/src/routes/v1/incidents/put.test.ts +++ b/apps/server/src/routes/v1/incidents/put.test.ts @@ -60,7 +60,10 @@ test("invalid payload should return 400", async () => { }); const result = (await res.json()) as Record; - expect(result.message).toBe("invalid_date in 'acknowledgedAt': Invalid date"); + // expect(result.message).toBe("invalid_date in 'acknowledgedAt': Invalid date"); + expect(result.message).toBe( + "invalid_type in 'acknowledgedAt': Invalid input: expected date, received Date", + ); expect(res.status).toBe(400); }); diff --git a/apps/server/src/routes/v1/maintenances/schema.ts b/apps/server/src/routes/v1/maintenances/schema.ts index ee3782aff..6b30a7746 100644 --- a/apps/server/src/routes/v1/maintenances/schema.ts +++ b/apps/server/src/routes/v1/maintenances/schema.ts @@ -37,7 +37,7 @@ export const MaintenanceSchema = z monitorIds: z .array(z.number()) .optional() - .default([]) + .prefault([]) .openapi({ description: "IDs of affected monitors" }), pageId: z.number().openapi({ description: "The id of the status page this maintenance belongs to", diff --git a/apps/server/src/routes/v1/monitors/run/schema.ts b/apps/server/src/routes/v1/monitors/run/schema.ts index 06cbc489c..ca0e86a04 100644 --- a/apps/server/src/routes/v1/monitors/run/schema.ts +++ b/apps/server/src/routes/v1/monitors/run/schema.ts @@ -2,7 +2,7 @@ import { z } from "@hono/zod-openapi"; export const QuerySchema = z .object({ - "no-wait": z.coerce.boolean().optional().default(false).openapi({ + "no-wait": z.coerce.boolean().optional().prefault(false).openapi({ description: "Don't wait for the result", }), }) diff --git a/apps/server/src/routes/v1/monitors/schema.ts b/apps/server/src/routes/v1/monitors/schema.ts index 1f6994e20..31c35f0b3 100644 --- a/apps/server/src/routes/v1/monitors/schema.ts +++ b/apps/server/src/routes/v1/monitors/schema.ts @@ -20,11 +20,7 @@ const statusAssertion = z description: "The comparison to run", example: "eq", }), - target: z - .number() - .int() - .positive() - .openapi({ description: "The target value" }), + target: z.int().positive().openapi({ description: "The target value" }), }) .openapi({ description: "The status assertion", @@ -94,13 +90,15 @@ export const ParamsSchema = z.object({ }), }); +const PeriodicityEnumHonoSchema = z.enum([...monitorPeriodicitySchema.options]); + export const MonitorSchema = z .object({ id: z.number().openapi({ example: 123, description: "The id of the monitor", }), - periodicity: monitorPeriodicitySchema.openapi({ + periodicity: PeriodicityEnumHonoSchema.openapi({ example: "1m", description: "How often the monitor should run", }), @@ -111,38 +109,35 @@ export const MonitorSchema = z regions: z .preprocess( (val) => { - let regions: Array = []; - if (!val) return regions; + let parsedRegions: Array = []; + if (!val) return parsedRegions; if (Array.isArray(val)) { - regions = val; + parsedRegions = val; } if (String(val).length > 0) { - regions = String(val).split(","); + parsedRegions = String(val).split(","); } - - const deprecatedRegions = regions.filter((r) => { - return !AVAILABLE_REGIONS.includes( - r as (typeof AVAILABLE_REGIONS)[number], - ); - }); - - if (deprecatedRegions.length > 0) { - throw new ZodError([ - { - code: "custom", - path: ["regions"], - message: `Deprecated regions are not allowed: ${deprecatedRegions.join( - ", ", - )}`, - }, - ]); - } - - return regions; + return parsedRegions; }, z.array(z.enum(monitorRegions)), ) - .default([]) + .superRefine((regions, ctx) => { + const deprecatedRegions = regions.filter((r) => { + return !AVAILABLE_REGIONS.includes( + r as (typeof AVAILABLE_REGIONS)[number], + ); + }); + if (deprecatedRegions.length > 0) { + ctx.addIssue({ + code: "custom", + path: ["regions"], + message: `Deprecated regions are not allowed: ${deprecatedRegions.join( + ", ", + )}`, + }); + } + }) + .prefault([]) .openapi({ example: ["ams"], description: "Where we should monitor it", @@ -166,7 +161,7 @@ export const MonitorSchema = z return String(val); }, z.string()) .nullish() - .default("") + .prefault("") .openapi({ example: "Hello World", description: "The body", @@ -190,7 +185,7 @@ export const MonitorSchema = z ]); } }, - z.array(z.object({ key: z.string(), value: z.string() })).default([]), + z.array(z.object({ key: z.string(), value: z.string() })).prefault([]), ) .nullish() .openapi({ @@ -216,47 +211,46 @@ export const MonitorSchema = z } }, z.array(assertion)) .nullish() - .default([]) + .prefault([]) .openapi({ description: "The assertions to run", }), active: z .boolean() - .default(false) + .prefault(false) .openapi({ description: "If the monitor is active" }), public: z .boolean() - .default(false) + .prefault(false) .openapi({ description: "If the monitor is public" }), degradedAfter: z.number().nullish().openapi({ description: "The time after the monitor is considered degraded in milliseconds", }), - timeout: z.number().nullish().default(45000).openapi({ + timeout: z.number().nullish().prefault(45000).openapi({ description: "The timeout of the request in milliseconds", }), - retry: z.number().default(3).openapi({ + retry: z.number().prefault(3).openapi({ description: "The number of retries to attempt", }), - followRedirects: z.boolean().default(true).openapi({ + followRedirects: z.boolean().prefault(true).openapi({ description: "If the monitor should follow redirects", }), - jobType: z.enum(monitorJobTypes).optional().default("http").openapi({ + jobType: z.enum(monitorJobTypes).optional().prefault("http").openapi({ description: "The type of the monitor", }), openTelemetry: z .object({ - endpoint: z - .string() - .url() + endpoint: z.url().optional().prefault("http://localhost:4317").openapi({ + description: "The endpoint of the OpenTelemetry collector", + }), + headers: z + .record(z.string(), z.string()) .optional() - .default("http://localhost:4317") + .prefault({}) .openapi({ - description: "The endpoint of the OpenTelemetry collector", + description: "The headers to send to the OpenTelemetry collector", }), - headers: z.record(z.string()).optional().default({}).openapi({ - description: "The headers to send to the OpenTelemetry collector", - }), }) .optional() .openapi({ @@ -316,13 +310,13 @@ export const TriggerResult = z.discriminatedUnion("jobType", [ ]); export const ResultRun = z.object({ - latency: z.number().int(), // in ms - statusCode: z.number().int().nullable().default(null), - monitorId: z.string().default(""), + latency: z.int(), // in ms + statusCode: z.int().nullable().prefault(null), + monitorId: z.string().prefault(""), url: z.string().optional(), - error: z.coerce.boolean().default(false), + error: z.coerce.boolean().prefault(false), region: z.enum(monitorRegions), - timestamp: z.number().int().optional(), + timestamp: z.int().optional(), message: z.string().nullable().optional(), timing: z .preprocess((val) => { @@ -413,7 +407,7 @@ const baseRequest = z.object({ }, z.array(z.enum(monitorRegions)), ) - .default([]) + .prefault([]) .openapi({ example: ["ams"], description: "Where we should monitor it", @@ -421,7 +415,6 @@ const baseRequest = z.object({ openTelemetry: z .object({ endpoint: z - .string() .url() .optional() .openapi({ @@ -441,13 +434,10 @@ const baseRequest = z.object({ const httpRequestSchema = z.object({ method: z.enum(monitorMethods), - url: z - .string() - .url() - .openapi({ - description: "URL to request", - examples: ["https://openstat.us", "https://www.openstatus.dev"], - }), + url: z.url().openapi({ + description: "URL to request", + examples: ["https://openstat.us", "https://www.openstatus.dev"], + }), headers: z .record(z.string(), z.string()) .optional() diff --git a/apps/server/src/routes/v1/monitors/summary/schema.ts b/apps/server/src/routes/v1/monitors/summary/schema.ts index 129fd025b..edb5f007c 100644 --- a/apps/server/src/routes/v1/monitors/summary/schema.ts +++ b/apps/server/src/routes/v1/monitors/summary/schema.ts @@ -4,14 +4,11 @@ import { ParamsSchema } from "../schema"; export { ParamsSchema }; export const SummarySchema = z.object({ - ok: z.number().int().openapi({ + ok: z.int().openapi({ description: "The number of ok responses (defined by the assertions - or by default status code 200)", }), - count: z - .number() - .int() - .openapi({ description: "The total number of request" }), + count: z.int().openapi({ description: "The total number of request" }), day: z.coerce .date() .openapi({ description: "The date of the daily stat in ISO8601 format" }), diff --git a/apps/server/src/routes/v1/pageSubscribers/schema.ts b/apps/server/src/routes/v1/pageSubscribers/schema.ts index 741094a55..37a108b73 100644 --- a/apps/server/src/routes/v1/pageSubscribers/schema.ts +++ b/apps/server/src/routes/v1/pageSubscribers/schema.ts @@ -20,7 +20,7 @@ export const PageSubscriberSchema = z description: "The id of the subscriber", example: 1, }), - email: z.string().email().openapi({ + email: z.email().openapi({ description: "The email of the subscriber", }), pageId: z.number().openapi({ diff --git a/apps/server/src/routes/v1/pages/schema.ts b/apps/server/src/routes/v1/pages/schema.ts index 39f040f9d..59f5b4fd3 100644 --- a/apps/server/src/routes/v1/pages/schema.ts +++ b/apps/server/src/routes/v1/pages/schema.ts @@ -43,7 +43,6 @@ export const PageSchema = z example: "status.acme.com", }), icon: z - .string() .url() .or(z.literal("")) .transform((val) => (val ? val : undefined)) @@ -52,7 +51,7 @@ export const PageSchema = z description: "The icon of the page", example: "https://example.com/icon.png", }), - passwordProtected: z.boolean().optional().default(false).openapi({ + passwordProtected: z.boolean().optional().prefault(false).openapi({ description: "Make the page password protected. Used with the 'passwordProtected' property.", example: true, @@ -61,7 +60,7 @@ export const PageSchema = z description: "Your password to protect the page from the public", example: "hidden-password", }), - showMonitorValues: z.boolean().optional().nullish().default(true).openapi({ + showMonitorValues: z.boolean().optional().nullish().prefault(true).openapi({ description: "Displays the total and failed request numbers for each monitor", example: true, diff --git a/apps/server/src/routes/v1/statusReportUpdates/schema.ts b/apps/server/src/routes/v1/statusReportUpdates/schema.ts index 3f0f0b8ed..8b012bbbe 100644 --- a/apps/server/src/routes/v1/statusReportUpdates/schema.ts +++ b/apps/server/src/routes/v1/statusReportUpdates/schema.ts @@ -22,7 +22,7 @@ export const StatusReportUpdateSchema = z status: z.enum(statusReportStatus).openapi({ description: "The status of the update", }), - date: z.coerce.date().default(new Date()).openapi({ + date: z.coerce.date().prefault(new Date()).openapi({ description: "The date of the update in ISO8601 format", }), message: z.string().openapi({ diff --git a/apps/server/src/routes/v1/statusReports/post.ts b/apps/server/src/routes/v1/statusReports/post.ts index 3372dd583..0a402b978 100644 --- a/apps/server/src/routes/v1/statusReports/post.ts +++ b/apps/server/src/routes/v1/statusReports/post.ts @@ -32,7 +32,7 @@ const postRoute = createRoute({ id: true, statusReportUpdateIds: true, }).extend({ - date: z.coerce.date().optional().default(new Date()).openapi({ + date: z.coerce.date().optional().prefault(new Date()).openapi({ description: "The date of the report in ISO8601 format, defaults to now", }), diff --git a/apps/server/src/routes/v1/statusReports/schema.ts b/apps/server/src/routes/v1/statusReports/schema.ts index aee598854..a70286e2d 100644 --- a/apps/server/src/routes/v1/statusReports/schema.ts +++ b/apps/server/src/routes/v1/statusReports/schema.ts @@ -30,14 +30,14 @@ export const StatusReportSchema = z .array(z.number()) .optional() .nullable() - .default([]) + .prefault([]) .openapi({ description: "The ids of the status report updates", }), monitorIds: z .array(z.number()) .optional() - .default([]) + .prefault([]) .openapi({ description: "Ids of the monitors the status report." }), pageId: z.number().openapi({ description: "The id of the page this status report belongs to", diff --git a/apps/server/src/routes/v1/whoami/schema.ts b/apps/server/src/routes/v1/whoami/schema.ts index 996b79fcb..9f35fe534 100644 --- a/apps/server/src/routes/v1/whoami/schema.ts +++ b/apps/server/src/routes/v1/whoami/schema.ts @@ -9,7 +9,7 @@ export const WorkspaceSchema = z .optional() .openapi({ description: "The current workspace name" }), slug: z.string().openapi({ description: "The current workspace slug" }), - plan: z.enum(workspacePlans).nullable().default("free").openapi({ + plan: z.enum(workspacePlans).nullable().prefault("free").openapi({ description: "The current workspace plan", }), }) diff --git a/apps/status-page/package.json b/apps/status-page/package.json index f5bf355cd..4f898d0a1 100644 --- a/apps/status-page/package.json +++ b/apps/status-page/package.json @@ -18,7 +18,7 @@ "@dnd-kit/sortable": "10.0.0", "@dnd-kit/utilities": "3.2.2", "@hookform/devtools": "4.4.0", - "@hookform/resolvers": "4.1.3", + "@hookform/resolvers": "5.1.0", "@libsql/client": "0.15.15", "@openpanel/nextjs": "1.0.8", "@openstatus/analytics": "workspace:*", @@ -83,7 +83,7 @@ "superjson": "2.2.2", "tailwind-merge": "3.3.1", "unified": "11.0.5", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/apps/status-page/src/app/(status-page)/[domain]/layout.tsx b/apps/status-page/src/app/(status-page)/[domain]/layout.tsx index 12c20ceea..90c088799 100644 --- a/apps/status-page/src/app/(status-page)/[domain]/layout.tsx +++ b/apps/status-page/src/app/(status-page)/[domain]/layout.tsx @@ -18,10 +18,10 @@ import { notFound } from "next/navigation"; import { z } from "zod"; export const schema = z.object({ - value: z.enum(["duration", "requests", "manual"]).default("duration"), - type: z.enum(["absolute", "manual"]).default("absolute"), - uptime: z.coerce.boolean().default(true), - theme: z.enum(THEME_KEYS as [ThemeKey, ...ThemeKey[]]).default("default"), + value: z.enum(["duration", "requests", "manual"]).prefault("duration"), + type: z.enum(["absolute", "manual"]).prefault("absolute"), + uptime: z.coerce.boolean().prefault(true), + theme: z.enum(THEME_KEYS as [ThemeKey, ...ThemeKey[]]).prefault("default"), }); export default async function Layout({ diff --git a/apps/status-page/src/components/forms/form-subscribe-email.tsx b/apps/status-page/src/components/forms/form-subscribe-email.tsx index e9f5e7fd8..ecbb258f0 100644 --- a/apps/status-page/src/components/forms/form-subscribe-email.tsx +++ b/apps/status-page/src/components/forms/form-subscribe-email.tsx @@ -16,7 +16,7 @@ import { toast } from "sonner"; import { z } from "zod"; const schema = z.object({ - email: z.string().email(), + email: z.email(), }); type FormValues = z.infer; diff --git a/apps/web/next-env.d.ts b/apps/web/next-env.d.ts index c4b7818fb..9edff1c7c 100644 --- a/apps/web/next-env.d.ts +++ b/apps/web/next-env.d.ts @@ -1,6 +1,6 @@ /// /// -import "./.next/dev/types/routes.d.ts"; +import "./.next/types/routes.d.ts"; // NOTE: This file should not be edited // see https://nextjs.org/docs/app/api-reference/config/typescript for more information. diff --git a/apps/web/package.json b/apps/web/package.json index e737da8dd..aecd35e2a 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -14,7 +14,7 @@ "@auth/core": "0.40.0", "@auth/drizzle-adapter": "1.10.0", "@google-cloud/tasks": "4.0.1", - "@hookform/resolvers": "4.1.3", + "@hookform/resolvers": "5.1.0", "@libsql/client": "0.15.15", "@openpanel/nextjs": "1.0.8", "@openstatus/analytics": "workspace:*", @@ -91,7 +91,7 @@ "superjson": "2.2.2", "tailwind-merge": "3.3.1", "tailwindcss-animate": "1.0.7", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/apps/web/src/app/(landing)/status/utils.ts b/apps/web/src/app/(landing)/status/utils.ts index c33c61401..0fc18fee8 100644 --- a/apps/web/src/app/(landing)/status/utils.ts +++ b/apps/web/src/app/(landing)/status/utils.ts @@ -15,12 +15,12 @@ export const externalStatus = z.object({ name: z.string(), url: z.string(), external_id: z.string(), - last_updated_at: z.string().datetime({ offset: true }), + last_updated_at: z.iso.datetime({ offset: true }), time_zone: z.string(), status_indicator: z.string(), status_description: atlassianDescriptionEnum, created_at: z.string(), - updated_at: z.string().datetime(), + updated_at: z.iso.datetime(), }); export const externalStatusArray = z.array(externalStatus); diff --git a/apps/web/src/app/api/checker/cron/_cron.ts b/apps/web/src/app/api/checker/cron/_cron.ts index 4db0fe0f4..19a159530 100644 --- a/apps/web/src/app/api/checker/cron/_cron.ts +++ b/apps/web/src/app/api/checker/cron/_cron.ts @@ -89,7 +89,9 @@ export const cron = async ({ const monitors = z.array(selectMonitorSchema).safeParse(result); const allResult = []; if (!monitors.success) { - console.error(`Error while fetching the monitors ${monitors.error.errors}`); + console.error( + `Error while fetching the monitors ${monitors.error.issues.map((issue) => issue.message).join(", ")}`, + ); throw new Error("Error while fetching the monitors"); } @@ -104,7 +106,7 @@ export const cron = async ({ const monitorStatus = z.array(selectMonitorStatusSchema).safeParse(result); if (!monitorStatus.success) { console.error( - `Error while fetching the monitor status ${monitorStatus.error.errors}`, + `Error while fetching the monitor status ${monitorStatus.error.issues.map((issue) => issue.message).join(", ")}`, ); continue; } diff --git a/apps/web/src/app/api/checker/test/http/route.ts b/apps/web/src/app/api/checker/test/http/route.ts index 85c596b2e..15f20ed65 100644 --- a/apps/web/src/app/api/checker/test/http/route.ts +++ b/apps/web/src/app/api/checker/test/http/route.ts @@ -21,7 +21,7 @@ export async function POST(request: Request) { const json = await request.json(); const _valid = httpPayloadSchema .pick({ url: true, method: true, headers: true, body: true }) - .merge(z.object({ region: monitorRegionSchema.default("ams") })) + .extend(z.object({ region: monitorRegionSchema.prefault("ams") }).shape) .safeParse(json); if (!_valid.success) { diff --git a/apps/web/src/app/api/checker/test/tcp/route.ts b/apps/web/src/app/api/checker/test/tcp/route.ts index b10a06c0a..6181b2766 100644 --- a/apps/web/src/app/api/checker/test/tcp/route.ts +++ b/apps/web/src/app/api/checker/test/tcp/route.ts @@ -22,7 +22,7 @@ export async function POST(request: Request) { const json = await request.json(); const _valid = tcpPayload .pick({ url: true }) - .merge(z.object({ region: monitorRegionSchema.default("ams") })) + .extend(z.object({ region: monitorRegionSchema.prefault("ams") }).shape) .safeParse(json); if (!_valid.success) { diff --git a/apps/web/src/app/api/checker/test/tcp/schema.ts b/apps/web/src/app/api/checker/test/tcp/schema.ts index c5b2a30d2..673d1a2ec 100644 --- a/apps/web/src/app/api/checker/test/tcp/schema.ts +++ b/apps/web/src/app/api/checker/test/tcp/schema.ts @@ -7,12 +7,12 @@ export const tcpPayload = z.object({ monitorId: z.string(), url: z.string(), cronTimestamp: z.number(), - timeout: z.number().default(45000), + timeout: z.number().prefault(45000), degradedAfter: z.number().nullable(), }); export const TCPResponse = z.object({ - type: z.literal("tcp").default("tcp"), + type: z.literal("tcp").prefault("tcp"), requestId: z.number().optional(), workspaceId: z.number().optional(), monitorId: z.number().optional(), @@ -27,11 +27,11 @@ export const TCPResponse = z.object({ }); export const TCPResponseTest = TCPResponse.extend({ - state: z.literal("success").default("success"), + state: z.literal("success").prefault("success"), }).or( z.object({ - type: z.literal("tcp").default("tcp"), - state: z.literal("error").default("error"), + type: z.literal("tcp").prefault("tcp"), + state: z.literal("error").prefault("error"), }), ); export type tcpPayload = z.infer; diff --git a/apps/web/src/components/ping-response-analysis/utils.ts b/apps/web/src/components/ping-response-analysis/utils.ts index fa5b5bd35..63e372402 100644 --- a/apps/web/src/components/ping-response-analysis/utils.ts +++ b/apps/web/src/components/ping-response-analysis/utils.ts @@ -100,11 +100,11 @@ export const timingSchema = z.object({ }); export const checkerSchema = z.object({ - type: z.literal("http").default("http"), - state: z.literal("success").default("success"), + type: z.literal("http").prefault("http"), + state: z.literal("success").prefault("success"), status: z.number(), latency: z.number(), - headers: z.record(z.string()), + headers: z.record(z.string(), z.string()), timestamp: z.number(), timing: timingSchema, body: z.string().optional().nullable(), @@ -113,18 +113,18 @@ export const checkerSchema = z.object({ export const cachedCheckerSchema = z.object({ url: z.string(), timestamp: z.number(), - method: z.enum(["GET", "POST", "PUT", "DELETE"]).default("GET"), + method: z.enum(["GET", "POST", "PUT", "DELETE"]).prefault("GET"), checks: checkerSchema.extend({ region: monitorRegionSchema }).array(), }); const errorRequest = z.object({ message: z.string(), - state: z.literal("error").default("error"), + state: z.literal("error").prefault("error"), }); export const regionCheckerSchema = checkerSchema.extend({ region: monitorRegionSchema, - state: z.literal("success").default("success"), + state: z.literal("success").prefault("success"), }); export const regionCheckerSchemaResponse = regionCheckerSchema.or( diff --git a/apps/web/src/env.ts b/apps/web/src/env.ts index b986456af..2e3e75fe8 100644 --- a/apps/web/src/env.ts +++ b/apps/web/src/env.ts @@ -19,7 +19,7 @@ export const env = createEnv({ GCP_CLIENT_EMAIL: z.string(), GCP_PRIVATE_KEY: z.string(), CRON_SECRET: z.string(), - EXTERNAL_API_URL: z.string().url(), + EXTERNAL_API_URL: z.url(), CLICKHOUSE_URL: z.string(), CLICKHOUSE_USERNAME: z.string(), CLICKHOUSE_PASSWORD: z.string(), diff --git a/apps/web/src/lib/preferred-settings/validation.ts b/apps/web/src/lib/preferred-settings/validation.ts index 341ca0fc6..899f073ce 100644 --- a/apps/web/src/lib/preferred-settings/validation.ts +++ b/apps/web/src/lib/preferred-settings/validation.ts @@ -2,7 +2,7 @@ import { z } from "zod"; export const preferencesSchema = z .object({ - combinedRegions: z.boolean().nullable().default(false).optional(), + combinedRegions: z.boolean().nullable().prefault(false).optional(), // ... other settings to store user preferences // accessible via document.cookie in the client and cookies() on the server }) diff --git a/apps/workflows/package.json b/apps/workflows/package.json index 53f5e4d7d..4bb060fdf 100644 --- a/apps/workflows/package.json +++ b/apps/workflows/package.json @@ -33,7 +33,7 @@ "effect": "3.19.12", "hono": "4.5.3", "limiter": "^3.0.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/apps/workflows/src/env.ts b/apps/workflows/src/env.ts index 160b68aca..ff0acccaf 100644 --- a/apps/workflows/src/env.ts +++ b/apps/workflows/src/env.ts @@ -3,22 +3,22 @@ import { z } from "zod"; export const env = () => z .object({ - NODE_ENV: z.string().default("development"), - PORT: z.coerce.number().default(3000), - GCP_PROJECT_ID: z.string().default(""), - GCP_CLIENT_EMAIL: z.string().default(""), - GCP_PRIVATE_KEY: z.string().default(""), - GCP_LOCATION: z.string().default("europe-west1"), - CRON_SECRET: z.string().default(""), - SITE_URL: z.string().default("http://localhost:3000"), - DATABASE_URL: z.string().default("http://localhost:8080"), - DATABASE_AUTH_TOKEN: z.string().default(""), - RESEND_API_KEY: z.string().default(""), - TINY_BIRD_API_KEY: z.string().default(""), - QSTASH_TOKEN: z.string().default(""), - SCREENSHOT_SERVICE_URL: z.string().default(""), - TWILLIO_AUTH_TOKEN: z.string().default(""), - TWILLIO_ACCOUNT_ID: z.string().default(""), - SENTRY_DSN: z.string().default(""), + NODE_ENV: z.string().prefault("development"), + PORT: z.coerce.number().prefault(3000), + GCP_PROJECT_ID: z.string().prefault(""), + GCP_CLIENT_EMAIL: z.string().prefault(""), + GCP_PRIVATE_KEY: z.string().prefault(""), + GCP_LOCATION: z.string().prefault("europe-west1"), + CRON_SECRET: z.string().prefault(""), + SITE_URL: z.string().prefault("http://localhost:3000"), + DATABASE_URL: z.string().prefault("http://localhost:8080"), + DATABASE_AUTH_TOKEN: z.string().prefault(""), + RESEND_API_KEY: z.string().prefault(""), + TINY_BIRD_API_KEY: z.string().prefault(""), + QSTASH_TOKEN: z.string().prefault(""), + SCREENSHOT_SERVICE_URL: z.string().prefault(""), + TWILLIO_AUTH_TOKEN: z.string().prefault(""), + TWILLIO_ACCOUNT_ID: z.string().prefault(""), + SENTRY_DSN: z.string().prefault(""), }) .parse(process.env); diff --git a/packages/analytics/env.ts b/packages/analytics/env.ts index 9d030817e..a0b3c82f3 100644 --- a/packages/analytics/env.ts +++ b/packages/analytics/env.ts @@ -1,5 +1,5 @@ import { createEnv } from "@t3-oss/env-core"; -import { z } from "zod/v4"; +import { z } from "zod"; export const env = createEnv({ server: { @@ -9,10 +9,10 @@ export const env = createEnv({ NEXT_PUBLIC_OPENPANEL_CLIENT_ID: z.string(), }, clientPrefix: "NEXT_PUBLIC_", - - runtimeEnv: process.env, - + runtimeEnv: { + OPENPANEL_CLIENT_SECRET: process.env.OPENPANEL_CLIENT_SECRET, + NEXT_PUBLIC_OPENPANEL_CLIENT_ID: + process.env.NEXT_PUBLIC_OPENPANEL_CLIENT_ID, + }, skipValidation: true, - - // runtimeEnv: process.env, }); diff --git a/packages/analytics/tsconfig.json b/packages/analytics/tsconfig.json index 6db9cd3c3..7f4d9b728 100644 --- a/packages/analytics/tsconfig.json +++ b/packages/analytics/tsconfig.json @@ -3,8 +3,20 @@ "extends": "@openstatus/tsconfig/base.json", "exclude": ["dist", "node_modules"], "compilerOptions": { - "module": "nodenext", - "moduleResolution": "nodenext" + "outDir": "dist", + "target": "es2021", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "checkJs": true, + "skipLibCheck": true, + "strict": true, + "forceConsistentCasingInFileNames": true, + "noEmit": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "noUncheckedIndexedAccess": true }, "include": ["**/*.ts", "env.ts"] } diff --git a/packages/api/package.json b/packages/api/package.json index cc364a49e..21a9516e8 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -32,7 +32,7 @@ "random-word-slugs": "0.1.7", "stripe": "13.8.0", "superjson": "2.2.2", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/api/src/router/checker.ts b/packages/api/src/router/checker.ts index e67c16ccc..1f20ba22c 100644 --- a/packages/api/src/router/checker.ts +++ b/packages/api/src/router/checker.ts @@ -26,7 +26,7 @@ const ABORT_TIMEOUT = 10000; // Input schemas const httpTestInput = z.object({ - url: z.string().url(), + url: z.url(), method: z .enum([ "GET", @@ -39,10 +39,10 @@ const httpTestInput = z.object({ "CONNECT", "TRACE", ]) - .default("GET"), + .prefault("GET"), headers: z.array(z.object({ key: z.string(), value: z.string() })).optional(), body: z.string().optional(), - region: monitorRegionSchema.optional().default("ams"), + region: monitorRegionSchema.optional().prefault("ams"), assertions: z .array( z.discriminatedUnion("type", [ @@ -53,17 +53,17 @@ const httpTestInput = z.object({ recordAssertion, ]), ) - .default([]), + .prefault([]), }); const tcpTestInput = z.object({ url: z.string(), - region: monitorRegionSchema.optional().default("ams"), + region: monitorRegionSchema.optional().prefault("ams"), }); const dnsTestInput = z.object({ url: z.string(), - region: monitorRegionSchema.optional().default("ams"), + region: monitorRegionSchema.optional().prefault("ams"), assertions: z .array( z.discriminatedUnion("type", [ @@ -74,13 +74,13 @@ const dnsTestInput = z.object({ jsonBodyAssertion, ]), ) - .default([]), + .prefault([]), }); export const tcpOutput = z .object({ - state: z.literal("success").default("success"), - type: z.literal("tcp").default("tcp"), + state: z.literal("success").prefault("success"), + type: z.literal("tcp").prefault("tcp"), requestId: z.number().optional(), workspaceId: z.number().optional(), monitorId: z.number().optional(), @@ -95,18 +95,18 @@ export const tcpOutput = z }) .or( z.object({ - state: z.literal("error").default("error"), + state: z.literal("error").prefault("error"), message: z.string(), }), ); export const httpOutput = z .object({ - state: z.literal("success").default("success"), - type: z.literal("http").default("http"), + state: z.literal("success").prefault("success"), + type: z.literal("http").prefault("http"), status: z.number(), latency: z.number(), - headers: z.record(z.string()), + headers: z.record(z.string(), z.string()), timestamp: z.number(), timing: z.object({ dnsStart: z.number(), @@ -125,23 +125,25 @@ export const httpOutput = z }) .or( z.object({ - state: z.literal("error").default("error"), + state: z.literal("error").prefault("error"), message: z.string(), }), ); export const dnsOutput = z .object({ - state: z.literal("success").default("success"), - type: z.literal("dns").default("dns"), - records: z.record(z.enum(dnsRecords), z.array(z.string())).default({}), + state: z.literal("success").prefault("success"), + type: z.literal("dns").prefault("dns"), + records: z + .partialRecord(z.enum(dnsRecords), z.array(z.string())) + .prefault({}), latency: z.number().optional(), timestamp: z.number(), region: monitorRegionSchema, }) .or( z.object({ - state: z.literal("error").default("error"), + state: z.literal("error").prefault("error"), message: z.string(), }), ); diff --git a/packages/api/src/router/domain.ts b/packages/api/src/router/domain.ts index 29c29acb5..526e660a8 100644 --- a/packages/api/src/router/domain.ts +++ b/packages/api/src/router/domain.ts @@ -13,7 +13,7 @@ export const domainConfigResponseSchema = z.object({ .array(z.union([z.literal("dns-01"), z.literal("http-01")])) .optional() .nullable(), - misconfigured: z.boolean().default(true).optional(), + misconfigured: z.boolean().prefault(true).optional(), }); export const domainResponseSchema = z.object({ diff --git a/packages/api/src/router/feedback.ts b/packages/api/src/router/feedback.ts index a76e60cb6..3d2e2bd84 100644 --- a/packages/api/src/router/feedback.ts +++ b/packages/api/src/router/feedback.ts @@ -13,7 +13,7 @@ export const feedbackRouter = createTRPCRouter({ isMobile: z.boolean().optional(), // NOTE: coming from ContactForm name: z.string().optional(), - email: z.string().email().optional(), + email: z.email().optional(), blocker: z.boolean().optional(), type: z.string().optional(), }), diff --git a/packages/api/src/router/monitor.ts b/packages/api/src/router/monitor.ts index 676851e56..842e889df 100644 --- a/packages/api/src/router/monitor.ts +++ b/packages/api/src/router/monitor.ts @@ -218,7 +218,7 @@ export const monitorRouter = createTRPCRouter({ monitorTag: selectMonitorTagSchema, }) .array(), - maintenance: z.boolean().default(false).optional(), + maintenance: z.boolean().prefault(false).optional(), monitorsToNotifications: z .object({ notification: selectNotificationSchema, @@ -659,7 +659,7 @@ export const monitorRouter = createTRPCRouter({ selectMonitorSchema.extend({ monitorTagsToMonitors: z .array(z.object({ monitorTag: selectMonitorTagSchema })) - .default([]), + .prefault([]), }), ) .parse(monitors); @@ -695,7 +695,7 @@ export const monitorRouter = createTRPCRouter({ selectMonitorSchema.extend({ monitorTagsToMonitors: z .array(z.object({ monitorTag: selectMonitorTagSchema })) - .default([]), + .prefault([]), }), ) .parse( @@ -853,8 +853,8 @@ export const monitorRouter = createTRPCRouter({ return z .array( selectMonitorSchema.extend({ - tags: z.array(selectMonitorTagSchema).default([]), - incidents: z.array(selectIncidentSchema).default([]), + tags: z.array(selectMonitorTagSchema).prefault([]), + incidents: z.array(selectIncidentSchema).prefault([]), }), ) .parse( @@ -900,12 +900,12 @@ export const monitorRouter = createTRPCRouter({ return selectMonitorSchema .extend({ - notifications: z.array(selectNotificationSchema).default([]), - pages: z.array(selectPageSchema).default([]), - tags: z.array(selectMonitorTagSchema).default([]), - maintenances: z.array(selectMaintenanceSchema).default([]), - incidents: z.array(selectIncidentSchema).default([]), - privateLocations: z.array(selectPrivateLocationSchema).default([]), + notifications: z.array(selectNotificationSchema).prefault([]), + pages: z.array(selectPageSchema).prefault([]), + tags: z.array(selectMonitorTagSchema).prefault([]), + maintenances: z.array(selectMaintenanceSchema).prefault([]), + incidents: z.array(selectIncidentSchema).prefault([]), + privateLocations: z.array(selectPrivateLocationSchema).prefault([]), }) .parse({ ...data, @@ -1140,7 +1140,7 @@ export const monitorRouter = createTRPCRouter({ z.object({ id: z.number(), timeout: z.number(), - degradedAfter: z.number().optional(), + degradedAfter: z.number().nullish(), }), ) .mutation(async ({ ctx, input }) => { @@ -1292,11 +1292,11 @@ export const monitorRouter = createTRPCRouter({ recordAssertion, ]), ), - active: z.boolean().default(true), + active: z.boolean().prefault(true), // skip the test check if assertions are OK - skipCheck: z.boolean().default(true), + skipCheck: z.boolean().prefault(true), // save check in db (iff success? -> e.g. onboarding to get a first ping) - saveCheck: z.boolean().default(false), + saveCheck: z.boolean().prefault(false), }), ) .mutation(async ({ ctx, input }) => { @@ -1418,9 +1418,9 @@ export const monitorRouter = createTRPCRouter({ recordAssertion, ]), ), - active: z.boolean().default(false), - saveCheck: z.boolean().default(false), - skipCheck: z.boolean().default(false), + active: z.boolean().prefault(false), + saveCheck: z.boolean().prefault(false), + skipCheck: z.boolean().prefault(false), }), ) .mutation(async ({ ctx, input }) => { diff --git a/packages/api/src/router/notification.ts b/packages/api/src/router/notification.ts index f117166e1..22882b0e3 100644 --- a/packages/api/src/router/notification.ts +++ b/packages/api/src/router/notification.ts @@ -281,7 +281,7 @@ export const notificationRouter = createTRPCRouter({ z.object({ id: z.number(), name: z.string(), - data: z.record( + data: z.partialRecord( z.enum(notificationProvider), z.string().or(z.record(z.string(), z.string())), ), @@ -350,12 +350,12 @@ export const notificationRouter = createTRPCRouter({ .input( z.object({ provider: z.enum(notificationProvider), - data: z.record( + data: z.partialRecord( z.enum(notificationProvider), z.record(z.string(), z.string()).or(z.string()), ), name: z.string(), - monitors: z.array(z.number()).default([]), + monitors: z.array(z.number()).prefault([]), }), ) .mutation(async (opts) => { @@ -460,7 +460,7 @@ export const notificationRouter = createTRPCRouter({ .input( z.object({ provider: z.enum(notificationProvider), - data: z.record( + data: z.partialRecord( z.enum(notificationProvider), z.record(z.string(), z.string()).or(z.string()), ), diff --git a/packages/api/src/router/page.ts b/packages/api/src/router/page.ts index faace3be4..94ae85ec6 100644 --- a/packages/api/src/router/page.ts +++ b/packages/api/src/router/page.ts @@ -32,7 +32,6 @@ import { } from "@openstatus/db/src/schema"; import { Events } from "@openstatus/analytics"; -import { Redis } from "@openstatus/upstash"; import { env } from "../env"; import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc"; @@ -40,8 +39,6 @@ if (process.env.NODE_ENV === "test") { require("../test/preload"); } -const _redis = Redis.fromEnv(); - // Helper functions to reuse Vercel API logic async function addDomainToVercel(domain: string) { const data = await fetch( @@ -502,14 +499,14 @@ export const pageRouter = createTRPCRouter({ monitors: z .array( selectMonitorSchema.extend({ - order: z.number().default(0), - groupOrder: z.number().default(0), + order: z.number().prefault(0), + groupOrder: z.number().prefault(0), groupId: z.number().nullable(), }), ) - .default([]), - monitorGroups: z.array(selectMonitorGroupSchema).default([]), - maintenances: z.array(selectMaintenanceSchema).default([]), + .prefault([]), + monitorGroups: z.array(selectMonitorGroupSchema).prefault([]), + maintenances: z.array(selectMaintenanceSchema).prefault([]), }) .parse({ ...data, diff --git a/packages/api/src/router/statusPage.ts b/packages/api/src/router/statusPage.ts index f6f4a4fa1..3be9e87e3 100644 --- a/packages/api/src/router/statusPage.ts +++ b/packages/api/src/router/statusPage.ts @@ -357,8 +357,10 @@ export const statusPageRouter = createTRPCRouter({ monitorIds: z.string().array(), cardType: z .enum(["requests", "duration", "dominant", "manual"]) - .default("requests"), - barType: z.enum(["absolute", "dominant", "manual"]).default("dominant"), + .prefault("requests"), + barType: z + .enum(["absolute", "dominant", "manual"]) + .prefault("dominant"), }), ) .query(async (opts) => { @@ -832,9 +834,7 @@ export const statusPageRouter = createTRPCRouter({ subscribe: publicProcedure .meta({ track: Events.SubscribePage, trackProps: ["slug", "email"] }) - .input( - z.object({ slug: z.string().toLowerCase(), email: z.string().email() }), - ) + .input(z.object({ slug: z.string().toLowerCase(), email: z.email() })) .mutation(async (opts) => { if (!opts.input.slug) return null; diff --git a/packages/api/src/router/statusReport.ts b/packages/api/src/router/statusReport.ts index 1d4558f2e..952df7f10 100644 --- a/packages/api/src/router/statusReport.ts +++ b/packages/api/src/router/statusReport.ts @@ -227,7 +227,7 @@ export const statusReportRouter = createTRPCRouter({ .query(async (opts) => { const selectPublicStatusReportSchemaWithRelation = selectStatusReportSchema.extend({ - status: statusReportStatusSchema.default("investigating"), // TODO: remove! + status: statusReportStatusSchema.prefault("investigating"), // TODO: remove! monitorsToStatusReports: z .array( z.object({ @@ -236,9 +236,9 @@ export const statusReportRouter = createTRPCRouter({ monitor: selectMonitorSchema, }), ) - .default([]), + .prefault([]), statusReportUpdates: z.array(selectStatusReportUpdateSchema), - date: z.date().default(new Date()), + date: z.date().prefault(new Date()), }); const data = await opts.ctx.db.query.statusReport.findFirst({ @@ -275,7 +275,7 @@ export const statusReportRouter = createTRPCRouter({ getStatusReportByWorkspace: protectedProcedure.query(async (opts) => { // FIXME: can we get rid of that? const selectStatusSchemaWithRelation = selectStatusReportSchema.extend({ - status: statusReportStatusSchema.default("investigating"), // TODO: remove! + status: statusReportStatusSchema.prefault("investigating"), // TODO: remove! monitorsToStatusReports: z .array( z.object({ @@ -284,7 +284,7 @@ export const statusReportRouter = createTRPCRouter({ monitor: selectMonitorSchema, }), ) - .default([]), + .prefault([]), statusReportUpdates: z.array(selectStatusReportUpdateSchema), }); @@ -308,7 +308,7 @@ export const statusReportRouter = createTRPCRouter({ .query(async (opts) => { // FIXME: can we get rid of that? const selectStatusSchemaWithRelation = selectStatusReportSchema.extend({ - status: statusReportStatusSchema.default("investigating"), // TODO: remove! + status: statusReportStatusSchema.prefault("investigating"), // TODO: remove! monitorsToStatusReports: z .array( z.object({ @@ -317,7 +317,7 @@ export const statusReportRouter = createTRPCRouter({ monitor: selectMonitorSchema, }), ) - .default([]), + .prefault([]), statusReportUpdates: z.array(selectStatusReportUpdateSchema), }); @@ -412,8 +412,8 @@ export const statusReportRouter = createTRPCRouter({ return selectStatusReportSchema .extend({ - updates: z.array(selectStatusReportUpdateSchema).default([]), - monitors: z.array(selectMonitorSchema).default([]), + updates: z.array(selectStatusReportUpdateSchema).prefault([]), + monitors: z.array(selectMonitorSchema).prefault([]), page: selectPageSchema, }) .array() diff --git a/packages/api/src/router/stripe/webhook.ts b/packages/api/src/router/stripe/webhook.ts index d5b624652..16a99313b 100644 --- a/packages/api/src/router/stripe/webhook.ts +++ b/packages/api/src/router/stripe/webhook.ts @@ -19,7 +19,7 @@ const webhookProcedure = publicProcedure.input( account: z.string().nullish(), created: z.number(), data: z.object({ - object: z.record(z.any()), + object: z.record(z.string(), z.any()), }), type: z.string(), }), diff --git a/packages/api/src/router/tinybird/index.ts b/packages/api/src/router/tinybird/index.ts index eec6343cc..1d7300903 100644 --- a/packages/api/src/router/tinybird/index.ts +++ b/packages/api/src/router/tinybird/index.ts @@ -226,7 +226,7 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ monitorId: z.string(), region: z.enum(monitorRegions).or(z.string()).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), }), ) .query(async (opts) => { @@ -239,7 +239,7 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ monitorId: z.string(), region: z.enum(monitorRegions).or(z.string()).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), from: z.coerce.date().optional(), to: z.coerce.date().optional(), }), @@ -280,10 +280,10 @@ export const tinybirdRouter = createTRPCRouter({ monitorId: z.string(), fromDate: z.string().optional(), toDate: z.string().optional(), - interval: z.number().int().optional(), // in minutes, default 30 + interval: z.int().optional(), // in minutes, default 30 regions: z.enum(monitorRegions).or(z.string()).array().optional(), - type: z.enum(types).default("http"), - period: z.enum(["7d", "30d"]).default("30d"), + type: z.enum(types).prefault("http"), + period: z.enum(["7d", "30d"]).prefault("30d"), }), ) .query(async (opts) => { @@ -311,7 +311,7 @@ export const tinybirdRouter = createTRPCRouter({ .input( z.object({ monitorId: z.string(), - interval: z.number().int().default(30), // in days + interval: z.int().prefault(30), // in days }), ) .query(async (opts) => { @@ -342,9 +342,9 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ monitorId: z.string(), period: z.enum(periods), - type: z.enum(types).default("http"), + type: z.enum(types).prefault("http"), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), }), ) .query(async (opts) => { @@ -377,9 +377,9 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ monitorId: z.string(), period: z.enum(periods), - type: z.enum(types).default("http"), + type: z.enum(types).prefault("http"), region: z.enum(monitorRegions).or(z.string()).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), }), ) .query(async (opts) => { @@ -411,9 +411,9 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ monitorId: z.string(), period: z.enum(periods), - type: z.enum(types).default("http"), + type: z.enum(types).prefault("http"), region: z.enum(monitorRegions).or(z.string()).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), }), ) .query(async (opts) => { @@ -445,11 +445,11 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ monitorId: z.string(), period: z.enum(periods), - type: z.enum(types).default("http"), + type: z.enum(types).prefault("http"), // Additional filters - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), fromDate: z.string().optional(), toDate: z.string().optional(), }), @@ -487,9 +487,9 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ monitorIds: z.string().array(), period: z.enum(["45d"]), - type: z.enum(types).default("http"), + type: z.enum(types).prefault("http"), region: z.enum(monitorRegions).or(z.string()).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), }), ) .query(async (opts) => { @@ -518,7 +518,7 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ id: z.string().nullable(), monitorId: z.string(), - period: z.enum(["14d"]).default("14d"), + period: z.enum(["14d"]).prefault("14d"), }), ) .query(async (opts) => { @@ -549,7 +549,7 @@ export const tinybirdRouter = createTRPCRouter({ .input( z.object({ monitorIds: z.string().array(), - type: z.enum(types).default("http"), + type: z.enum(types).prefault("http"), }), ) .query(async (opts) => { @@ -579,7 +579,7 @@ export const tinybirdRouter = createTRPCRouter({ monitorId: z.string(), period: z.enum(periods), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - type: z.enum(types).default("http"), + type: z.enum(types).prefault("http"), fromDate: z.string().optional(), toDate: z.string().optional(), }), @@ -601,7 +601,7 @@ export const tinybirdRouter = createTRPCRouter({ z.object({ monitorId: z.string(), period: z.enum(periods), - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), type: z.literal("http"), }), @@ -627,8 +627,8 @@ export const tinybirdRouter = createTRPCRouter({ .input( z.object({ monitorIds: z.string().array(), - period: z.enum(["1d"]).default("1d"), - type: z.enum(types).default("http"), + period: z.enum(["1d"]).prefault("1d"), + type: z.enum(types).prefault("http"), }), ) .query(async (opts) => { @@ -642,7 +642,7 @@ export const tinybirdRouter = createTRPCRouter({ workspace30d: protectedProcedure .input( z.object({ - type: z.enum(types).default("http"), + type: z.enum(types).prefault("http"), }), ) .query(async (opts) => { diff --git a/packages/api/src/trpc.ts b/packages/api/src/trpc.ts index 7fa97090b..cc469f74c 100644 --- a/packages/api/src/trpc.ts +++ b/packages/api/src/trpc.ts @@ -1,7 +1,7 @@ import { TRPCError, initTRPC } from "@trpc/server"; import { type NextRequest, after } from "next/server"; import superjson from "superjson"; -import { ZodError } from "zod"; +import { ZodError, treeifyError } from "zod"; import { type EventProps, @@ -106,7 +106,7 @@ export const t = initTRPC data: { ...shape.data, zodError: - error.cause instanceof ZodError ? error.cause.flatten() : null, + error.cause instanceof ZodError ? treeifyError(error.cause) : null, }, }; }, diff --git a/packages/assertions/package.json b/packages/assertions/package.json index cce09ec2c..c1fd30bbb 100644 --- a/packages/assertions/package.json +++ b/packages/assertions/package.json @@ -10,7 +10,7 @@ "devDependencies": { "@openstatus/tsconfig": "workspace:*", "typescript": "5.9.3", - "zod": "3.25.76" + "zod": "4.1.13" }, "keywords": [], "author": "", diff --git a/packages/assertions/src/v1.ts b/packages/assertions/src/v1.ts index 77df107a6..0b7ea37d7 100644 --- a/packages/assertions/src/v1.ts +++ b/packages/assertions/src/v1.ts @@ -211,55 +211,53 @@ function evaluateRecord( return { success: true }; } -export const base = z - .object({ - version: z.enum(["v1"]).default("v1"), - type: z.string(), - }) - .passthrough(); -export const statusAssertion = base.merge( +export const base = z.looseObject({ + version: z.enum(["v1"]).prefault("v1"), + type: z.string(), +}); +export const statusAssertion = base.extend( z.object({ type: z.literal("status"), compare: numberCompare, - target: z.number().int().positive(), - }), + target: z.int().positive(), + }).shape, ); -export const headerAssertion = base.merge( +export const headerAssertion = base.extend( z.object({ type: z.literal("header"), compare: stringCompare, key: z.string(), target: z.string(), - }), + }).shape, ); -export const textBodyAssertion = base.merge( +export const textBodyAssertion = base.extend( z.object({ type: z.literal("textBody"), compare: stringCompare, target: z.string(), - }), + }).shape, ); -export const jsonBodyAssertion = base.merge( +export const jsonBodyAssertion = base.extend( z.object({ type: z.literal("jsonBody"), path: z.string(), // https://www.npmjs.com/package/jsonpath-plus compare: stringCompare, target: z.string(), - }), + }).shape, ); export const dnsRecords = ["A", "AAAA", "CNAME", "MX", "TXT", "NS"] as const; -export const recordAssertion = base.merge( +export const recordAssertion = base.extend( z.object({ type: z.literal("dnsRecord"), key: z.enum(dnsRecords), compare: recordCompare, target: z.string(), - }), + }).shape, ); export const assertion = z.discriminatedUnion("type", [ diff --git a/packages/db/env.mjs b/packages/db/env.mjs index 9d41071aa..2c6f37283 100644 --- a/packages/db/env.mjs +++ b/packages/db/env.mjs @@ -1,5 +1,5 @@ import { createEnv } from "@t3-oss/env-core"; -import { z } from "zod/v3"; +import { z } from "zod"; export const env = createEnv({ server: { diff --git a/packages/db/package.json b/packages/db/package.json index 5f5b9dbf5..d637c64dd 100644 --- a/packages/db/package.json +++ b/packages/db/package.json @@ -19,8 +19,8 @@ "@openstatus/theme-store": "workspace:*", "@t3-oss/env-core": "0.13.10", "drizzle-orm": "0.44.4", - "drizzle-zod": "0.5.1", - "zod": "3.25.76" + "drizzle-zod": "0.8.3", + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/db/src/schema/invitations/validation.ts b/packages/db/src/schema/invitations/validation.ts index 340f00173..e081a2285 100644 --- a/packages/db/src/schema/invitations/validation.ts +++ b/packages/db/src/schema/invitations/validation.ts @@ -4,7 +4,7 @@ import { z } from "zod"; import { invitation } from "./invitation"; export const insertInvitationSchema = createInsertSchema(invitation, { - email: z.string().email(), + email: z.email(), }); export const selectInvitationSchema = createSelectSchema(invitation); diff --git a/packages/db/src/schema/maintenances/validation.ts b/packages/db/src/schema/maintenances/validation.ts index c0db1674d..40f1084bb 100644 --- a/packages/db/src/schema/maintenances/validation.ts +++ b/packages/db/src/schema/maintenances/validation.ts @@ -5,19 +5,23 @@ import { maintenance } from "./maintenance"; export const insertMaintenanceSchema = createInsertSchema(maintenance) .extend({ // REMINDER: trick to make the react-hook-form controlled but not allow empty string - title: z.string().min(1, { message: "Required" }), - message: z.string().min(1, { message: "Required" }), + title: z.string().min(1, { + error: "Required", + }), + message: z.string().min(1, { + error: "Required", + }), - monitors: z.number().array().default([]).optional(), + monitors: z.number().array().prefault([]).optional(), }) // REMINDER: validate that `from` date is before `to` date .refine((data) => data.from < data.to, { path: ["to"], - message: "End date cannot be earlier than start date.", + error: "End date cannot be earlier than start date.", }); export const selectMaintenanceSchema = createSelectSchema(maintenance).extend({ - monitors: z.number().array().default([]).optional(), + monitors: z.number().array().prefault([]).optional(), }); export type InsertMaintenance = z.infer; diff --git a/packages/db/src/schema/monitors/validation.ts b/packages/db/src/schema/monitors/validation.ts index e888e4f8d..af147ab0f 100644 --- a/packages/db/src/schema/monitors/validation.ts +++ b/packages/db/src/schema/monitors/validation.ts @@ -37,23 +37,23 @@ const headersToArraySchema = z.preprocess( } return []; }, - z.array(z.object({ key: z.string(), value: z.string() })).default([]), + z.array(z.object({ key: z.string(), value: z.string() })).prefault([]), ); export const selectMonitorSchema = createSelectSchema(monitor, { - periodicity: monitorPeriodicitySchema.default("10m"), - status: monitorStatusSchema.default("active"), - jobType: monitorJobTypesSchema.default("http"), - timeout: z.number().default(45), - followRedirects: z.boolean().default(true), - retry: z.number().default(3), - regions: regionsToArraySchema.default([]), + periodicity: monitorPeriodicitySchema.prefault("10m"), + status: monitorStatusSchema.prefault("active"), + jobType: monitorJobTypesSchema.prefault("http"), + timeout: z.number().prefault(45), + followRedirects: z.boolean().prefault(true), + retry: z.number().prefault(3), + regions: regionsToArraySchema.prefault([]), }).extend({ - headers: headersToArraySchema.default([]), - otelHeaders: headersToArraySchema.default([]), - body: bodyToStringSchema.default(""), + headers: headersToArraySchema.prefault([]), + otelHeaders: headersToArraySchema.prefault([]), + body: bodyToStringSchema.prefault(""), // for tcp monitors the method is not needed - method: monitorMethodsSchema.default("GET"), + method: monitorMethodsSchema.prefault("GET"), }); const headersSchema = z @@ -65,21 +65,21 @@ export const insertMonitorSchema = createInsertSchema(monitor, { .string() .min(1, "Name must be at least 1 character long") .max(255, "Name must be at most 255 characters long"), - periodicity: monitorPeriodicitySchema.default("10m"), - status: monitorStatusSchema.default("active"), - regions: z.array(monitorRegionSchema).default([]).optional(), - headers: headersSchema.default([]), - otelHeaders: headersSchema.default([]), + periodicity: monitorPeriodicitySchema.prefault("10m"), + status: monitorStatusSchema.prefault("active"), + regions: z.array(monitorRegionSchema).prefault([]).optional(), + headers: headersSchema.prefault([]), + otelHeaders: headersSchema.prefault([]), }).extend({ - method: monitorMethodsSchema.default("GET"), - notifications: z.array(z.number()).optional().default([]), - pages: z.array(z.number()).optional().default([]), - body: z.string().default("").optional(), - tags: z.array(z.number()).optional().default([]), + method: monitorMethodsSchema.prefault("GET"), + notifications: z.array(z.number()).optional().prefault([]), + pages: z.array(z.number()).optional().prefault([]), + body: z.string().prefault("").optional(), + tags: z.array(z.number()).optional().prefault([]), statusAssertions: z.array(assertions.statusAssertion).optional(), headerAssertions: z.array(assertions.headerAssertion).optional(), textBodyAssertions: z.array(assertions.textBodyAssertion).optional(), - timeout: z.coerce.number().gte(0).lte(60000).default(45000), + timeout: z.coerce.number().gte(0).lte(60000).prefault(45000), degradedAfter: z.coerce.number().gte(0).lte(60000).nullish(), }); diff --git a/packages/db/src/schema/notifications/validation.ts b/packages/db/src/schema/notifications/validation.ts index d4eb12699..dc6bba2e0 100644 --- a/packages/db/src/schema/notifications/validation.ts +++ b/packages/db/src/schema/notifications/validation.ts @@ -12,15 +12,15 @@ export const selectNotificationSchema = createSelectSchema(notification).extend( .preprocess((val) => { return String(val); }, z.string()) - .default("{}"), + .prefault("{}"), }, ); // we need to extend, otherwise data can be `null` or `undefined` - default is not export const insertNotificationSchema = createInsertSchema(notification).extend( { - data: z.string().default("{}"), - monitors: z.array(z.number()).optional().default([]), + data: z.string().prefault("{}"), + monitors: z.array(z.number()).optional().prefault([]), }, ); @@ -33,19 +33,19 @@ const phoneRegex = new RegExp( ); export const phoneSchema = z.string().regex(phoneRegex, "Invalid Number!"); -export const emailSchema = z.string().email(); -export const urlSchema = z.string().url(); +export const emailSchema = z.email(); +export const urlSchema = z.url(); export const ntfyDataSchema = z.object({ ntfy: z.object({ - topic: z.string().default(""), - serverUrl: z.string().default("https://ntfy.sh"), + topic: z.string().prefault(""), + serverUrl: z.string().prefault("https://ntfy.sh"), token: z.string().optional(), }), }); export const webhookDataSchema = z.object({ webhook: z.object({ - endpoint: z.string().url(), + endpoint: z.url(), headers: z .array(z.object({ key: z.string(), value: z.string() })) .optional(), @@ -88,59 +88,59 @@ export const NotificationDataSchema = z.union([ export const InsertNotificationWithDataSchema = z.discriminatedUnion( "provider", [ - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("discord"), data: discordDataSchema, - }), + }).shape, ), - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("email"), data: emailDataSchema, - }), + }).shape, ), - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("google-chat"), data: googleChatDataSchema, - }), + }).shape, ), - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("ntfy"), data: ntfyDataSchema, - }), + }).shape, ), - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("pagerduty"), data: pagerdutyDataSchema, - }), + }).shape, ), - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("opsgenie"), data: opsgenieDataSchema, - }), + }).shape, ), - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("sms"), data: phoneDataSchema, - }), + }).shape, ), - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("slack"), data: slackDataSchema, - }), + }).shape, ), - insertNotificationSchema.merge( + insertNotificationSchema.extend( z.object({ provider: z.literal("webhook"), data: webhookDataSchema, - }), + }).shape, ), insertNotificationSchema.merge( z.object({ diff --git a/packages/db/src/schema/page_subscribers/validation.ts b/packages/db/src/schema/page_subscribers/validation.ts index efccf9299..d1052757f 100644 --- a/packages/db/src/schema/page_subscribers/validation.ts +++ b/packages/db/src/schema/page_subscribers/validation.ts @@ -4,7 +4,7 @@ import { z } from "zod"; import { pageSubscriber } from "./page_subscribers"; export const insertPageSubscriberSchema = createInsertSchema(pageSubscriber, { - email: z.string().email(), + email: z.email(), }); export const selectPageSubscriberSchema = createSelectSchema(pageSubscriber); diff --git a/packages/db/src/schema/pages/validation.ts b/packages/db/src/schema/pages/validation.ts index 2f8c76b5c..346ffd484 100644 --- a/packages/db/src/schema/pages/validation.ts +++ b/packages/db/src/schema/pages/validation.ts @@ -23,39 +23,39 @@ const customDomainSchema = z .or(z.enum([""])); export const insertPageSchema = createInsertSchema(page, { - customDomain: customDomainSchema.default(""), + customDomain: customDomainSchema.prefault(""), icon: z.string().optional(), slug: slugSchema, }).extend({ - password: z.string().nullable().optional().default(""), + password: z.string().nullable().optional().prefault(""), monitors: z .array( z.object({ // REMINDER: has to be different from `id` in as the prop is already used by react-hook-form monitorId: z.number(), - order: z.number().default(0).optional(), + order: z.number().prefault(0).optional(), }), ) .optional() - .default([]), + .prefault([]), }); export const pageConfigurationSchema = z.object({ value: z .enum(["duration", "requests", "manual"]) .nullish() - .default("requests"), - type: z.enum(["absolute", "manual"]).nullish().default("absolute"), - uptime: z.coerce.boolean().nullish().default(true), + .prefault("requests"), + type: z.enum(["absolute", "manual"]).nullish().prefault("absolute"), + uptime: z.coerce.boolean().nullish().prefault(true), theme: z .enum(THEME_KEYS as [ThemeKey, ...ThemeKey[]]) .nullish() - .default("default"), + .prefault("default"), }); export const selectPageSchema = createSelectSchema(page).extend({ - password: z.string().optional().nullable().default(""), - configuration: pageConfigurationSchema.nullish().default({}), + password: z.string().optional().nullable().prefault(""), + configuration: pageConfigurationSchema.nullish().prefault({}), }); export type InsertPage = z.infer; diff --git a/packages/db/src/schema/plan/schema.ts b/packages/db/src/schema/plan/schema.ts index d20e0ac8b..f2c2ee54a 100644 --- a/packages/db/src/schema/plan/schema.ts +++ b/packages/db/src/schema/plan/schema.ts @@ -10,44 +10,46 @@ export const limitsSchema = z.object({ /** * Monitor limits */ - monitors: z.number().default(1), - "synthetic-checks": z.number().default(30), // monthly limits - periodicity: monitorPeriodicitySchema.array().default(["10m", "30m", "1h"]), - "multi-region": z.boolean().default(true), - "max-regions": z.number().default(6), + monitors: z.number().prefault(1), + "synthetic-checks": z.number().prefault(30), // monthly limits + periodicity: monitorPeriodicitySchema.array().prefault(["10m", "30m", "1h"]), + "multi-region": z.boolean().prefault(true), + "max-regions": z.number().prefault(6), "data-retention": z .enum(["14 days", "3 months", "12 months", "24 months"]) - .default("14 days"), - regions: monitorRegionSchema.array().default(FREE_FLY_REGIONS), - "private-locations": z.boolean().default(false), - screenshots: z.boolean().default(false), - "response-logs": z.boolean().default(false), - otel: z.boolean().default(false), + .prefault("14 days"), + regions: monitorRegionSchema.array().prefault(FREE_FLY_REGIONS), + "private-locations": z.boolean().prefault(false), + screenshots: z.boolean().prefault(false), + "response-logs": z.boolean().prefault(false), + otel: z.boolean().prefault(false), /** * Status page limits */ - "status-pages": z.number().default(1), - maintenance: z.boolean().default(true), - "monitor-values-visibility": z.boolean().default(true), - "status-subscribers": z.boolean().default(false), - "custom-domain": z.boolean().default(false), - "password-protection": z.boolean().default(false), - "white-label": z.boolean().default(false), + "status-pages": z.number().prefault(1), + maintenance: z.boolean().prefault(true), + "monitor-values-visibility": z.boolean().prefault(true), + "status-subscribers": z.boolean().prefault(false), + "custom-domain": z.boolean().prefault(false), + "password-protection": z.boolean().prefault(false), + "white-label": z.boolean().prefault(false), /** * Notification limits */ - notifications: z.boolean().default(true), - pagerduty: z.boolean().default(false), - opsgenie: z.boolean().default(false), - whatsapp: z.boolean().default(false), - sms: z.boolean().default(false), - "sms-limit": z.number().default(0), - "notification-channels": z.number().default(1), + + notifications: z.boolean().prefault(true), + pagerduty: z.boolean().prefault(false), + opsgenie: z.boolean().prefault(false), + whatsapp: z.boolean().prefault(false), + sms: z.boolean().prefault(false), + "sms-limit": z.number().prefault(0), + "notification-channels": z.number().prefault(1), + /** * Collaboration limits */ - members: z.literal("Unlimited").or(z.number()).default(1), - "audit-log": z.boolean().default(false), + members: z.literal("Unlimited").or(z.number()).prefault(1), + "audit-log": z.boolean().prefault(false), }); export type Limits = z.infer; diff --git a/packages/db/src/schema/shared.ts b/packages/db/src/schema/shared.ts index be1d35ff5..035b42c44 100644 --- a/packages/db/src/schema/shared.ts +++ b/packages/db/src/schema/shared.ts @@ -29,7 +29,7 @@ export const selectPublicMonitorSchema = })); export const selectStatusReportPageSchema = selectStatusReportSchema.extend({ - statusReportUpdates: z.array(selectStatusReportUpdateSchema).default([]), + statusReportUpdates: z.array(selectStatusReportUpdateSchema).prefault([]), monitorsToStatusReports: z .array( z.object({ @@ -38,7 +38,7 @@ export const selectStatusReportPageSchema = selectStatusReportSchema.extend({ monitor: selectPublicMonitorSchema, }), ) - .default([]), + .prefault([]), }); export const selectMaintenancePageSchema = selectMaintenanceSchema.extend({ @@ -50,7 +50,7 @@ export const selectMaintenancePageSchema = selectMaintenanceSchema.extend({ monitor: selectPublicMonitorSchema, }), ) - .default([]), + .prefault([]), }); // TODO: it would be nice to automatically add the monitor relation here // .refine((data) => ({ monitors: data.maintenancesToMonitors.map((m) => m.monitorId) })); @@ -65,26 +65,26 @@ export const selectPageSchemaWithMonitorsRelation = selectPageSchema.extend({ z.object({ monitorId: z.number(), pageId: z.number(), - order: z.number().default(0).optional(), + order: z.number().prefault(0).optional(), monitor: selectMonitorSchema, }), ), - maintenances: selectMaintenanceSchema.array().default([]), + maintenances: selectMaintenanceSchema.array().prefault([]), statusReports: selectStatusReportSchema .extend({ statusReportUpdates: selectStatusReportUpdateSchema.array() }) .array() - .default([]), + .prefault([]), }); export const legacy_selectPublicPageSchemaWithRelation = selectPageSchema .extend({ - monitors: z.array(selectPublicMonitorSchema).default([]), - statusReports: z.array(selectStatusReportPageSchema).default([]), - incidents: z.array(selectIncidentSchema).default([]), - maintenances: z.array(selectMaintenancePageSchema).default([]), + monitors: z.array(selectPublicMonitorSchema).prefault([]), + statusReports: z.array(selectStatusReportPageSchema).prefault([]), + incidents: z.array(selectIncidentSchema).prefault([]), + maintenances: z.array(selectMaintenancePageSchema).prefault([]), workspacePlan: workspacePlanSchema .nullable() - .default("free") + .prefault("free") .transform((val) => val ?? "free"), }) .omit({ @@ -94,7 +94,9 @@ export const legacy_selectPublicPageSchemaWithRelation = selectPageSchema const selectPublicMonitorWithStatusSchema = selectPublicMonitorBaseSchema .extend({ - status: z.enum(["success", "degraded", "error", "info"]).default("success"), + status: z + .enum(["success", "degraded", "error", "info"]) + .prefault("success"), monitorGroupId: z.number().nullable().optional(), order: z.number().default(0).optional(), groupOrder: z.number().default(0).optional(), @@ -119,24 +121,24 @@ const trackersSchema = z monitors: z.array(selectPublicMonitorWithStatusSchema), status: z .enum(["success", "degraded", "error", "info"]) - .default("success"), + .prefault("success"), order: z.number(), }), ]), ) - .default([]); + .prefault([]); export const statusPageEventSchema = z.object({ id: z.number(), name: z.string(), from: z.date(), to: z.date().nullable(), - status: z.enum(["success", "degraded", "error", "info"]).default("success"), + status: z.enum(["success", "degraded", "error", "info"]).prefault("success"), type: z.enum(["maintenance", "incident", "report"]), }); export const selectPublicPageSchemaWithRelation = selectPageSchema.extend({ - monitorGroups: selectMonitorGroupSchema.array().default([]), + monitorGroups: selectMonitorGroupSchema.array().prefault([]), // TODO: include status of the monitor monitors: selectPublicMonitorWithStatusSchema.array(), trackers: trackersSchema, @@ -145,10 +147,10 @@ export const selectPublicPageSchemaWithRelation = selectPageSchema.extend({ statusReports: z.array(selectStatusReportPageSchema), incidents: z.array(selectIncidentSchema), maintenances: z.array(selectMaintenancePageSchema), - status: z.enum(["success", "degraded", "error", "info"]).default("success"), + status: z.enum(["success", "degraded", "error", "info"]).prefault("success"), workspacePlan: workspacePlanSchema .nullable() - .default("free") + .prefault("free") .transform((val) => val ?? "free"), }); @@ -162,7 +164,7 @@ export const selectPublicStatusReportSchemaWithRelation = monitor: selectPublicMonitorSchema, }), ) - .default([]), + .prefault([]), statusReportUpdates: z.array(selectStatusReportUpdateSchema), }); diff --git a/packages/db/src/schema/status_reports/validation.ts b/packages/db/src/schema/status_reports/validation.ts index 4fd6325cb..2807b4455 100644 --- a/packages/db/src/schema/status_reports/validation.ts +++ b/packages/db/src/schema/status_reports/validation.ts @@ -15,18 +15,18 @@ export const insertStatusReportUpdateSchema = createInsertSchema( status: statusReportStatusSchema, }, ).extend({ - date: z.coerce.date().optional().default(new Date()), + date: z.coerce.date().optional().prefault(new Date()), }); export const insertStatusReportSchema = createInsertSchema(statusReport, { status: statusReportStatusSchema, }) .extend({ - date: z.coerce.date().optional().default(new Date()), + date: z.coerce.date().optional().prefault(new Date()), /** * relationship to monitors and pages */ - monitors: z.number().array().optional().default([]), + monitors: z.number().array().optional().prefault([]), }) .extend({ /** diff --git a/packages/db/src/schema/workspaces/validation.ts b/packages/db/src/schema/workspaces/validation.ts index eeca961bb..4d4d51b26 100644 --- a/packages/db/src/schema/workspaces/validation.ts +++ b/packages/db/src/schema/workspaces/validation.ts @@ -15,22 +15,46 @@ export const workspaceRoleSchema = z.enum(workspaceRole); export const selectWorkspaceSchema = createSelectSchema(workspace) .extend({ limits: z.string().transform((val) => { - const parsed = JSON.parse(val); - const result = limitsSchema.partial().safeParse(parsed); - if (result.error) return {}; - return result.data; + try { + const parsed = JSON.parse(val); + + // Only validate properties that are actually present in the parsed object + // This avoids triggering .prefault() for missing properties + const validated: Record = {}; + const limitsShape = limitsSchema.shape; + + for (const key in parsed) { + if (key in limitsShape) { + // Validate only the properties that exist in the parsed object + const propertySchema = limitsShape[key as keyof typeof limitsShape]; + const result = propertySchema.safeParse(parsed[key]); + if (result.success) { + validated[key] = result.data; + } else { + console.warn(`Invalid value for limits.${key}:`, result.error); + // Skip invalid properties instead of failing entirely + } + } + // Unknown properties are ignored + } + + return validated; + } catch (error) { + console.error("Error parsing limits:", error); + return {}; + } }), plan: z .enum(workspacePlans) .nullable() - .default("free") + .prefault("free") .transform((val) => val ?? "free"), // REMINDER: workspace usage usage: z .object({ - monitors: z.number().default(0), - notifications: z.number().default(0), - pages: z.number().default(0), + monitors: z.number().prefault(0), + notifications: z.number().prefault(0), + pages: z.number().prefault(0), // checks: z.number().default(0), }) .nullish(), diff --git a/packages/emails/package.json b/packages/emails/package.json index f1ae1489f..965a19848 100644 --- a/packages/emails/package.json +++ b/packages/emails/package.json @@ -19,7 +19,7 @@ "@t3-oss/env-core": "0.13.10", "react-email": "5.0.8", "resend": "6.6.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/error/package.json b/packages/error/package.json index 2dab37565..1b33ac867 100644 --- a/packages/error/package.json +++ b/packages/error/package.json @@ -5,7 +5,7 @@ "main": "index.ts", "scripts": {}, "dependencies": { - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/error/src/utils.ts b/packages/error/src/utils.ts index 22663001a..33355769a 100644 --- a/packages/error/src/utils.ts +++ b/packages/error/src/utils.ts @@ -57,7 +57,7 @@ export function parseZodErrorIssues(issues: ZodIssue[]): string { return issues .map((i) => i.code === "invalid_union" - ? i.unionErrors.map((ue) => parseZodErrorIssues(ue.issues)).join("; ") + ? i.errors.map((ue) => parseZodErrorIssues(ue)).join("; ") : i.code === "unrecognized_keys" ? i.message : `${i.path.length ? `${i.code} in '${i.path}': ` : ""}${i.message}`, diff --git a/packages/notifications/discord/package.json b/packages/notifications/discord/package.json index 20c0d7fdd..7b4d3088c 100644 --- a/packages/notifications/discord/package.json +++ b/packages/notifications/discord/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@openstatus/db": "workspace:*", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/email/package.json b/packages/notifications/email/package.json index c86038a6a..8094b70f4 100644 --- a/packages/notifications/email/package.json +++ b/packages/notifications/email/package.json @@ -17,7 +17,7 @@ "@t3-oss/env-core": "0.13.10", "react-dom": "19.2.2", "resend": "6.6.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/google-chat/package.json b/packages/notifications/google-chat/package.json index 97f4edcce..6ffb251c1 100644 --- a/packages/notifications/google-chat/package.json +++ b/packages/notifications/google-chat/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@openstatus/db": "workspace:*", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/ntfy/package.json b/packages/notifications/ntfy/package.json index 116b36f40..3a6634679 100644 --- a/packages/notifications/ntfy/package.json +++ b/packages/notifications/ntfy/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@openstatus/db": "workspace:*", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/ntfy/src/schema.ts b/packages/notifications/ntfy/src/schema.ts index e96d7d64a..e7d7119cd 100644 --- a/packages/notifications/ntfy/src/schema.ts +++ b/packages/notifications/ntfy/src/schema.ts @@ -3,7 +3,7 @@ import { z } from "zod"; export const NtfySchema = z.object({ ntfy: z.object({ topic: z.string(), - serverUrl: z.string().default("https://ntfy.sh"), + serverUrl: z.string().prefault("https://ntfy.sh"), token: z.string().optional(), }), }); diff --git a/packages/notifications/opsgenie/package.json b/packages/notifications/opsgenie/package.json index 00150b9db..43b3d7ccf 100644 --- a/packages/notifications/opsgenie/package.json +++ b/packages/notifications/opsgenie/package.json @@ -10,7 +10,7 @@ "@t3-oss/env-core": "0.13.10", "@types/validator": "13.12.0", "validator": "13.12.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/opsgenie/src/schema.ts b/packages/notifications/opsgenie/src/schema.ts index e315a31e4..da3bee2eb 100644 --- a/packages/notifications/opsgenie/src/schema.ts +++ b/packages/notifications/opsgenie/src/schema.ts @@ -7,7 +7,7 @@ export const OpsGeniePayloadAlert = z.object({ message: z.string(), alias: z.string(), description: z.string(), - source: z.string().default("OpenStatus"), + source: z.string().prefault("OpenStatus"), details: z .object({ message: z.string(), @@ -18,5 +18,5 @@ export const OpsGeniePayloadAlert = z.object({ }); export const OpsGenieCloseAlert = z.object({ - source: z.string().default("OpenStatus"), + source: z.string().prefault("OpenStatus"), }); diff --git a/packages/notifications/pagerduty/package.json b/packages/notifications/pagerduty/package.json index f1376b44a..9dfe9e635 100644 --- a/packages/notifications/pagerduty/package.json +++ b/packages/notifications/pagerduty/package.json @@ -10,7 +10,7 @@ "@t3-oss/env-core": "0.13.10", "@types/validator": "13.12.0", "validator": "13.12.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/pagerduty/src/schema/config.ts b/packages/notifications/pagerduty/src/schema/config.ts index 1ea2964d8..f476fa3dd 100644 --- a/packages/notifications/pagerduty/src/schema/config.ts +++ b/packages/notifications/pagerduty/src/schema/config.ts @@ -41,7 +41,7 @@ const baseEventPayloadSchema = z.object({ dedup_key: z.string(), }); -export const triggerEventPayloadSchema = baseEventPayloadSchema.merge( +export const triggerEventPayloadSchema = baseEventPayloadSchema.extend( z.object({ event_action: z.literal("trigger"), payload: z.object({ @@ -56,19 +56,19 @@ export const triggerEventPayloadSchema = baseEventPayloadSchema.merge( }), images: z.array(imageSchema).optional(), links: z.array(linkSchema).optional(), - }), + }).shape, ); -export const acknowledgeEventPayloadSchema = baseEventPayloadSchema.merge( +export const acknowledgeEventPayloadSchema = baseEventPayloadSchema.extend( z.object({ event_action: z.literal("acknowledge"), - }), + }).shape, ); -export const resolveEventPayloadSchema = baseEventPayloadSchema.merge( +export const resolveEventPayloadSchema = baseEventPayloadSchema.extend( z.object({ event_action: z.literal("resolve"), - }), + }).shape, ); export const eventPayloadV2Schema = z.discriminatedUnion("event_action", [ diff --git a/packages/notifications/slack/package.json b/packages/notifications/slack/package.json index 87aaed7f6..6c9314984 100644 --- a/packages/notifications/slack/package.json +++ b/packages/notifications/slack/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@openstatus/db": "workspace:*", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/telegram/package.json b/packages/notifications/telegram/package.json index 819d2159f..861fadf66 100644 --- a/packages/notifications/telegram/package.json +++ b/packages/notifications/telegram/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@openstatus/db": "workspace:*", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/twillio-sms/package.json b/packages/notifications/twillio-sms/package.json index cd99fc33f..294cdd72a 100644 --- a/packages/notifications/twillio-sms/package.json +++ b/packages/notifications/twillio-sms/package.json @@ -9,7 +9,7 @@ "@openstatus/db": "workspace:*", "@t3-oss/env-core": "0.13.10", "validator": "13.12.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/twillio-whatsapp/package.json b/packages/notifications/twillio-whatsapp/package.json index e7f2dd6f1..9a17656ec 100644 --- a/packages/notifications/twillio-whatsapp/package.json +++ b/packages/notifications/twillio-whatsapp/package.json @@ -9,7 +9,7 @@ "@openstatus/db": "workspace:*", "@t3-oss/env-core": "0.13.10", "validator": "13.12.0", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/notifications/webhook/package.json b/packages/notifications/webhook/package.json index 6757c66c8..b65ab51aa 100644 --- a/packages/notifications/webhook/package.json +++ b/packages/notifications/webhook/package.json @@ -8,7 +8,7 @@ "dependencies": { "@openstatus/db": "workspace:*", "@openstatus/utils": "workspace:*", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/regions/package.json b/packages/regions/package.json index cb3d80d57..a07747005 100644 --- a/packages/regions/package.json +++ b/packages/regions/package.json @@ -5,7 +5,7 @@ "main": "index.ts", "scripts": {}, "dependencies": { - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/tinybird/package.json b/packages/tinybird/package.json index 49af32199..3baef274b 100644 --- a/packages/tinybird/package.json +++ b/packages/tinybird/package.json @@ -4,8 +4,8 @@ "main": "src/index.ts", "license": "MIT", "dependencies": { - "@chronark/zod-bird": "0.3.6", - "zod": "3.25.76" + "@chronark/zod-bird": "1.0.0", + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/tinybird/src/audit-log/base-validation.ts b/packages/tinybird/src/audit-log/base-validation.ts index c449411e8..6d74aae4f 100644 --- a/packages/tinybird/src/audit-log/base-validation.ts +++ b/packages/tinybird/src/audit-log/base-validation.ts @@ -9,11 +9,10 @@ export const baseSchema = z.object({ action: z.string(), // REMINDER: do not use .default(Date.now()), it will be evaluated only once timestamp: z - .number() .int() .optional() .transform((val) => val || Date.now()), - version: z.number().int().default(1), + version: z.int().prefault(1), }); /** @@ -31,7 +30,7 @@ export const actorSchema = z id: z.string(), type: actorTypeSchema, }) - .default({ + .prefault({ id: "server", type: "system", }); diff --git a/packages/tinybird/src/client.ts b/packages/tinybird/src/client.ts index 05ca02e94..fcd49b853 100644 --- a/packages/tinybird/src/client.ts +++ b/packages/tinybird/src/client.ts @@ -33,11 +33,11 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__stats_global__v0", parameters: z.object({ - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), period: z.enum(["total", "1h", "10m", "1d", "1w", "1m"]).optional(), }), data: z.object({ - count: z.number().int(), + count: z.int(), }), // REMINDER: cache on build time as it's a global stats opts: { cache: "force-cache" }, @@ -51,14 +51,14 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("http").default("http"), - latency: z.number().int(), - statusCode: z.number().int().nullable(), + type: z.literal("http").prefault("http"), + latency: z.int(), + statusCode: z.int().nullable(), monitorId: z.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.string(), }), @@ -71,19 +71,19 @@ export class OSTinybird { pipe: "endpoint__http_list_1d__v1", parameters: z.object({ monitorId: z.string(), - fromDate: z.number().int().optional(), - toDate: z.number().int().optional(), + fromDate: z.int().optional(), + toDate: z.int().optional(), }), data: z.object({ - type: z.literal("http").default("http"), + type: z.literal("http").prefault("http"), id: z.string().nullable(), - latency: z.number().int(), - statusCode: z.number().int().nullable(), + latency: z.int(), + statusCode: z.int().nullable(), monitorId: z.string(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), timing: timingPhasesSchema, }), @@ -98,14 +98,14 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("http").default("http"), - latency: z.number().int(), - statusCode: z.number().int().nullable(), + type: z.literal("http").prefault("http"), + latency: z.int(), + statusCode: z.int().nullable(), monitorId: z.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.string(), }), @@ -118,19 +118,19 @@ export class OSTinybird { pipe: "endpoint__http_list_7d__v1", parameters: z.object({ monitorId: z.string(), - fromDate: z.number().int().optional(), - toDate: z.number().int().optional(), + fromDate: z.int().optional(), + toDate: z.int().optional(), }), data: z.object({ - type: z.literal("http").default("http"), + type: z.literal("http").prefault("http"), id: z.string().nullable(), - latency: z.number().int(), - statusCode: z.number().int().nullable(), + latency: z.int(), + statusCode: z.int().nullable(), monitorId: z.string(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), timing: timingPhasesSchema, }), @@ -145,14 +145,14 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("http").default("http"), - latency: z.number().int(), - statusCode: z.number().int().nullable(), + type: z.literal("http").prefault("http"), + latency: z.int(), + statusCode: z.int().nullable(), monitorId: z.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.string(), }), @@ -165,19 +165,19 @@ export class OSTinybird { pipe: "endpoint__http_list_14d__v1", parameters: z.object({ monitorId: z.string(), - fromDate: z.number().int().optional(), - toDate: z.number().int().optional(), + fromDate: z.int().optional(), + toDate: z.int().optional(), }), data: z.object({ - type: z.literal("http").default("http"), + type: z.literal("http").prefault("http"), id: z.string().nullable(), - latency: z.number().int(), - statusCode: z.number().int().nullable(), + latency: z.int(), + statusCode: z.int().nullable(), monitorId: z.string(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), timing: timingPhasesSchema, }), @@ -190,18 +190,18 @@ export class OSTinybird { pipe: "endpoint__http_metrics_1d__v0", parameters: z.object({ regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int(), - ok: z.number().int(), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int(), + ok: z.int(), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -211,21 +211,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__http_metrics_1d__v1", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -236,18 +236,18 @@ export class OSTinybird { pipe: "endpoint__http_metrics_7d__v0", parameters: z.object({ regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int(), - ok: z.number().int(), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int(), + ok: z.int(), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -257,21 +257,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__http_metrics_7d__v1", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -282,18 +282,18 @@ export class OSTinybird { pipe: "endpoint__http_metrics_14d__v0", parameters: z.object({ regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int(), - ok: z.number().int(), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int(), + ok: z.int(), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -303,21 +303,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__http_metrics_14d__v1", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -327,17 +327,17 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__http_metrics_by_interval_1d__v0", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -347,17 +347,17 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__http_metrics_by_interval_7d__v0", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -367,17 +367,17 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__http_metrics_by_interval_14d__v0", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -392,13 +392,13 @@ export class OSTinybird { }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - count: z.number().int(), - ok: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + count: z.int(), + ok: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -413,13 +413,13 @@ export class OSTinybird { }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - count: z.number().int(), - ok: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + count: z.int(), + ok: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -434,13 +434,13 @@ export class OSTinybird { }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - count: z.number().int(), - ok: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + count: z.int(), + ok: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -457,8 +457,8 @@ export class OSTinybird { // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00) return new Date(`${val} GMT`).toISOString(); }), - count: z.number().default(0), - ok: z.number().default(0), + count: z.number().prefault(0), + ok: z.number().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -469,15 +469,15 @@ export class OSTinybird { pipe: "endpoint__http_status_45d__v0", parameters: z.object({ monitorId: z.string(), - days: z.number().int().max(45).optional(), + days: z.int().max(45).optional(), }), data: z.object({ day: z.string().transform((val) => { // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00) return new Date(`${val} GMT`).toISOString(); }), - count: z.number().default(0), - ok: z.number().default(0), + count: z.number().prefault(0), + ok: z.number().prefault(0), }), opts: { next: { @@ -498,10 +498,10 @@ export class OSTinybird { // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00) return new Date(`${val} GMT`).toISOString(); }), - count: z.number().default(0), - ok: z.number().default(0), - degraded: z.number().default(0), - error: z.number().default(0), + count: z.number().prefault(0), + ok: z.number().prefault(0), + degraded: z.number().prefault(0), + error: z.number().prefault(0), monitorId: z.string(), }), opts: { next: { revalidate: REVALIDATE } }, @@ -516,21 +516,21 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("http").default("http"), - latency: z.number().int(), - statusCode: z.number().int().nullable(), + type: z.literal("http").prefault("http"), + latency: z.int(), + statusCode: z.int().nullable(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), monitorId: z.string(), - url: z.string().url(), + url: z.url(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), + cronTimestamp: z.int(), message: z.string().nullable(), headers: headersSchema, timing: timingPhasesSchema, assertions: z.string().nullable(), body: z.string().nullable(), - trigger: z.enum(triggers).nullable().default("cron"), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.string(), id: z.string().nullable(), @@ -546,22 +546,22 @@ export class OSTinybird { parameters: z.object({ monitorId: z.string(), region: z.enum(monitorRegions).or(z.string()).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), }), data: z.object({ - type: z.literal("http").default("http"), - latency: z.number().int(), - statusCode: z.number().int().nullable(), + type: z.literal("http").prefault("http"), + latency: z.int(), + statusCode: z.int().nullable(), monitorId: z.string(), - url: z.string().url(), + url: z.url(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), + cronTimestamp: z.int(), message: z.string().nullable(), headers: headersSchema, timing: timingSchema, assertions: z.string().nullable(), - trigger: z.enum(triggers).nullable().default("cron"), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.string(), }), @@ -575,21 +575,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "get_result_for_on_demand_check_http", parameters: z.object({ - monitorId: z.number().int(), + monitorId: z.int(), timestamp: z.number(), url: z.string(), }), data: z.object({ - latency: z.number().int(), // in ms - statusCode: z.number().int().nullable().default(null), - monitorId: z.string().default(""), - url: z.string().url().optional(), + latency: z.int(), // in ms + statusCode: z.int().nullable().prefault(null), + monitorId: z.string().prefault(""), + url: z.url().optional(), error: z .number() - .default(0) + .prefault(0) .transform((val) => val !== 0), region: z.enum(monitorRegions), - timestamp: z.number().int().optional(), + timestamp: z.int().optional(), message: z.string().nullable().optional(), timing: timingSchema, // TODO: make sure to include all data! @@ -606,13 +606,13 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("tcp").default("tcp"), - latency: z.number().int(), + type: z.literal("tcp").prefault("tcp"), + latency: z.int(), monitorId: z.coerce.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.coerce.string(), }), @@ -625,18 +625,18 @@ export class OSTinybird { pipe: "endpoint__tcp_list_1d__v1", parameters: z.object({ monitorId: z.string(), - fromDate: z.number().int().optional(), - toDate: z.number().int().optional(), + fromDate: z.int().optional(), + toDate: z.int().optional(), }), data: z.object({ - type: z.literal("tcp").default("tcp"), + type: z.literal("tcp").prefault("tcp"), id: z.string().nullable(), - latency: z.number().int(), + latency: z.int(), monitorId: z.coerce.string(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), }), opts: { next: { revalidate: REVALIDATE } }, @@ -650,13 +650,13 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("tcp").default("tcp"), - latency: z.number().int(), + type: z.literal("tcp").prefault("tcp"), + latency: z.int(), monitorId: z.coerce.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.coerce.string(), }), @@ -669,18 +669,18 @@ export class OSTinybird { pipe: "endpoint__tcp_list_7d__v1", parameters: z.object({ monitorId: z.string(), - fromDate: z.number().int().optional(), - toDate: z.number().int().optional(), + fromDate: z.int().optional(), + toDate: z.int().optional(), }), data: z.object({ - type: z.literal("tcp").default("tcp"), + type: z.literal("tcp").prefault("tcp"), id: z.string().nullable(), - latency: z.number().int(), + latency: z.int(), monitorId: z.coerce.string(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), }), opts: { next: { revalidate: REVALIDATE } }, @@ -694,13 +694,13 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("tcp").default("tcp"), - latency: z.number().int(), + type: z.literal("tcp").prefault("tcp"), + latency: z.int(), monitorId: z.coerce.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.coerce.string(), }), @@ -713,18 +713,18 @@ export class OSTinybird { pipe: "endpoint__tcp_list_14d__v1", parameters: z.object({ monitorId: z.string(), - fromDate: z.number().int().optional(), - toDate: z.number().int().optional(), + fromDate: z.int().optional(), + toDate: z.int().optional(), }), data: z.object({ - type: z.literal("tcp").default("tcp"), + type: z.literal("tcp").prefault("tcp"), id: z.string().nullable(), - latency: z.number().int(), + latency: z.int(), monitorId: z.coerce.string(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), }), opts: { next: { revalidate: REVALIDATE } }, @@ -736,18 +736,18 @@ export class OSTinybird { pipe: "endpoint__tcp_metrics_1d__v0", parameters: z.object({ regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int(), - ok: z.number().int(), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int(), + ok: z.int(), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -757,21 +757,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__tcp_metrics_1d__v1", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -781,19 +781,19 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__tcp_metrics_7d__v0", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int(), - ok: z.number().int(), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int(), + ok: z.int(), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -803,21 +803,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__tcp_metrics_7d__v1", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -828,18 +828,18 @@ export class OSTinybird { pipe: "endpoint__tcp_metrics_14d__v0", parameters: z.object({ regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int(), - ok: z.number().int(), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int(), + ok: z.int(), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -849,21 +849,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__tcp_metrics_14d__v1", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -874,17 +874,17 @@ export class OSTinybird { pipe: "endpoint__tcp_metrics_by_interval_1d__v0", parameters: z.object({ regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -895,17 +895,17 @@ export class OSTinybird { pipe: "endpoint__tcp_metrics_by_interval_7d__v0", parameters: z.object({ regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -916,17 +916,17 @@ export class OSTinybird { pipe: "endpoint__tcp_metrics_by_interval_14d__v0", parameters: z.object({ regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), monitorId: z.string(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -941,13 +941,13 @@ export class OSTinybird { }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - count: z.number().int(), - ok: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + count: z.int(), + ok: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -962,13 +962,13 @@ export class OSTinybird { }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - count: z.number().int(), - ok: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + count: z.int(), + ok: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -983,13 +983,13 @@ export class OSTinybird { }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - count: z.number().int(), - ok: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + count: z.int(), + ok: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1006,8 +1006,8 @@ export class OSTinybird { // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00) return new Date(`${val} GMT`).toISOString(); }), - count: z.number().default(0), - ok: z.number().default(0), + count: z.number().prefault(0), + ok: z.number().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1018,15 +1018,15 @@ export class OSTinybird { pipe: "endpoint__tcp_status_45d__v0", parameters: z.object({ monitorId: z.string(), - days: z.number().int().max(45).optional(), + days: z.int().max(45).optional(), }), data: z.object({ day: z.string().transform((val) => { // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00) return new Date(`${val} GMT`).toISOString(); }), - count: z.number().default(0), - ok: z.number().default(0), + count: z.number().prefault(0), + ok: z.number().prefault(0), }), opts: { next: { @@ -1041,17 +1041,17 @@ export class OSTinybird { pipe: "endpoint__tcp_status_45d__v1", parameters: z.object({ monitorIds: z.string().array(), - days: z.number().int().max(45).optional(), + days: z.int().max(45).optional(), }), data: z.object({ day: z.string().transform((val) => { // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00) return new Date(`${val} GMT`).toISOString(); }), - count: z.number().default(0), - ok: z.number().default(0), - degraded: z.number().default(0), - error: z.number().default(0), + count: z.number().prefault(0), + ok: z.number().prefault(0), + degraded: z.number().prefault(0), + error: z.number().prefault(0), monitorId: z.coerce.string(), }), opts: { next: { revalidate: REVALIDATE } }, @@ -1068,7 +1068,7 @@ export class OSTinybird { day: z .string() .transform((val) => new Date(`${val} GMT`).toISOString()), - count: z.number().int(), + count: z.int(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1084,7 +1084,7 @@ export class OSTinybird { day: z .string() .transform((val) => new Date(`${val} GMT`).toISOString()), - count: z.number().int(), + count: z.int(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1098,15 +1098,15 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("tcp").default("tcp"), + type: z.literal("tcp").prefault("tcp"), id: z.string().nullable(), uri: z.string(), - latency: z.number().int(), + latency: z.int(), monitorId: z.coerce.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), errorMessage: z.string().nullable(), @@ -1122,16 +1122,16 @@ export class OSTinybird { parameters: z.object({ monitorId: z.string(), region: z.enum(monitorRegions).or(z.string()).optional(), - cronTimestamp: z.number().int().optional(), + cronTimestamp: z.int().optional(), }), data: z.object({ - type: z.literal("tcp").default("tcp"), - latency: z.number().int(), + type: z.literal("tcp").prefault("tcp"), + latency: z.int(), monitorId: z.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), workspaceId: z.string(), }), @@ -1149,18 +1149,18 @@ export class OSTinybird { pipe: "endpoint__http_metrics_regions_1d__v0", parameters: z.object({ monitorId: z.string(), - interval: z.number().int().optional(), + interval: z.int().optional(), // Comma-separated list of regions, e.g. "ams,fra". Keeping string to pass directly. regions: z.string().array().optional(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1171,17 +1171,17 @@ export class OSTinybird { pipe: "endpoint__http_metrics_regions_7d__v0", parameters: z.object({ monitorId: z.string(), - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.string().array().optional(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1192,17 +1192,17 @@ export class OSTinybird { pipe: "endpoint__http_metrics_regions_14d__v0", parameters: z.object({ monitorId: z.string(), - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.string().array().optional(), }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1216,13 +1216,13 @@ export class OSTinybird { fromDate: z.string().optional(), toDate: z.string().optional(), regions: z.enum(monitorRegions).or(z.string()).array().optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), }), data: z.object({ interval: z.coerce.date(), - success: z.number().int(), - degraded: z.number().int(), - error: z.number().int(), + success: z.int(), + degraded: z.int(), + error: z.int(), }), }); } @@ -1235,13 +1235,13 @@ export class OSTinybird { fromDate: z.string().optional(), toDate: z.string().optional(), regions: z.enum(monitorRegions).or(z.string()).array().optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), }), data: z.object({ interval: z.coerce.date(), - success: z.number().int(), - degraded: z.number().int(), - error: z.number().int(), + success: z.int(), + degraded: z.int(), + error: z.int(), }), }); } @@ -1254,13 +1254,13 @@ export class OSTinybird { fromDate: z.string().optional(), toDate: z.string().optional(), regions: z.enum(monitorRegions).or(z.string()).array().optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), }), data: z.object({ interval: z.coerce.date(), - success: z.number().int(), - degraded: z.number().int(), - error: z.number().int(), + success: z.int(), + degraded: z.int(), + error: z.int(), }), }); } @@ -1273,13 +1273,13 @@ export class OSTinybird { fromDate: z.string().optional(), toDate: z.string().optional(), regions: z.enum(monitorRegions).or(z.string()).array().optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), }), data: z.object({ interval: z.coerce.date(), - success: z.number().int(), - degraded: z.number().int(), - error: z.number().int(), + success: z.int(), + degraded: z.int(), + error: z.int(), }), }); } @@ -1289,7 +1289,7 @@ export class OSTinybird { pipe: "endpoint__audit_log__v1", parameters: z.object({ monitorId: z.string(), - interval: z.number().int().default(30), // in days + interval: z.int().prefault(30), // in days }), data: z.object({ action: z.string(), @@ -1302,7 +1302,7 @@ export class OSTinybird { return {}; } }), - timestamp: z.number().int(), + timestamp: z.int(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1315,15 +1315,15 @@ export class OSTinybird { monitorIds: z.string().array(), }), data: z.object({ - minLatency: z.number().int(), - maxLatency: z.number().int(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), - lastTimestamp: z.number().int(), - count: z.number().int(), + minLatency: z.int(), + maxLatency: z.int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), + lastTimestamp: z.int(), + count: z.int(), monitorId: z.string(), }), opts: { next: { revalidate: REVALIDATE } }, @@ -1337,15 +1337,15 @@ export class OSTinybird { monitorIds: z.string().array(), }), data: z.object({ - minLatency: z.number().int(), - maxLatency: z.number().int(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), - lastTimestamp: z.number().int(), - count: z.number().int(), + minLatency: z.int(), + maxLatency: z.int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), + lastTimestamp: z.int(), + count: z.int(), monitorId: z.coerce.string(), }), opts: { next: { revalidate: REVALIDATE } }, @@ -1357,36 +1357,36 @@ export class OSTinybird { pipe: "endpoint__http_timing_phases_14d__v1", parameters: z.object({ monitorId: z.string(), - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), }), data: z.object({ - timestamp: z.number().int(), - p50Dns: z.number().int(), - p50Ttfb: z.number().int(), - p50Transfer: z.number().int(), - p50Connect: z.number().int(), - p50Tls: z.number().int(), - p75Dns: z.number().int(), - p75Ttfb: z.number().int(), - p75Transfer: z.number().int(), - p75Connect: z.number().int(), - p75Tls: z.number().int(), - p90Dns: z.number().int(), - p90Ttfb: z.number().int(), - p90Transfer: z.number().int(), - p90Connect: z.number().int(), - p90Tls: z.number().int(), - p95Dns: z.number().int(), - p95Ttfb: z.number().int(), - p95Transfer: z.number().int(), - p95Connect: z.number().int(), - p95Tls: z.number().int(), - p99Dns: z.number().int(), - p99Ttfb: z.number().int(), - p99Transfer: z.number().int(), - p99Connect: z.number().int(), - p99Tls: z.number().int(), + timestamp: z.int(), + p50Dns: z.int(), + p50Ttfb: z.int(), + p50Transfer: z.int(), + p50Connect: z.int(), + p50Tls: z.int(), + p75Dns: z.int(), + p75Ttfb: z.int(), + p75Transfer: z.int(), + p75Connect: z.int(), + p75Tls: z.int(), + p90Dns: z.int(), + p90Ttfb: z.int(), + p90Transfer: z.int(), + p90Connect: z.int(), + p90Tls: z.int(), + p95Dns: z.int(), + p95Ttfb: z.int(), + p95Transfer: z.int(), + p95Connect: z.int(), + p95Tls: z.int(), + p99Dns: z.int(), + p99Ttfb: z.int(), + p99Transfer: z.int(), + p99Connect: z.int(), + p99Tls: z.int(), }), }); } @@ -1400,12 +1400,12 @@ export class OSTinybird { toDate: z.string().optional(), }), data: z.object({ - timestamp: z.number().int(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), + timestamp: z.int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), }), }); } @@ -1419,12 +1419,12 @@ export class OSTinybird { toDate: z.string().optional(), }), data: z.object({ - timestamp: z.number().int(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), + timestamp: z.int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), }), }); } @@ -1438,13 +1438,13 @@ export class OSTinybird { toDate: z.string().optional(), }), data: z.object({ - timestamp: z.number().int(), + timestamp: z.int(), monitorId: z.string(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1460,12 +1460,12 @@ export class OSTinybird { toDate: z.string().optional(), }), data: z.object({ - timestamp: z.number().int(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), + timestamp: z.int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), }), }); } @@ -1479,12 +1479,12 @@ export class OSTinybird { toDate: z.string().optional(), }), data: z.object({ - timestamp: z.number().int(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), + timestamp: z.int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), }), }); } @@ -1498,13 +1498,13 @@ export class OSTinybird { toDate: z.string().optional(), }), data: z.object({ - timestamp: z.number().int(), + timestamp: z.int(), monitorId: z.coerce.string(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1518,15 +1518,15 @@ export class OSTinybird { monitorId: z.string(), }), data: z.object({ - type: z.literal("dns").default("dns"), + type: z.literal("dns").prefault("dns"), id: z.coerce.string().nullable(), uri: z.string(), - latency: z.number().int(), + latency: z.int(), monitorId: z.coerce.string(), error: z.coerce.boolean(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), errorMessage: z.string().nullable(), @@ -1553,19 +1553,19 @@ export class OSTinybird { pipe: "endpoint__dns_list_14d__v0", parameters: z.object({ monitorId: z.string(), - fromDate: z.number().int().optional(), - toDate: z.number().int().optional(), + fromDate: z.int().optional(), + toDate: z.int().optional(), }), data: z.object({ - type: z.literal("dns").default("dns"), + type: z.literal("dns").prefault("dns"), id: z.coerce.string().nullable(), uri: z.string(), - latency: z.number().int(), + latency: z.int(), monitorId: z.coerce.string(), requestStatus: z.enum(["error", "success", "degraded"]).nullable(), region: z.enum(monitorRegions).or(z.string()), - cronTimestamp: z.number().int(), - trigger: z.enum(triggers).nullable().default("cron"), + cronTimestamp: z.int(), + trigger: z.enum(triggers).nullable().prefault("cron"), timestamp: z.number(), records: z .string() @@ -1587,21 +1587,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__dns_metrics_1d__v0", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1611,21 +1611,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__dns_metrics_7d__v0", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1635,21 +1635,21 @@ export class OSTinybird { return this.tb.buildPipe({ pipe: "endpoint__dns_metrics_14d__v0", parameters: z.object({ - interval: z.number().int().optional(), + interval: z.int().optional(), regions: z.array(z.enum(monitorRegions).or(z.string())).optional(), monitorId: z.string(), }), data: z.object({ - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), - count: z.number().int().default(0), - success: z.number().int().default(0), - degraded: z.number().int().default(0), - error: z.number().int().default(0), - lastTimestamp: z.number().int().nullable(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), + count: z.int().prefault(0), + success: z.int().prefault(0), + degraded: z.int().prefault(0), + error: z.int().prefault(0), + lastTimestamp: z.int().nullable(), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1663,13 +1663,13 @@ export class OSTinybird { fromDate: z.string().optional(), toDate: z.string().optional(), regions: z.enum(monitorRegions).or(z.string()).array().optional(), - interval: z.number().int().optional(), + interval: z.int().optional(), }), data: z.object({ interval: z.coerce.date(), - success: z.number().int(), - degraded: z.number().int(), - error: z.number().int(), + success: z.int(), + degraded: z.int(), + error: z.int(), }), }); } @@ -1683,12 +1683,12 @@ export class OSTinybird { toDate: z.string().optional(), }), data: z.object({ - timestamp: z.number().int(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), + timestamp: z.int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), }), }); } @@ -1698,7 +1698,7 @@ export class OSTinybird { pipe: "endpoint__dns_metrics_regions_14d__v0", parameters: z.object({ monitorId: z.string(), - interval: z.number().int().optional(), + interval: z.int().optional(), // Comma-separated list of regions, e.g. "ams,fra". Keeping string to pass directly. regions: z.string().array().optional(), fromDate: z.string().optional(), @@ -1706,12 +1706,12 @@ export class OSTinybird { }), data: z.object({ region: z.enum(monitorRegions).or(z.string()), - timestamp: z.number().int(), - p50Latency: z.number().nullable().default(0), - p75Latency: z.number().nullable().default(0), - p90Latency: z.number().nullable().default(0), - p95Latency: z.number().nullable().default(0), - p99Latency: z.number().nullable().default(0), + timestamp: z.int(), + p50Latency: z.number().nullable().prefault(0), + p75Latency: z.number().nullable().prefault(0), + p90Latency: z.number().nullable().prefault(0), + p95Latency: z.number().nullable().prefault(0), + p99Latency: z.number().nullable().prefault(0), }), opts: { next: { revalidate: REVALIDATE } }, }); @@ -1728,10 +1728,10 @@ export class OSTinybird { // That's a hack because clickhouse return the date in UTC but in shitty format (2021-09-01 00:00:00) return new Date(`${val} GMT`).toISOString(); }), - count: z.number().default(0), - ok: z.number().default(0), - degraded: z.number().default(0), - error: z.number().default(0), + count: z.number().prefault(0), + ok: z.number().prefault(0), + degraded: z.number().prefault(0), + error: z.number().prefault(0), monitorId: z.coerce.string(), }), opts: { next: { revalidate: REVALIDATE } }, @@ -1747,13 +1747,13 @@ export class OSTinybird { toDate: z.string().optional(), }), data: z.object({ - timestamp: z.number().int(), + timestamp: z.int(), monitorId: z.coerce.string(), - p50Latency: z.number().int(), - p75Latency: z.number().int(), - p90Latency: z.number().int(), - p95Latency: z.number().int(), - p99Latency: z.number().int(), + p50Latency: z.int(), + p75Latency: z.int(), + p90Latency: z.int(), + p95Latency: z.int(), + p99Latency: z.int(), }), opts: { next: { revalidate: REVALIDATE } }, }); diff --git a/packages/tracker/package.json b/packages/tracker/package.json index b8872ea3a..420fc85b4 100644 --- a/packages/tracker/package.json +++ b/packages/tracker/package.json @@ -7,7 +7,7 @@ "dependencies": { "@openstatus/db": "workspace:*", "@openstatus/tinybird": "workspace:*", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/packages/ui/package.json b/packages/ui/package.json index 9991a09fd..c68ad61a6 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -22,7 +22,7 @@ "@dnd-kit/modifiers": "9.0.0", "@dnd-kit/sortable": "10.0.0", "@dnd-kit/utilities": "3.2.2", - "@hookform/resolvers": "4.1.3", + "@hookform/resolvers": "5.1.0", "@radix-ui/react-accordion": "1.2.2", "@radix-ui/react-alert-dialog": "1.1.4", "@radix-ui/react-avatar": "1.1.2", @@ -58,7 +58,7 @@ "recharts": "2.15.0", "tailwind-merge": "2.5.5", "tailwindcss-animate": "1.0.7", - "zod": "3.25.76" + "zod": "4.1.13" }, "peerDependencies": { "next-themes": "0.2.1", diff --git a/packages/utils/index.ts b/packages/utils/index.ts index 8350a591d..67d8d6214 100644 --- a/packages/utils/index.ts +++ b/packages/utils/index.ts @@ -13,17 +13,17 @@ export const httpPayloadSchema = z.object({ cronTimestamp: z.number(), status: z.enum(monitorStatus), assertions: z.array(base).nullable(), - timeout: z.number().default(45000), + timeout: z.number().prefault(45000), degradedAfter: z.number().nullable(), - trigger: z.enum(["cron", "api"]).optional().nullable().default("cron"), + trigger: z.enum(["cron", "api"]).optional().nullable().prefault("cron"), otelConfig: z .object({ endpoint: z.string(), - headers: z.record(z.string()), + headers: z.record(z.string(), z.string()), }) .optional(), - retry: z.number().default(3), - followRedirects: z.boolean().default(true), + retry: z.number().prefault(3), + followRedirects: z.boolean().prefault(true), }); export type HttpPayload = z.infer; @@ -35,16 +35,16 @@ export const tpcPayloadSchema = z.object({ monitorId: z.string(), assertions: z.array(base).nullable(), cronTimestamp: z.number(), - timeout: z.number().default(45000), + timeout: z.number().prefault(45000), degradedAfter: z.number().nullable(), - trigger: z.enum(["cron", "api"]).optional().nullable().default("cron"), + trigger: z.enum(["cron", "api"]).optional().nullable().prefault("cron"), otelConfig: z .object({ endpoint: z.string(), - headers: z.record(z.string()), + headers: z.record(z.string(), z.string()), }) .optional(), - retry: z.number().default(3), + retry: z.number().prefault(3), }); export type TcpPayload = z.infer; @@ -56,16 +56,16 @@ export const DNSPayloadSchema = z.object({ monitorId: z.string(), assertions: z.array(base).nullable(), cronTimestamp: z.number(), - timeout: z.number().default(45000), + timeout: z.number().prefault(45000), degradedAfter: z.number().nullable(), - trigger: z.enum(["cron", "api"]).optional().nullable().default("cron"), + trigger: z.enum(["cron", "api"]).optional().nullable().prefault("cron"), otelConfig: z .object({ endpoint: z.string(), - headers: z.record(z.string()), + headers: z.record(z.string(), z.string()), }) .optional(), - retry: z.number().default(3), + retry: z.number().prefault(3), }); export type DNSPayload = z.infer; diff --git a/packages/utils/package.json b/packages/utils/package.json index 19bea00d5..706bf9205 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -8,7 +8,7 @@ "@openstatus/assertions": "workspace:*", "@openstatus/db": "workspace:*", "@openstatus/regions": "workspace:*", - "zod": "3.25.76" + "zod": "4.1.13" }, "devDependencies": { "@openstatus/tsconfig": "workspace:*", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8fb08d542..dfd1ebd10 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -69,8 +69,8 @@ importers: specifier: 4.4.0 version: 4.4.0(@types/react@19.2.2)(react-dom@19.2.2(react@19.2.2))(react@19.2.2) '@hookform/resolvers': - specifier: 4.1.3 - version: 4.1.3(react-hook-form@7.68.0(react@19.2.2)) + specifier: 5.1.0 + version: 5.1.0(react-hook-form@7.68.0(react@19.2.2)) '@libsql/client': specifier: 0.15.15 version: 0.15.15 @@ -312,8 +312,8 @@ importers: specifier: 11.0.5 version: 11.0.5 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@tailwindcss/postcss': specifier: 4.1.11 @@ -414,7 +414,7 @@ importers: version: 3.550.0 '@hono/zod-validator': specifier: 0.2.2 - version: 0.2.2(hono@4.5.3)(zod@3.25.76) + version: 0.2.2(hono@4.5.3)(zod@4.1.13) '@openstatus/db': specifier: workspace:* version: link:../../packages/db @@ -423,7 +423,7 @@ importers: version: link:../../packages/utils '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) '@upstash/qstash': specifier: 2.6.2 version: 2.6.2 @@ -434,8 +434,8 @@ importers: specifier: 1.46.0 version: 1.46.0 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -450,11 +450,11 @@ importers: specifier: 1.2.2 version: 1.2.2(hono@4.5.3) '@hono/zod-openapi': - specifier: 0.15.1 - version: 0.15.1(hono@4.5.3)(zod@3.25.76) + specifier: 1.1.5 + version: 1.1.5(hono@4.5.3)(zod@4.1.13) '@hono/zod-validator': specifier: 0.2.2 - version: 0.2.2(hono@4.5.3)(zod@3.25.76) + version: 0.2.2(hono@4.5.3)(zod@4.1.13) '@logtape/logtape': specifier: 1.1.2 version: 1.1.2 @@ -496,7 +496,7 @@ importers: version: 0.8.5(hono@4.5.3) '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) '@unkey/api': specifier: 2.2.0 version: 2.2.0 @@ -516,8 +516,8 @@ importers: specifier: 13.12.0 version: 13.12.0 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -556,8 +556,8 @@ importers: specifier: 4.4.0 version: 4.4.0(@types/react@19.2.2)(react-dom@19.2.2(react@19.2.2))(react@19.2.2) '@hookform/resolvers': - specifier: 4.1.3 - version: 4.1.3(react-hook-form@7.68.0(react@19.2.2)) + specifier: 5.1.0 + version: 5.1.0(react-hook-form@7.68.0(react@19.2.2)) '@libsql/client': specifier: 0.15.15 version: 0.15.15 @@ -751,8 +751,8 @@ importers: specifier: 11.0.5 version: 11.0.5 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -800,8 +800,8 @@ importers: specifier: 4.0.1 version: 4.0.1 '@hookform/resolvers': - specifier: 4.1.3 - version: 4.1.3(react-hook-form@7.68.0(react@19.2.2)) + specifier: 5.1.0 + version: 5.1.0(react-hook-form@7.68.0(react@19.2.2)) '@libsql/client': specifier: 0.15.15 version: 0.15.15 @@ -888,7 +888,7 @@ importers: version: 2.1.6 '@t3-oss/env-nextjs': specifier: 0.7.0 - version: 0.7.0(typescript@5.9.3)(zod@3.25.76) + version: 0.7.0(typescript@5.9.3)(zod@4.1.13) '@tailwindcss/container-queries': specifier: 0.1.1 version: 0.1.1(tailwindcss@4.1.11) @@ -1031,8 +1031,8 @@ importers: specifier: 1.0.7 version: 1.0.7(tailwindcss@4.1.11) zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1155,8 +1155,8 @@ importers: specifier: ^3.0.0 version: 3.0.0 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1230,7 +1230,7 @@ importers: version: link:../utils '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) '@trpc/client': specifier: 11.4.4 version: 11.4.4(@trpc/server@11.4.4(typescript@5.9.3))(typescript@5.9.3) @@ -1265,8 +1265,8 @@ importers: specifier: 2.2.2 version: 2.2.2 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1297,8 +1297,8 @@ importers: specifier: 5.9.3 version: 5.9.3 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 packages/db: dependencies: @@ -1316,16 +1316,16 @@ importers: version: link:../theme-store '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) drizzle-orm: specifier: 0.44.4 version: 0.44.4(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(bun-types@1.3.5) drizzle-zod: - specifier: 0.5.1 - version: 0.5.1(drizzle-orm@0.44.4(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(bun-types@1.3.5))(zod@3.25.76) + specifier: 0.8.3 + version: 0.8.3(drizzle-orm@0.44.4(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(bun-types@1.3.5))(zod@4.1.13) zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1365,7 +1365,7 @@ importers: version: 2.0.1(@react-email/body@0.2.0(react@19.2.2))(@react-email/button@0.2.0(react@19.2.2))(@react-email/code-block@0.2.0(react@19.2.2))(@react-email/code-inline@0.0.5(react@19.2.2))(@react-email/container@0.0.15(react@19.2.2))(@react-email/heading@0.0.15(react@19.2.2))(@react-email/hr@0.0.11(react@19.2.2))(@react-email/img@0.0.11(react@19.2.2))(@react-email/link@0.0.12(react@19.2.2))(@react-email/preview@0.0.13(react@19.2.2))(@react-email/text@0.1.5(react@19.2.2))(react@19.2.2) '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) react-email: specifier: 5.0.8 version: 5.0.8 @@ -1373,8 +1373,8 @@ importers: specifier: 6.6.0 version: 6.6.0(@react-email/render@2.0.0(react-dom@19.2.2(react@19.2.2))(react@19.2.2)) zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1398,8 +1398,8 @@ importers: packages/error: dependencies: zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1445,8 +1445,8 @@ importers: specifier: workspace:* version: link:../../db zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1486,7 +1486,7 @@ importers: version: 2.0.0(react-dom@19.2.2(react@19.2.2))(react@19.2.2) '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) react-dom: specifier: 19.2.2 version: 19.2.2(react@19.2.2) @@ -1494,8 +1494,8 @@ importers: specifier: 6.6.0 version: 6.6.0(@react-email/render@2.0.0(react-dom@19.2.2(react@19.2.2))(react@19.2.2)) zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1519,8 +1519,8 @@ importers: specifier: workspace:* version: link:../../db zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1541,8 +1541,8 @@ importers: specifier: workspace:* version: link:../../db zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1564,7 +1564,7 @@ importers: version: link:../../db '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) '@types/validator': specifier: 13.12.0 version: 13.12.0 @@ -1572,8 +1572,8 @@ importers: specifier: 13.12.0 version: 13.12.0 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1601,7 +1601,7 @@ importers: version: link:../../db '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) '@types/validator': specifier: 13.12.0 version: 13.12.0 @@ -1609,8 +1609,8 @@ importers: specifier: 13.12.0 version: 13.12.0 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1637,8 +1637,8 @@ importers: specifier: workspace:* version: link:../../db zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1659,8 +1659,8 @@ importers: specifier: workspace:* version: link:../../db zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1682,13 +1682,13 @@ importers: version: link:../../db '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) validator: specifier: 13.12.0 version: 13.12.0 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1713,13 +1713,13 @@ importers: version: link:../../db '@t3-oss/env-core': specifier: 0.13.10 - version: 0.13.10(typescript@5.9.3)(zod@3.25.76) + version: 0.13.10(typescript@5.9.3)(zod@4.1.13) validator: specifier: 13.12.0 version: 13.12.0 zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1746,8 +1746,8 @@ importers: specifier: workspace:* version: link:../../utils zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1796,13 +1796,11 @@ importers: specifier: 5.9.3 version: 5.9.3 - packages/react/dist: {} - packages/regions: dependencies: zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1823,11 +1821,11 @@ importers: packages/tinybird: dependencies: '@chronark/zod-bird': - specifier: 0.3.6 - version: 0.3.6 + specifier: 1.0.0 + version: 1.0.0(zod@4.1.13) zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1851,8 +1849,8 @@ importers: specifier: workspace:* version: link:../tinybird zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -1878,8 +1876,8 @@ importers: specifier: 3.2.2 version: 3.2.2(react@19.2.2) '@hookform/resolvers': - specifier: 4.1.3 - version: 4.1.3(react-hook-form@7.68.0(react@19.2.2)) + specifier: 5.1.0 + version: 5.1.0(react-hook-form@7.68.0(react@19.2.2)) '@radix-ui/react-accordion': specifier: 1.2.2 version: 1.2.2(@types/react-dom@19.2.2(@types/react@19.2.2))(@types/react@19.2.2)(react-dom@19.2.2(react@19.2.2))(react@19.2.2) @@ -1992,8 +1990,8 @@ importers: specifier: 1.0.7 version: 1.0.7(tailwindcss@4.1.8) zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@biomejs/biome': specifier: 1.9.4 @@ -2060,8 +2058,8 @@ importers: specifier: workspace:* version: link:../regions zod: - specifier: 3.25.76 - version: 3.25.76 + specifier: 4.1.13 + version: 4.1.13 devDependencies: '@openstatus/tsconfig': specifier: workspace:* @@ -2096,10 +2094,10 @@ packages: '@apm-js-collab/tracing-hooks@0.3.1': resolution: {integrity: sha512-Vu1CbmPURlN5fTboVuKMoJjbO5qcq9fA5YXpskx3dXe/zTBvjODFoerw+69rVBlRLrJpwPqSDqEuJDEKIrTldw==} - '@asteasolutions/zod-to-openapi@7.3.4': - resolution: {integrity: sha512-/2rThQ5zPi9OzVwes6U7lK1+Yvug0iXu25olp7S0XsYmOqnyMfxH7gdSQjn/+DSOHRg7wnotwGJSyL+fBKdnEA==} + '@asteasolutions/zod-to-openapi@8.2.0': + resolution: {integrity: sha512-u05zNUirlukJAf9oEHmxSF31L1XQhz9XdpVILt7+xhrz65oQqBpiOWFkGvRWL0IpjOUJ878idKoNmYPxrFnkeg==} peerDependencies: - zod: ^3.20.2 + zod: ^4.0.0 '@astro-community/astro-embed-twitter@0.5.9': resolution: {integrity: sha512-bTIP/2LB3iEzlZ58L7dFyLJuWLeFDXgzZUQZKlWIfsXiKYqKIfLTQ01U10sh9UiHpm1M+4kOVPpue5LbUpJXHw==} @@ -2658,8 +2656,10 @@ packages: '@capsizecss/unpack@2.4.0': resolution: {integrity: sha512-GrSU71meACqcmIUxPYOJvGKF0yryjN/L1aCuE9DViCTJI7bfkjgYDPD1zbNDcINJwSSP6UaBZY9GAbYDO7re0Q==} - '@chronark/zod-bird@0.3.6': - resolution: {integrity: sha512-hE8kCGLJK5ncH8F7uPaqPiOOqo68vUI66nusg7HO5X9BcyN8lXfeQliu6Ou1kOSq95OYshf9nB2fk2+LEvF4ng==} + '@chronark/zod-bird@1.0.0': + resolution: {integrity: sha512-OWdZt5EULFgDaHTbkxkxN130ohapRxSMaYdaW/fZTcQP3z1c4cYk4izJwbbTPOP4GdQeys18Prls0xz4NpFV0A==} + peerDependencies: + zod: ^4.0.0 '@cspotcode/source-map-support@0.8.1': resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} @@ -3144,12 +3144,12 @@ packages: peerDependencies: hono: '>=3.*' - '@hono/zod-openapi@0.15.1': - resolution: {integrity: sha512-2Un3D5xD1j4tIvUwzQ/XkB6xwrEA0Ne23TRjB8UVw0PgUWzsB3xiB8Hl/y2ZEMfcIfrA15/ga4P6Bkct8uYaLg==} + '@hono/zod-openapi@1.1.5': + resolution: {integrity: sha512-EAnY6ad4yt/MUKHx716BEGGOXSl5d0/FOLozOYB/pmSEFq07qrzefKFtBEMAgd3hlpJXjH+4lwgTtlAo+BGBgQ==} engines: {node: '>=16.0.0'} peerDependencies: hono: '>=4.3.6' - zod: 3.* + zod: ^4.0.0 '@hono/zod-validator@0.2.2': resolution: {integrity: sha512-dSDxaPV70Py8wuIU2QNpoVEIOSzSXZ/6/B/h4xA7eOMz7+AarKTSGV8E6QwrdcCbBLkpqfJ4Q2TmBO0eP1tCBQ==} @@ -3157,16 +3157,22 @@ packages: hono: '>=3.9.0' zod: ^3.19.1 + '@hono/zod-validator@0.7.6': + resolution: {integrity: sha512-Io1B6d011Gj1KknV4rXYz4le5+5EubcWEU/speUjuw9XMMIaP3n78yXLhjd2A3PXaXaUwEAluOiAyLqhBEJgsw==} + peerDependencies: + hono: '>=3.9.0' + zod: ^3.25.0 || ^4.0.0 + '@hookform/devtools@4.4.0': resolution: {integrity: sha512-Mtlic+uigoYBPXlfvPBfiYYUZuyMrD3pTjDpVIhL6eCZTvQkHsKBSKeZCvXWUZr8fqrkzDg27N+ZuazLKq6Vmg==} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 react-dom: ^16.8.0 || ^17 || ^18 || ^19 - '@hookform/resolvers@4.1.3': - resolution: {integrity: sha512-Jsv6UOWYTrEFJ/01ZrnwVXs7KDvP8XIo115i++5PWvNkNvkrsTfGiLS6w+eJ57CYtUtDQalUWovCZDHFJ8u1VQ==} + '@hookform/resolvers@5.1.0': + resolution: {integrity: sha512-A5tY8gxqvvR0lFfropqpy/gUDOxjwT7LZCxJ8lNA9puK7nFNRl/O0egGKxzdF4JSz/pnnT1O8g76P/YMyTBEFw==} peerDependencies: - react-hook-form: ^7.0.0 + react-hook-form: ^7.55.0 '@iconify-json/lucide@1.2.26': resolution: {integrity: sha512-arD/8mK0lRxFY2LgLf345NhWVWiOtV8sOxJuLnq4QRz3frMiOwVwGxEgp5Xe/bRGzxO2CxxCBok0bPRpCkYZQQ==} @@ -3596,8 +3602,8 @@ packages: resolution: {integrity: sha512-EFd6cVbHsgLa6wa4RljGj6Wk75qoHxUSyc5asLyyPSyuhIcdS2Q3Phw6ImS1q+CkALthJRShiYfKANcQMuMqsQ==} engines: {node: '>=18'} - '@napi-rs/wasm-runtime@1.1.0': - resolution: {integrity: sha512-Fq6DJW+Bb5jaWE69/qOE0D1TUN9+6uWhCeZpdnSBk14pjLcCWR7Q8n49PTSPHazM37JqrsdpEthXy2xn6jWWiA==} + '@napi-rs/wasm-runtime@1.1.1': + resolution: {integrity: sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==} '@neon-rs/load@0.0.4': resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} @@ -3882,103 +3888,103 @@ packages: '@oslojs/encoding@1.1.0': resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} - '@oxc-resolver/binding-android-arm-eabi@11.15.0': - resolution: {integrity: sha512-Q+lWuFfq7whNelNJIP1dhXaVz4zO9Tu77GcQHyxDWh3MaCoO2Bisphgzmsh4ZoUe2zIchQh6OvQL99GlWHg9Tw==} + '@oxc-resolver/binding-android-arm-eabi@11.16.2': + resolution: {integrity: sha512-lVJbvydLQIDZHKUb6Zs9Rq80QVTQ9xdCQE30eC9/cjg4wsMoEOg65QZPymUAIVJotpUAWJD0XYcwE7ugfxx5kQ==} cpu: [arm] os: [android] - '@oxc-resolver/binding-android-arm64@11.15.0': - resolution: {integrity: sha512-vbdBttesHR0W1oJaxgWVTboyMUuu+VnPsHXJ6jrXf4czELzB6GIg5DrmlyhAmFBhjwov+yJH/DfTnHS+2sDgOw==} + '@oxc-resolver/binding-android-arm64@11.16.2': + resolution: {integrity: sha512-fEk+g/g2rJ6LnBVPqeLcx+/alWZ/Db1UlXG+ZVivip0NdrnOzRL48PAmnxTMGOrLwsH1UDJkwY3wOjrrQltCqg==} cpu: [arm64] os: [android] - '@oxc-resolver/binding-darwin-arm64@11.15.0': - resolution: {integrity: sha512-R67lsOe1UzNjqVBCwCZX1rlItTsj/cVtBw4Uy19CvTicqEWvwaTn8t34zLD75LQwDDPCY3C8n7NbD+LIdw+ZoA==} + '@oxc-resolver/binding-darwin-arm64@11.16.2': + resolution: {integrity: sha512-Pkbp1qi7kdUX6k3Fk1PvAg6p7ruwaWKg1AhOlDgrg2vLXjtv9ZHo7IAQN6kLj0W771dPJZWqNxoqTPacp2oYWA==} cpu: [arm64] os: [darwin] - '@oxc-resolver/binding-darwin-x64@11.15.0': - resolution: {integrity: sha512-77mya5F8WV0EtCxI0MlVZcqkYlaQpfNwl/tZlfg4jRsoLpFbaTeWv75hFm6TE84WULVlJtSgvf7DhoWBxp9+ZQ==} + '@oxc-resolver/binding-darwin-x64@11.16.2': + resolution: {integrity: sha512-FYCGcU1iSoPkADGLfQbuj0HWzS+0ItjDCt9PKtu2Hzy6T0dxO4Y1enKeCOxCweOlmLEkSxUlW5UPT4wvT3LnAg==} cpu: [x64] os: [darwin] - '@oxc-resolver/binding-freebsd-x64@11.15.0': - resolution: {integrity: sha512-X1Sz7m5PC+6D3KWIDXMUtux+0Imj6HfHGdBStSvgdI60OravzI1t83eyn6eN0LPTrynuPrUgjk7tOnOsBzSWHw==} + '@oxc-resolver/binding-freebsd-x64@11.16.2': + resolution: {integrity: sha512-1zHCoK6fMcBjE54P2EG/z70rTjcRxvyKfvk4E/QVrWLxNahuGDFZIxoEoo4kGnnEcmPj41F0c2PkrQbqlpja5g==} cpu: [x64] os: [freebsd] - '@oxc-resolver/binding-linux-arm-gnueabihf@11.15.0': - resolution: {integrity: sha512-L1x/wCaIRre+18I4cH/lTqSAymlV0k4HqfSYNNuI9oeL28Ks86lI6O5VfYL6sxxWYgjuWB98gNGo7tq7d4GarQ==} + '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.2': + resolution: {integrity: sha512-+ucLYz8EO5FDp6kZ4o1uDmhoP+M98ysqiUW4hI3NmfiOJQWLrAzQjqaTdPfIOzlCXBU9IHp5Cgxu6wPjVb8dbA==} cpu: [arm] os: [linux] - '@oxc-resolver/binding-linux-arm-musleabihf@11.15.0': - resolution: {integrity: sha512-abGXd/zMGa0tH8nKlAXdOnRy4G7jZmkU0J85kMKWns161bxIgGn/j7zxqh3DKEW98wAzzU9GofZMJ0P5YCVPVw==} + '@oxc-resolver/binding-linux-arm-musleabihf@11.16.2': + resolution: {integrity: sha512-qq+TpNXyw1odDgoONRpMLzH4hzhwnEw55398dL8rhKGvvYbio71WrJ00jE+hGlEi7H1Gkl11KoPJRaPlRAVGPw==} cpu: [arm] os: [linux] - '@oxc-resolver/binding-linux-arm64-gnu@11.15.0': - resolution: {integrity: sha512-SVjjjtMW66Mza76PBGJLqB0KKyFTBnxmtDXLJPbL6ZPGSctcXVmujz7/WAc0rb9m2oV0cHQTtVjnq6orQnI/jg==} + '@oxc-resolver/binding-linux-arm64-gnu@11.16.2': + resolution: {integrity: sha512-xlMh4gNtplNQEwuF5icm69udC7un0WyzT5ywOeHrPMEsghKnLjXok2wZgAA7ocTm9+JsI+nVXIQa5XO1x+HPQg==} cpu: [arm64] os: [linux] - '@oxc-resolver/binding-linux-arm64-musl@11.15.0': - resolution: {integrity: sha512-JDv2/AycPF2qgzEiDeMJCcSzKNDm3KxNg0KKWipoKEMDFqfM7LxNwwSVyAOGmrYlE4l3dg290hOMsr9xG7jv9g==} + '@oxc-resolver/binding-linux-arm64-musl@11.16.2': + resolution: {integrity: sha512-OZs33QTMi0xmHv/4P0+RAKXJTBk7UcMH5tpTaCytWRXls/DGaJ48jOHmriQGK2YwUqXl+oneuNyPOUO0obJ+Hg==} cpu: [arm64] os: [linux] - '@oxc-resolver/binding-linux-ppc64-gnu@11.15.0': - resolution: {integrity: sha512-zbu9FhvBLW4KJxo7ElFvZWbSt4vP685Qc/Gyk/Ns3g2gR9qh2qWXouH8PWySy+Ko/qJ42+HJCLg+ZNcxikERfg==} + '@oxc-resolver/binding-linux-ppc64-gnu@11.16.2': + resolution: {integrity: sha512-UVyuhaV32dJGtF6fDofOcBstg9JwB2Jfnjfb8jGlu3xcG+TsubHRhuTwQ6JZ1sColNT1nMxBiu7zdKUEZi1kwg==} cpu: [ppc64] os: [linux] - '@oxc-resolver/binding-linux-riscv64-gnu@11.15.0': - resolution: {integrity: sha512-Kfleehe6B09C2qCnyIU01xLFqFXCHI4ylzkicfX/89j+gNHh9xyNdpEvit88Kq6i5tTGdavVnM6DQfOE2qNtlg==} + '@oxc-resolver/binding-linux-riscv64-gnu@11.16.2': + resolution: {integrity: sha512-YZZS0yv2q5nE1uL/Fk4Y7m9018DSEmDNSG8oJzy1TJjA1jx5HL52hEPxi98XhU6OYhSO/vC1jdkJeE8TIHugug==} cpu: [riscv64] os: [linux] - '@oxc-resolver/binding-linux-riscv64-musl@11.15.0': - resolution: {integrity: sha512-J7LPiEt27Tpm8P+qURDwNc8q45+n+mWgyys4/V6r5A8v5gDentHRGUx3iVk5NxdKhgoGulrzQocPTZVosq25Eg==} + '@oxc-resolver/binding-linux-riscv64-musl@11.16.2': + resolution: {integrity: sha512-9VYuypwtx4kt1lUcwJAH4dPmgJySh4/KxtAPdRoX2BTaZxVm/yEXHq0mnl/8SEarjzMvXKbf7Cm6UBgptm3DZw==} cpu: [riscv64] os: [linux] - '@oxc-resolver/binding-linux-s390x-gnu@11.15.0': - resolution: {integrity: sha512-+8/d2tAScPjVJNyqa7GPGnqleTB/XW9dZJQ2D/oIM3wpH3TG+DaFEXBbk4QFJ9K9AUGBhvQvWU2mQyhK/yYn3Q==} + '@oxc-resolver/binding-linux-s390x-gnu@11.16.2': + resolution: {integrity: sha512-3gbwQ+xlL5gpyzgSDdC8B4qIM4mZaPDLaFOi3c/GV7CqIdVJc5EZXW4V3T6xwtPBOpXPXfqQLbhTnUD4SqwJtA==} cpu: [s390x] os: [linux] - '@oxc-resolver/binding-linux-x64-gnu@11.15.0': - resolution: {integrity: sha512-xtvSzH7Nr5MCZI2FKImmOdTl9kzuQ51RPyLh451tvD2qnkg3BaqI9Ox78bTk57YJhlXPuxWSOL5aZhKAc9J6qg==} + '@oxc-resolver/binding-linux-x64-gnu@11.16.2': + resolution: {integrity: sha512-m0WcK0j54tSwWa+hQaJMScZdWneqE7xixp/vpFqlkbhuKW9dRHykPAFvSYg1YJ3MJgu9ZzVNpYHhPKJiEQq57Q==} cpu: [x64] os: [linux] - '@oxc-resolver/binding-linux-x64-musl@11.15.0': - resolution: {integrity: sha512-14YL1zuXj06+/tqsuUZuzL0T425WA/I4nSVN1kBXeC5WHxem6lQ+2HGvG+crjeJEqHgZUT62YIgj88W+8E7eyg==} + '@oxc-resolver/binding-linux-x64-musl@11.16.2': + resolution: {integrity: sha512-ZjUm3w96P2t47nWywGwj1A2mAVBI/8IoS7XHhcogWCfXnEI3M6NPIRQPYAZW4s5/u3u6w1uPtgOwffj2XIOb/g==} cpu: [x64] os: [linux] - '@oxc-resolver/binding-openharmony-arm64@11.15.0': - resolution: {integrity: sha512-/7Qli+1Wk93coxnrQaU8ySlICYN8HsgyIrzqjgIkQEpI//9eUeaeIHZptNl2fMvBGeXa7k2QgLbRNaBRgpnvMw==} + '@oxc-resolver/binding-openharmony-arm64@11.16.2': + resolution: {integrity: sha512-OFVQ2x3VenTp13nIl6HcQ/7dmhFmM9dg2EjKfHcOtYfrVLQdNR6THFU7GkMdmc8DdY1zLUeilHwBIsyxv5hkwQ==} cpu: [arm64] os: [openharmony] - '@oxc-resolver/binding-wasm32-wasi@11.15.0': - resolution: {integrity: sha512-q5rn2eIMQLuc/AVGR2rQKb2EVlgreATGG8xXg8f4XbbYCVgpxaq+dgMbiPStyNywW1MH8VU2T09UEm30UtOQvg==} + '@oxc-resolver/binding-wasm32-wasi@11.16.2': + resolution: {integrity: sha512-+O1sY3RrGyA2AqDnd3yaDCsqZqCblSTEpY7TbbaOaw0X7iIbGjjRLdrQk9StG3QSiZuBy9FdFwotIiSXtwvbAQ==} engines: {node: '>=14.0.0'} cpu: [wasm32] - '@oxc-resolver/binding-win32-arm64-msvc@11.15.0': - resolution: {integrity: sha512-yCAh2RWjU/8wWTxQDgGPgzV9QBv0/Ojb5ej1c/58iOjyTuy/J1ZQtYi2SpULjKmwIxLJdTiCHpMilauWimE31w==} + '@oxc-resolver/binding-win32-arm64-msvc@11.16.2': + resolution: {integrity: sha512-jMrMJL+fkx6xoSMFPOeyQ1ctTFjavWPOSZEKUY5PebDwQmC9cqEr4LhdTnGsOtFrWYLXlEU4xWeMdBoc/XKkOA==} cpu: [arm64] os: [win32] - '@oxc-resolver/binding-win32-ia32-msvc@11.15.0': - resolution: {integrity: sha512-lmXKb6lvA6M6QIbtYfgjd+AryJqExZVSY2bfECC18OPu7Lv1mHFF171Mai5l9hG3r4IhHPPIwT10EHoilSCYeA==} + '@oxc-resolver/binding-win32-ia32-msvc@11.16.2': + resolution: {integrity: sha512-tl0xDA5dcQplG2yg2ZhgVT578dhRFafaCfyqMEAXq8KNpor85nJ53C3PLpfxD2NKzPioFgWEexNsjqRi+kW2Mg==} cpu: [ia32] os: [win32] - '@oxc-resolver/binding-win32-x64-msvc@11.15.0': - resolution: {integrity: sha512-HZsfne0s/tGOcJK9ZdTGxsNU2P/dH0Shf0jqrPvsC6wX0Wk+6AyhSpHFLQCnLOuFQiHHU0ePfM8iYsoJb5hHpQ==} + '@oxc-resolver/binding-win32-x64-msvc@11.16.2': + resolution: {integrity: sha512-M7z0xjYQq1HdJk2DxTSLMvRMyBSI4wn4FXGcVQBsbAihgXevAReqwMdb593nmCK/OiFwSNcOaGIzUvzyzQ+95w==} cpu: [x64] os: [win32] @@ -7581,11 +7587,11 @@ packages: sqlite3: optional: true - drizzle-zod@0.5.1: - resolution: {integrity: sha512-C/8bvzUH/zSnVfwdSibOgFjLhtDtbKYmkbPbUCq46QZyZCH6kODIMSOgZ8R7rVjoI+tCj3k06MRJMDqsIeoS4A==} + drizzle-zod@0.8.3: + resolution: {integrity: sha512-66yVOuvGhKJnTdiqj1/Xaaz9/qzOdRJADpDa68enqS6g3t0kpNkwNYjUuaeXgZfO/UWuIM9HIhSlJ6C5ZraMww==} peerDependencies: - drizzle-orm: '>=0.23.13' - zod: '*' + drizzle-orm: '>=0.36.0' + zod: ^3.25.0 || ^4.0.0 dset@3.1.4: resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} @@ -8269,8 +8275,8 @@ packages: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} - import-in-the-middle@2.0.0: - resolution: {integrity: sha512-yNZhyQYqXpkT0AKq3F3KLasUSK4fHvebNH5hOsKQw2dhGSALvQ4U0BqUc5suziKvydO5u5hgN2hy1RJaho8U5A==} + import-in-the-middle@2.0.1: + resolution: {integrity: sha512-bruMpJ7xz+9jwGzrwEhWgvRrlKRYCRDBrfU+ur3FcasYXLJDxTruJ//8g2Noj+QFyRBeqbpj8Bhn4Fbw6HjvhA==} import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} @@ -9328,8 +9334,8 @@ packages: outvariant@1.4.3: resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} - oxc-resolver@11.15.0: - resolution: {integrity: sha512-Hk2J8QMYwmIO9XTCUiOH00+Xk2/+aBxRUnhrSlANDyCnLYc32R1WSIq1sU2yEdlqd53FfMpPEpnBYIKQMzliJw==} + oxc-resolver@11.16.2: + resolution: {integrity: sha512-Uy76u47vwhhF7VAmVY61Srn+ouiOobf45MU9vGct9GD2ARy6hKoqEElyHDB0L+4JOM6VLuZ431KiLwyjI/A21g==} oxfmt@0.18.0: resolution: {integrity: sha512-XqVS+LQi7ARsFlIftB69+jGN2qQaJNBjQU2b9ZQYt+iaUV9digh+dBIsU0isQIZhaQ1ihxGFfsTYQXE/Oak8Qw==} @@ -10211,6 +10217,7 @@ packages: source-map@0.8.0-beta.0: resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} engines: {node: '>= 8'} + deprecated: The work that was done in this beta branch won't be included in future versions space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} @@ -11351,10 +11358,10 @@ snapshots: transitivePeerDependencies: - supports-color - '@asteasolutions/zod-to-openapi@7.3.4(zod@3.25.76)': + '@asteasolutions/zod-to-openapi@8.2.0(zod@4.1.13)': dependencies: openapi3-ts: 4.5.0 - zod: 3.25.76 + zod: 4.1.13 '@astro-community/astro-embed-twitter@0.5.9(astro@5.13.7(@types/node@24.10.1)(jiti@2.6.1)(lightningcss@1.30.1)(rollup@4.53.3)(terser@5.44.1)(typescript@5.9.3)(yaml@2.8.1))': dependencies: @@ -12382,9 +12389,9 @@ snapshots: transitivePeerDependencies: - encoding - '@chronark/zod-bird@0.3.6': + '@chronark/zod-bird@1.0.0(zod@4.1.13)': dependencies: - zod: 3.25.76 + zod: 4.1.13 '@cspotcode/source-map-support@0.8.1': dependencies: @@ -12783,17 +12790,23 @@ snapshots: hono: 4.5.3 toucan-js: 4.1.1 - '@hono/zod-openapi@0.15.1(hono@4.5.3)(zod@3.25.76)': + '@hono/zod-openapi@1.1.5(hono@4.5.3)(zod@4.1.13)': dependencies: - '@asteasolutions/zod-to-openapi': 7.3.4(zod@3.25.76) - '@hono/zod-validator': 0.2.2(hono@4.5.3)(zod@3.25.76) + '@asteasolutions/zod-to-openapi': 8.2.0(zod@4.1.13) + '@hono/zod-validator': 0.7.6(hono@4.5.3)(zod@4.1.13) hono: 4.5.3 - zod: 3.25.76 + openapi3-ts: 4.5.0 + zod: 4.1.13 - '@hono/zod-validator@0.2.2(hono@4.5.3)(zod@3.25.76)': + '@hono/zod-validator@0.2.2(hono@4.5.3)(zod@4.1.13)': dependencies: hono: 4.5.3 - zod: 3.25.76 + zod: 4.1.13 + + '@hono/zod-validator@0.7.6(hono@4.5.3)(zod@4.1.13)': + dependencies: + hono: 4.5.3 + zod: 4.1.13 '@hookform/devtools@4.4.0(@types/react@19.2.2)(react-dom@19.2.2(react@19.2.2))(react@19.2.2)': dependencies: @@ -12811,7 +12824,7 @@ snapshots: - '@types/react' - supports-color - '@hookform/resolvers@4.1.3(react-hook-form@7.68.0(react@19.2.2))': + '@hookform/resolvers@5.1.0(react-hook-form@7.68.0(react@19.2.2))': dependencies: '@standard-schema/utils': 0.3.0 react-hook-form: 7.68.0(react@19.2.2) @@ -13224,7 +13237,7 @@ snapshots: outvariant: 1.4.3 strict-event-emitter: 0.5.1 - '@napi-rs/wasm-runtime@1.1.0': + '@napi-rs/wasm-runtime@1.1.1': dependencies: '@emnapi/core': 1.7.1 '@emnapi/runtime': 1.7.1 @@ -13504,7 +13517,7 @@ snapshots: dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/api-logs': 0.208.0 - import-in-the-middle: 2.0.0 + import-in-the-middle: 2.0.1 require-in-the-middle: 8.0.1 transitivePeerDependencies: - supports-color @@ -13533,66 +13546,66 @@ snapshots: '@oslojs/encoding@1.1.0': {} - '@oxc-resolver/binding-android-arm-eabi@11.15.0': + '@oxc-resolver/binding-android-arm-eabi@11.16.2': optional: true - '@oxc-resolver/binding-android-arm64@11.15.0': + '@oxc-resolver/binding-android-arm64@11.16.2': optional: true - '@oxc-resolver/binding-darwin-arm64@11.15.0': + '@oxc-resolver/binding-darwin-arm64@11.16.2': optional: true - '@oxc-resolver/binding-darwin-x64@11.15.0': + '@oxc-resolver/binding-darwin-x64@11.16.2': optional: true - '@oxc-resolver/binding-freebsd-x64@11.15.0': + '@oxc-resolver/binding-freebsd-x64@11.16.2': optional: true - '@oxc-resolver/binding-linux-arm-gnueabihf@11.15.0': + '@oxc-resolver/binding-linux-arm-gnueabihf@11.16.2': optional: true - '@oxc-resolver/binding-linux-arm-musleabihf@11.15.0': + '@oxc-resolver/binding-linux-arm-musleabihf@11.16.2': optional: true - '@oxc-resolver/binding-linux-arm64-gnu@11.15.0': + '@oxc-resolver/binding-linux-arm64-gnu@11.16.2': optional: true - '@oxc-resolver/binding-linux-arm64-musl@11.15.0': + '@oxc-resolver/binding-linux-arm64-musl@11.16.2': optional: true - '@oxc-resolver/binding-linux-ppc64-gnu@11.15.0': + '@oxc-resolver/binding-linux-ppc64-gnu@11.16.2': optional: true - '@oxc-resolver/binding-linux-riscv64-gnu@11.15.0': + '@oxc-resolver/binding-linux-riscv64-gnu@11.16.2': optional: true - '@oxc-resolver/binding-linux-riscv64-musl@11.15.0': + '@oxc-resolver/binding-linux-riscv64-musl@11.16.2': optional: true - '@oxc-resolver/binding-linux-s390x-gnu@11.15.0': + '@oxc-resolver/binding-linux-s390x-gnu@11.16.2': optional: true - '@oxc-resolver/binding-linux-x64-gnu@11.15.0': + '@oxc-resolver/binding-linux-x64-gnu@11.16.2': optional: true - '@oxc-resolver/binding-linux-x64-musl@11.15.0': + '@oxc-resolver/binding-linux-x64-musl@11.16.2': optional: true - '@oxc-resolver/binding-openharmony-arm64@11.15.0': + '@oxc-resolver/binding-openharmony-arm64@11.16.2': optional: true - '@oxc-resolver/binding-wasm32-wasi@11.15.0': + '@oxc-resolver/binding-wasm32-wasi@11.16.2': dependencies: - '@napi-rs/wasm-runtime': 1.1.0 + '@napi-rs/wasm-runtime': 1.1.1 optional: true - '@oxc-resolver/binding-win32-arm64-msvc@11.15.0': + '@oxc-resolver/binding-win32-arm64-msvc@11.16.2': optional: true - '@oxc-resolver/binding-win32-ia32-msvc@11.15.0': + '@oxc-resolver/binding-win32-ia32-msvc@11.16.2': optional: true - '@oxc-resolver/binding-win32-x64-msvc@11.15.0': + '@oxc-resolver/binding-win32-x64-msvc@11.16.2': optional: true '@oxfmt/darwin-arm64@0.18.0': @@ -15271,7 +15284,7 @@ snapshots: '@opentelemetry/semantic-conventions': 1.38.0 '@sentry/core': 10.31.0 '@sentry/opentelemetry': 10.31.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0) - import-in-the-middle: 2.0.0 + import-in-the-middle: 2.0.1 transitivePeerDependencies: - supports-color @@ -15310,7 +15323,7 @@ snapshots: '@sentry/core': 10.31.0 '@sentry/node-core': 10.31.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/instrumentation@0.208.0(@opentelemetry/api@1.9.0))(@opentelemetry/resources@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0) '@sentry/opentelemetry': 10.31.0(@opentelemetry/api@1.9.0)(@opentelemetry/context-async-hooks@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/core@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.2.0(@opentelemetry/api@1.9.0))(@opentelemetry/semantic-conventions@1.38.0) - import-in-the-middle: 2.0.0 + import-in-the-middle: 2.0.1 minimatch: 9.0.5 transitivePeerDependencies: - supports-color @@ -15720,26 +15733,21 @@ snapshots: dependencies: tslib: 2.8.1 - '@t3-oss/env-core@0.13.10(typescript@5.9.3)(zod@3.25.76)': - optionalDependencies: - typescript: 5.9.3 - zod: 3.25.76 - '@t3-oss/env-core@0.13.10(typescript@5.9.3)(zod@4.1.13)': optionalDependencies: typescript: 5.9.3 zod: 4.1.13 - '@t3-oss/env-core@0.7.0(typescript@5.9.3)(zod@3.25.76)': + '@t3-oss/env-core@0.7.0(typescript@5.9.3)(zod@4.1.13)': dependencies: - zod: 3.25.76 + zod: 4.1.13 optionalDependencies: typescript: 5.9.3 - '@t3-oss/env-nextjs@0.7.0(typescript@5.9.3)(zod@3.25.76)': + '@t3-oss/env-nextjs@0.7.0(typescript@5.9.3)(zod@4.1.13)': dependencies: - '@t3-oss/env-core': 0.7.0(typescript@5.9.3)(zod@3.25.76) - zod: 3.25.76 + '@t3-oss/env-core': 0.7.0(typescript@5.9.3)(zod@4.1.13) + zod: 4.1.13 optionalDependencies: typescript: 5.9.3 @@ -16264,7 +16272,7 @@ snapshots: '@unkey/api@2.2.0': dependencies: - zod: 3.25.76 + zod: 4.1.13 '@upstash/core-analytics@0.0.6': dependencies: @@ -17324,10 +17332,10 @@ snapshots: '@types/pg': 8.15.6 bun-types: 1.3.5 - drizzle-zod@0.5.1(drizzle-orm@0.44.4(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(bun-types@1.3.5))(zod@3.25.76): + drizzle-zod@0.8.3(drizzle-orm@0.44.4(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(bun-types@1.3.5))(zod@4.1.13): dependencies: drizzle-orm: 0.44.4(@libsql/client@0.15.15)(@opentelemetry/api@1.9.0)(@types/pg@8.15.6)(bun-types@1.3.5) - zod: 3.25.76 + zod: 4.1.13 dset@3.1.4: {} @@ -18345,7 +18353,7 @@ snapshots: parent-module: 1.0.1 resolve-from: 4.0.0 - import-in-the-middle@2.0.0: + import-in-the-middle@2.0.1: dependencies: acorn: 8.15.0 acorn-import-attributes: 1.9.5(acorn@8.15.0) @@ -18599,7 +18607,7 @@ snapshots: jiti: 2.6.1 js-yaml: 4.1.1 minimist: 1.2.8 - oxc-resolver: 11.15.0 + oxc-resolver: 11.16.2 picocolors: 1.1.1 picomatch: 4.0.3 smol-toml: 1.5.2 @@ -19617,28 +19625,28 @@ snapshots: outvariant@1.4.3: {} - oxc-resolver@11.15.0: + oxc-resolver@11.16.2: optionalDependencies: - '@oxc-resolver/binding-android-arm-eabi': 11.15.0 - '@oxc-resolver/binding-android-arm64': 11.15.0 - '@oxc-resolver/binding-darwin-arm64': 11.15.0 - '@oxc-resolver/binding-darwin-x64': 11.15.0 - '@oxc-resolver/binding-freebsd-x64': 11.15.0 - '@oxc-resolver/binding-linux-arm-gnueabihf': 11.15.0 - '@oxc-resolver/binding-linux-arm-musleabihf': 11.15.0 - '@oxc-resolver/binding-linux-arm64-gnu': 11.15.0 - '@oxc-resolver/binding-linux-arm64-musl': 11.15.0 - '@oxc-resolver/binding-linux-ppc64-gnu': 11.15.0 - '@oxc-resolver/binding-linux-riscv64-gnu': 11.15.0 - '@oxc-resolver/binding-linux-riscv64-musl': 11.15.0 - '@oxc-resolver/binding-linux-s390x-gnu': 11.15.0 - '@oxc-resolver/binding-linux-x64-gnu': 11.15.0 - '@oxc-resolver/binding-linux-x64-musl': 11.15.0 - '@oxc-resolver/binding-openharmony-arm64': 11.15.0 - '@oxc-resolver/binding-wasm32-wasi': 11.15.0 - '@oxc-resolver/binding-win32-arm64-msvc': 11.15.0 - '@oxc-resolver/binding-win32-ia32-msvc': 11.15.0 - '@oxc-resolver/binding-win32-x64-msvc': 11.15.0 + '@oxc-resolver/binding-android-arm-eabi': 11.16.2 + '@oxc-resolver/binding-android-arm64': 11.16.2 + '@oxc-resolver/binding-darwin-arm64': 11.16.2 + '@oxc-resolver/binding-darwin-x64': 11.16.2 + '@oxc-resolver/binding-freebsd-x64': 11.16.2 + '@oxc-resolver/binding-linux-arm-gnueabihf': 11.16.2 + '@oxc-resolver/binding-linux-arm-musleabihf': 11.16.2 + '@oxc-resolver/binding-linux-arm64-gnu': 11.16.2 + '@oxc-resolver/binding-linux-arm64-musl': 11.16.2 + '@oxc-resolver/binding-linux-ppc64-gnu': 11.16.2 + '@oxc-resolver/binding-linux-riscv64-gnu': 11.16.2 + '@oxc-resolver/binding-linux-riscv64-musl': 11.16.2 + '@oxc-resolver/binding-linux-s390x-gnu': 11.16.2 + '@oxc-resolver/binding-linux-x64-gnu': 11.16.2 + '@oxc-resolver/binding-linux-x64-musl': 11.16.2 + '@oxc-resolver/binding-openharmony-arm64': 11.16.2 + '@oxc-resolver/binding-wasm32-wasi': 11.16.2 + '@oxc-resolver/binding-win32-arm64-msvc': 11.16.2 + '@oxc-resolver/binding-win32-ia32-msvc': 11.16.2 + '@oxc-resolver/binding-win32-x64-msvc': 11.16.2 oxfmt@0.18.0: dependencies: