- 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
109 lines
2.6 KiB
TypeScript
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')
|
|
);
|
|
}
|