{"version":3,"file":"environment-config.mjs","sources":["../../../src/lib/config/environment-config.ts"],"sourcesContent":["/**\n * @fileoverview Environment-specific configuration management.\n *\n * Provides utilities for:\n * - Environment detection\n * - Environment-specific overrides\n * - Environment variable parsing\n * - Safe defaults per environment\n *\n * @module config/environment-config\n *\n * @example\n * ```typescript\n * const envConfig = new EnvironmentConfig();\n * const config = envConfig.resolve(baseConfig, {\n *   development: { api: { timeout: 30000 } },\n *   production: { api: { timeout: 10000 } },\n * });\n * ```\n */\n\nimport type {\n  ConfigRecord,\n  Environment,\n  EnvironmentConfig as EnvironmentConfigType,\n} from './types';\nimport { ConfigMerger } from './config-merger';\n\n// ============================================================================\n// Environment Detection\n// ============================================================================\n\n/**\n * Detect the current environment.\n */\nexport function detectEnvironment(): Environment {\n  // Check import.meta.env (Vite)\n  const importMetaMode = import.meta?.env?.MODE;\n  if (importMetaMode !== undefined && importMetaMode !== '') {\n    return normalizeEnvironment(importMetaMode);\n  }\n\n  // Check process.env (Node.js, CRA)\n  if (\n    typeof process !== 'undefined' &&\n    process.env?.NODE_ENV !== undefined &&\n    process.env.NODE_ENV !== ''\n  ) {\n    return normalizeEnvironment(process.env.NODE_ENV);\n  }\n\n  // Check window.__ENV__ (runtime injection)\n  const windowEnv =\n    typeof window !== 'undefined' ? (window as { __ENV__?: string }).__ENV__ : undefined;\n  if (windowEnv != null && windowEnv !== '') {\n    return normalizeEnvironment(windowEnv);\n  }\n\n  // Default to development\n  return 'development';\n}\n\n/**\n * Normalize environment string to standard values.\n */\nfunction normalizeEnvironment(env: string): Environment {\n  const normalized = env.toLowerCase().trim();\n\n  switch (normalized) {\n    case 'prod':\n    case 'production':\n      return 'production';\n    case 'stage':\n    case 'staging':\n      return 'staging';\n    case 'test':\n    case 'testing':\n      return 'test';\n    case 'dev':\n    case 'development':\n    default:\n      return 'development';\n  }\n}\n\n// ============================================================================\n// Environment Checks\n// ============================================================================\n\n/**\n * Check if running in development.\n */\nexport function isDevelopment(): boolean {\n  return detectEnvironment() === 'development';\n}\n\n/**\n * Check if running in production.\n */\nexport function isProduction(): boolean {\n  return detectEnvironment() === 'production';\n}\n\n/**\n * Check if running in staging.\n */\nexport function isStaging(): boolean {\n  return detectEnvironment() === 'staging';\n}\n\n/**\n * Check if running in test.\n */\nexport function isTest(): boolean {\n  return detectEnvironment() === 'test';\n}\n\n/**\n * Check if running in browser.\n */\nexport function isBrowser(): boolean {\n  return typeof window !== 'undefined';\n}\n\n/**\n * Check if running on server.\n */\nexport function isServer(): boolean {\n  return typeof window === 'undefined';\n}\n\n// ============================================================================\n// Environment Config Manager\n// ============================================================================\n\n/**\n * Manager for environment-specific configuration.\n */\nexport class EnvironmentConfigManager<T extends ConfigRecord = ConfigRecord> {\n  private environment: Environment;\n  private merger: ConfigMerger;\n\n  constructor(environment?: Environment) {\n    this.environment = environment ?? detectEnvironment();\n    this.merger = new ConfigMerger({ strategy: 'deep' });\n  }\n\n  /**\n   * Get the current environment.\n   */\n  getEnvironment(): Environment {\n    return this.environment;\n  }\n\n  /**\n   * Set the environment (for testing).\n   */\n  setEnvironment(env: Environment): void {\n    this.environment = env;\n  }\n\n  /**\n   * Resolve configuration with environment overrides.\n   */\n  resolve(baseConfig: T, envOverrides: EnvironmentConfigType<T>): T {\n    const overrides = envOverrides[this.environment] as T | undefined;\n\n    if (!overrides) {\n      return baseConfig;\n    }\n\n    return this.merger.mergeTwo(baseConfig, overrides as unknown as ConfigRecord) as T;\n  }\n\n  /**\n   * Get environment-specific value.\n   */\n  select<V>(options: { [K in Environment]?: V } & { default: V }): V {\n    return options[this.environment] ?? options.default;\n  }\n\n  /**\n   * Create environment-aware configuration factory.\n   */\n  createFactory<C extends ConfigRecord>(factory: (env: Environment) => C): () => C {\n    return () => factory(this.environment);\n  }\n}\n\n// ============================================================================\n// Environment-Specific Defaults\n// ============================================================================\n\n/**\n * Common configuration defaults per environment.\n */\nexport const environmentDefaults: Record<Environment, Partial<ConfigRecord>> = {\n  development: {\n    debug: true,\n    logLevel: 'debug',\n    apiTimeout: 30000,\n    cacheEnabled: false,\n    analyticsEnabled: false,\n    errorReportingEnabled: false,\n    performanceMonitoring: false,\n  },\n  staging: {\n    debug: true,\n    logLevel: 'info',\n    apiTimeout: 15000,\n    cacheEnabled: true,\n    analyticsEnabled: true,\n    errorReportingEnabled: true,\n    performanceMonitoring: true,\n  },\n  production: {\n    debug: false,\n    logLevel: 'error',\n    apiTimeout: 10000,\n    cacheEnabled: true,\n    analyticsEnabled: true,\n    errorReportingEnabled: true,\n    performanceMonitoring: true,\n  },\n  test: {\n    debug: false,\n    logLevel: 'error',\n    apiTimeout: 5000,\n    cacheEnabled: false,\n    analyticsEnabled: false,\n    errorReportingEnabled: false,\n    performanceMonitoring: false,\n  },\n};\n\n/**\n * Get environment defaults.\n */\nexport function getEnvironmentDefaults(env?: Environment): Partial<ConfigRecord> {\n  return environmentDefaults[env ?? detectEnvironment()];\n}\n\n// ============================================================================\n// Environment Variable Helpers\n// ============================================================================\n\n/**\n * Get an environment variable with type coercion.\n */\nexport function getEnvVar(name: string, defaultValue?: string): string | undefined {\n  // Try import.meta.env (Vite)\n  const importMetaEnv = import.meta?.env;\n  if (importMetaEnv !== undefined && importMetaEnv !== null) {\n    const value = importMetaEnv[name] as string | undefined;\n    if (value !== undefined) {\n      return value;\n    }\n  }\n\n  // Try process.env (Node.js)\n  if (typeof process !== 'undefined' && process.env !== undefined) {\n    const value = process.env[name];\n    if (value !== undefined) {\n      return value;\n    }\n  }\n\n  return defaultValue;\n}\n\n/**\n * Get a required environment variable.\n */\nexport function requireEnvVar(name: string): string {\n  const value = getEnvVar(name);\n  if (value === undefined) {\n    throw new Error(`Required environment variable ${name} is not set`);\n  }\n  return value;\n}\n\n/**\n * Get an environment variable as a number.\n */\nexport function getEnvVarAsNumber(name: string, defaultValue: number): number {\n  const value = getEnvVar(name);\n  if (value === undefined) {\n    return defaultValue;\n  }\n  const parsed = parseFloat(value);\n  return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Get an environment variable as a boolean.\n */\nexport function getEnvVarAsBoolean(name: string, defaultValue: boolean): boolean {\n  const value = getEnvVar(name);\n  if (value === undefined) {\n    return defaultValue;\n  }\n  return value.toLowerCase() === 'true' || value === '1';\n}\n\n/**\n * Get an environment variable as JSON.\n */\nexport function getEnvVarAsJson<T>(name: string, defaultValue: T): T {\n  const value = getEnvVar(name);\n  if (value === undefined) {\n    return defaultValue;\n  }\n  try {\n    return JSON.parse(value) as T;\n  } catch {\n    return defaultValue;\n  }\n}\n\n/**\n * Get an environment variable as an array.\n */\nexport function getEnvVarAsArray(\n  name: string,\n  defaultValue: string[] = [],\n  separator = ','\n): string[] {\n  const value = getEnvVar(name);\n  if (value === undefined) {\n    return defaultValue;\n  }\n  return value\n    .split(separator)\n    .map((s) => s.trim())\n    .filter(Boolean);\n}\n\n// ============================================================================\n// Singleton Instance\n// ============================================================================\n\nlet instance: EnvironmentConfigManager | null = null;\n\n/**\n * Get the singleton environment config manager.\n */\nexport function getEnvironmentConfig(): EnvironmentConfigManager {\n  instance ??= new EnvironmentConfigManager();\n  return instance;\n}\n\n/**\n * Reset the singleton instance.\n */\nexport function resetEnvironmentConfig(): void {\n  instance = null;\n}\n"],"names":["detectEnvironment","normalizeEnvironment","env","isDevelopment","isProduction","isStaging","isTest","isBrowser","isServer","EnvironmentConfigManager","environment","ConfigMerger","baseConfig","envOverrides","overrides","options","factory","environmentDefaults","getEnvironmentDefaults","getEnvVar","name","defaultValue","importMetaEnv","__vite_import_meta_env__","value","requireEnvVar","getEnvVarAsNumber","parsed","getEnvVarAsBoolean","getEnvVarAsJson","getEnvVarAsArray","separator","instance","getEnvironmentConfig","resetEnvironmentConfig"],"mappings":"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"}