2025-12-05 17:24:16 +01:00
|
|
|
import * as z from 'zod';
|
2025-06-09 01:38:57 +01:00
|
|
|
|
|
|
|
|
const envSchema = z.object({
|
2026-03-09 11:18:22 +01:00
|
|
|
// Legacy Cloudflare R2 config (used when OBJECT_STORAGE_* vars are absent)
|
2025-06-09 01:38:57 +01:00
|
|
|
CLOUDFLARE_ACCESS_KEY: z.string().optional(),
|
|
|
|
|
CLOUDFLARE_ACCOUNT_ID: z.string().optional(),
|
2025-09-21 19:35:41 +01:00
|
|
|
CLOUDFLARE_BUCKET_DOMAIN: z.string().optional(),
|
|
|
|
|
CLOUDFLARE_RENDERING_API_KEY: z.string().optional(),
|
|
|
|
|
CLOUDFLARE_SECRET_ACCESS_KEY: z.string().optional(),
|
2025-12-02 09:54:38 +01:00
|
|
|
CLOUDFLARE_IMAGE_BUCKET_DOMAIN: z.string().optional(),
|
2026-03-09 11:18:22 +01:00
|
|
|
// S3-compatible storage (MinIO, AWS S3, or other S3-compatible backends)
|
|
|
|
|
OBJECT_STORAGE_ENDPOINT: z.string().optional(),
|
|
|
|
|
OBJECT_STORAGE_REGION: z.string().optional(),
|
|
|
|
|
OBJECT_STORAGE_ACCESS_KEY_ID: z.string().optional(),
|
|
|
|
|
OBJECT_STORAGE_SECRET_ACCESS_KEY: z.string().optional(),
|
|
|
|
|
OBJECT_STORAGE_FORCE_PATH_STYLE: z.string().optional(),
|
|
|
|
|
OBJECT_STORAGE_BUCKET_VIDEOS: z.string().optional(),
|
|
|
|
|
OBJECT_STORAGE_BUCKET_DOCUMENTS: z.string().optional(),
|
|
|
|
|
OBJECT_STORAGE_BUCKET_MEDIA: z.string().optional(),
|
|
|
|
|
/** Public URL base for media bucket (images, thumbnails). Required for image uploads. */
|
|
|
|
|
OBJECT_STORAGE_MEDIA_PUBLIC_BASE_URL: z.string().optional(),
|
|
|
|
|
/** Optional: endpoint for presigned URLs when different from internal (e.g. browser-reachable) */
|
|
|
|
|
OBJECT_STORAGE_PUBLIC_ENDPOINT: z.string().optional(),
|
2025-09-21 19:35:41 +01:00
|
|
|
NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
|
|
|
|
|
OPENAPI_URL: z.string().optional(),
|
|
|
|
|
PORT: z.string().optional(),
|
|
|
|
|
REDIS_URL: z.string().optional(),
|
2026-03-09 11:18:22 +01:00
|
|
|
PUBLIC_SERVER_URL: z.string().optional(),
|
2025-06-09 01:38:57 +01:00
|
|
|
SMTP_HOST: z.string().optional(),
|
|
|
|
|
SMTP_PASSWORD: z.string().optional(),
|
2025-09-21 19:35:41 +01:00
|
|
|
SMTP_PORT: z.string().optional(),
|
|
|
|
|
SMTP_SENDER: z.string().optional(),
|
|
|
|
|
SMTP_USER: z.string().optional(),
|
2025-11-24 01:00:50 +01:00
|
|
|
ZOHO_TOKEN: z.string().optional(),
|
2025-12-02 09:54:38 +01:00
|
|
|
TRUSTED_ORIGINS: z.string().optional(),
|
2026-03-09 11:18:22 +01:00
|
|
|
PRIVATE_SERVER_KEY: z.string().optional(),
|
|
|
|
|
PROJECT_ID_VERCEL: z.string().optional(),
|
|
|
|
|
TEAM_ID_VERCEL: z.string().optional(),
|
|
|
|
|
AUTH_BEARER_TOKEN: z.string().optional(),
|
|
|
|
|
UNSPLASH_API_KEY: z.string().optional(),
|
|
|
|
|
/** When 'true', instance runs in self-hosted mode: single org, auto-enroll as student, no org switching */
|
|
|
|
|
PUBLIC_IS_SELFHOSTED: z.string().optional(),
|
|
|
|
|
/** License key for enterprise features (SSO, token-auth, no-tracking, etc.) */
|
|
|
|
|
LICENSE_KEY: z.string().optional()
|
2025-06-09 01:38:57 +01:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
export const env = envSchema.parse(process.env);
|