diff --git a/utils/env.ts b/utils/env.ts new file mode 100644 index 0000000..4fe93df --- /dev/null +++ b/utils/env.ts @@ -0,0 +1,108 @@ +// Environment utility to safely access environment variables +// Compatible with both Vite (browser) and Node.js (Jest/server) + +export interface EnvConfig { + VITE_COUCHDB_URL?: string; + VITE_COUCHDB_USERNAME?: string; + VITE_COUCHDB_PASSWORD?: string; + VITE_MAILGUN_API_KEY?: string; + VITE_MAILGUN_DOMAIN?: string; + VITE_MAILGUN_BASE_URL?: string; + VITE_MAILGUN_FROM_NAME?: string; + VITE_MAILGUN_FROM_EMAIL?: string; + NODE_ENV?: string; + COUCHDB_URL?: string; + [key: string]: string | undefined; +} + +/** + * Safely get environment variables from various sources + * Works in both browser (Vite) and Node.js (Jest/server) environments + */ +export function getEnv(): EnvConfig { + let env: EnvConfig = {}; + + // Try to get from import.meta.env (Vite/browser) + try { + if (typeof globalThis !== 'undefined' && 'import' in globalThis) { + const importMeta = ( + globalThis as { import?: { meta?: { env?: Record } } } + ).import?.meta; + if (importMeta?.env) { + env = { ...env, ...importMeta.env }; + } + } + } catch (_e) { + // Ignore errors accessing import.meta + } + + // Try to get from process.env (Node.js) + try { + if (typeof process !== 'undefined' && process.env) { + env = { ...env, ...process.env }; + } + } catch (_e) { + // Ignore errors accessing process.env + } + + return env; +} + +/** + * Get a specific environment variable with optional fallback + */ +export function getEnvVar(key: string, fallback?: string): string | undefined { + const env = getEnv(); + return env[key] || fallback; +} + +/** + * Check if we're running in a browser environment + */ +export function isBrowser(): boolean { + return typeof window !== 'undefined'; +} + +/** + * Check if we're running in a Node.js environment + */ +export function isNode(): boolean { + return typeof process !== 'undefined' && Boolean(process.versions?.node); +} + +/** + * Check if we're running in a test environment + */ +export function isTest(): boolean { + const env = getEnv(); + + // Check for Jest environment + if ( + typeof global !== 'undefined' && + 'expect' in global && + 'describe' in global + ) { + return true; + } + + // Check for Node.js test environment variables + if (typeof process !== 'undefined' && process.env) { + if (process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID) { + return true; + } + } + + // Check environment variables + return env.NODE_ENV === 'test'; +} + +/** + * Check if we're running in production + */ +export function isProduction(): boolean { + const env = getEnv(); + return ( + env.NODE_ENV === 'production' || + (typeof process !== 'undefined' && process.env?.NODE_ENV === 'production') + ); +}