diff --git a/packages/env/index.ts b/packages/env/index.ts index b9a06968..87135c5e 100644 --- a/packages/env/index.ts +++ b/packages/env/index.ts @@ -1,15 +1,33 @@ import { createEnv } from '@t3-oss/env-nextjs'; import { z } from 'zod'; -const server: Parameters[0]['server'] = { - CLERK_SECRET_KEY: z.string().min(1).startsWith('sk_'), - CLERK_WEBHOOK_SECRET: z.string().min(1).startsWith('whsec_'), - RESEND_AUDIENCE_ID: z.string().min(1), - RESEND_FROM: z.string().min(1).email(), +// Define service enable flags +const baseSchema = { + ENABLE_CLERK: z.boolean().default(false), + ENABLE_STRIPE: z.boolean().default(false), + ENABLE_RESEND: z.boolean().default(false), +}; + +// Define service-specific schemas +const clerkSchema = { + CLERK_SECRET_KEY: z.string().min(1).startsWith('sk_').optional(), + CLERK_WEBHOOK_SECRET: z.string().min(1).startsWith('whsec_').optional(), +}; + +const stripeSchema = { + STRIPE_SECRET_KEY: z.string().min(1).startsWith('sk_').optional(), + STRIPE_WEBHOOK_SECRET: z.string().min(1).startsWith('whsec_').optional(), +}; + +const resendSchema = { + RESEND_AUDIENCE_ID: z.string().min(1).optional(), + RESEND_FROM: z.string().min(1).email().optional(), + RESEND_TOKEN: z.string().min(1).startsWith('re_').optional(), +}; + +// Add other server variables +const serverBaseSchema = { DATABASE_URL: z.string().min(1).url(), - RESEND_TOKEN: z.string().min(1).startsWith('re_'), - STRIPE_SECRET_KEY: z.string().min(1).startsWith('sk_'), - STRIPE_WEBHOOK_SECRET: z.string().min(1).startsWith('whsec_'), BETTERSTACK_API_KEY: z.string().min(1), BETTERSTACK_URL: z.string().min(1).url(), ARCJET_KEY: z.string().min(1).startsWith('ajkey_'), @@ -19,18 +37,24 @@ const server: Parameters[0]['server'] = { .min(1) .startsWith('sk_') .or(z.string().min(1).startsWith('testsk_')), - - // Added by Sentry Integration, Vercel Marketplace SENTRY_ORG: z.string().min(1).optional(), SENTRY_PROJECT: z.string().min(1).optional(), - - // Added by Vercel VERCEL: z.string().optional(), NEXT_RUNTIME: z.enum(['nodejs', 'edge']).optional(), FLAGS_SECRET: z.string().min(1), }; -const client: Parameters[0]['client'] = { +// Dynamically build the server schema based on enabled services +const server = { + ...baseSchema, + ...serverBaseSchema, + ...(process.env.ENABLE_CLERK === 'true' ? clerkSchema : {}), + ...(process.env.ENABLE_STRIPE === 'true' ? stripeSchema : {}), + ...(process.env.ENABLE_RESEND === 'true' ? resendSchema : {}), +}; + +// Define client schema +const client = { NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string().min(1).startsWith('pk_'), NEXT_PUBLIC_CLERK_SIGN_IN_URL: z.string().min(1).startsWith('/'), NEXT_PUBLIC_CLERK_SIGN_UP_URL: z.string().min(1).startsWith('/'), @@ -42,15 +66,17 @@ const client: Parameters[0]['client'] = { NEXT_PUBLIC_GA_MEASUREMENT_ID: z.string().min(1).startsWith('G-'), NEXT_PUBLIC_POSTHOG_KEY: z.string().min(1).startsWith('phc_'), NEXT_PUBLIC_POSTHOG_HOST: z.string().min(1).url(), - - // Added by Vercel NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL: z.string().min(1).url(), }; +// Export the environment variables export const env = createEnv({ client, server, runtimeEnv: { + ENABLE_CLERK: process.env.ENABLE_CLERK === 'true', + ENABLE_STRIPE: process.env.ENABLE_STRIPE === 'true', + ENABLE_RESEND: process.env.ENABLE_RESEND === 'true', CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY, CLERK_WEBHOOK_SECRET: process.env.CLERK_WEBHOOK_SECRET, RESEND_AUDIENCE_ID: process.env.RESEND_AUDIENCE_ID, @@ -69,21 +95,17 @@ export const env = createEnv({ NEXT_RUNTIME: process.env.NEXT_RUNTIME, FLAGS_SECRET: process.env.FLAGS_SECRET, SVIX_TOKEN: process.env.SVIX_TOKEN, - NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: - process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, + NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, NEXT_PUBLIC_CLERK_SIGN_IN_URL: process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL, NEXT_PUBLIC_CLERK_SIGN_UP_URL: process.env.NEXT_PUBLIC_CLERK_SIGN_UP_URL, - NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL: - process.env.NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL, - NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL: - process.env.NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL, + NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL: process.env.NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL, + NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL: process.env.NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL, NEXT_PUBLIC_APP_URL: process.env.NEXT_PUBLIC_APP_URL, NEXT_PUBLIC_WEB_URL: process.env.NEXT_PUBLIC_WEB_URL, NEXT_PUBLIC_DOCS_URL: process.env.NEXT_PUBLIC_DOCS_URL, NEXT_PUBLIC_GA_MEASUREMENT_ID: process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID, NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY, NEXT_PUBLIC_POSTHOG_HOST: process.env.NEXT_PUBLIC_POSTHOG_HOST, - NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL: - process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL, + NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL: process.env.NEXT_PUBLIC_VERCEL_PROJECT_PRODUCTION_URL, }, });