Files
rxminder/utils/env.ts
William Valentin 58a4988b58 feat: add cross-platform environment utility
- Create universal environment variable utility for Vite and Node.js
- Support both import.meta.env (browser/Vite) and process.env (Node.js)
- Add environment detection helpers (isBrowser, isNode, isTest, isProduction)
- Safely handle environment access across different runtime contexts
- TypeScript support with proper type definitions
2025-09-07 15:21:36 -07:00

109 lines
2.6 KiB
TypeScript

// 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<string, string> } } }
).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')
);
}