From 40b5c98e515464e587bc9fb9c5ee21ad0eb1b70c Mon Sep 17 00:00:00 2001 From: nxtkofi Date: Tue, 21 Apr 2026 21:09:05 +0200 Subject: [PATCH] feat(env): add Zod env validation and update auth-server Add src/lib/env.ts with runtime Zod validation for NEXT_PUBLIC_* variables. Update auth-server to use validated env instead of process.env directly. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus --- src/lib/auth-server.ts | 6 ++++-- src/lib/env.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/lib/env.ts diff --git a/src/lib/auth-server.ts b/src/lib/auth-server.ts index a34a50e..746650a 100644 --- a/src/lib/auth-server.ts +++ b/src/lib/auth-server.ts @@ -1,5 +1,7 @@ import { convexBetterAuthNextJs } from '@convex-dev/better-auth/nextjs'; +import { env } from './env'; + export const { handler, preloadAuthQuery, @@ -9,6 +11,6 @@ export const { fetchAuthMutation, fetchAuthAction, } = convexBetterAuthNextJs({ - convexUrl: process.env.NEXT_PUBLIC_CONVEX_URL!, - convexSiteUrl: process.env.NEXT_PUBLIC_CONVEX_SITE_URL!, + convexUrl: env.NEXT_PUBLIC_CONVEX_URL, + convexSiteUrl: env.NEXT_PUBLIC_CONVEX_SITE_URL, }); diff --git a/src/lib/env.ts b/src/lib/env.ts new file mode 100644 index 0000000..553993f --- /dev/null +++ b/src/lib/env.ts @@ -0,0 +1,35 @@ +import { z } from 'zod/v4'; + +const serverSchema = z.object({ + NEXT_PUBLIC_CONVEX_URL: z.string().url(), + NEXT_PUBLIC_CONVEX_SITE_URL: z.string().url(), + NEXT_PUBLIC_SITE_URL: z.string().url(), +}); + +const clientSchema = z.object({ + NEXT_PUBLIC_CONVEX_URL: z.string().url(), + NEXT_PUBLIC_CONVEX_SITE_URL: z.string().url(), + NEXT_PUBLIC_SITE_URL: z.string().url(), +}); + +const processEnv = { + NEXT_PUBLIC_CONVEX_URL: process.env.NEXT_PUBLIC_CONVEX_URL, + NEXT_PUBLIC_CONVEX_SITE_URL: process.env.NEXT_PUBLIC_CONVEX_SITE_URL, + NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL, +}; + +const parsed = serverSchema.safeParse(processEnv); + +if (!parsed.success) { + console.error( + 'Invalid environment variables:', + parsed.error.flatten().fieldErrors, + ); + throw new Error('Invalid environment variables'); +} + +export const env = parsed.data; + +export function getClientEnv() { + return clientSchema.parse(processEnv); +}