Skip to content

env config

  • Source: src/config/env.ts

Usage

Import from the framework:

ts
import { Env } from '@zintrust/core';

// Example (if supported by the module):
// Env.*

BASE_URL

BASE_URL is an optional base origin (for example: http://127.0.0.1 or https://api.example.com).

It is used anywhere the framework needs to construct fully-qualified URLs, including the zin routes table output (URL column), which computes:

  • BASE_URL + PORT + route path

Encryption interoperability env vars

These env vars enable cross-framework encrypted payload compatibility (used by EncryptedEnvelope):

  • ENCRYPTION_CIPHER: aes-256-cbc or aes-256-gcm (case-insensitive). Required in production when startup secret validation is enabled.
  • APP_KEY: Base64 key (32 bytes). Supports base64:... prefix.
  • APP_PREVIOUS_KEYS: Optional key rotation list (comma-separated or JSON array).

Snapshot (top)

ts
/**
 * Environment Configuration
 * Type-safe access to environment variables
 *
 * Sealed namespace pattern - all exports through Env namespace
 * Safe for both Node.js and serverless runtimes (Cloudflare Workers, Deno, Lambda)
 */

import { ProcessLike } from '@zintrust/core';

const getProcessLike = (): ProcessLike | undefined => {
  return typeof process === 'undefined' ? undefined : (process as unknown as ProcessLike);
};

const dirnameFromExecPath = (execPath: string, platform?: string): string => {
  const separator = platform === 'win32' ? '\\' : '/';
  const lastSep = execPath.lastIndexOf(separator);
  if (lastSep <= 0) return '';
  return execPath.slice(0, lastSep);
};

// Private helper functions
const get = (key: string, defaultValue?: string): string => {
  const proc = getProcessLike();
  const env = proc?.env ?? {};
  return env[key] ?? defaultValue ?? '';
};

const getInt = (key: string, defaultValue?: number): number => {
  const proc = getProcessLike();
  const env = proc?.env ?? {};
  const value = env[key];
  if (value === undefined || value === null) return defaultValue ?? 0;
  if (typeof value === 'string' && value.trim() === '') return defaultValue ?? 0;
  return Number.parseInt(value, 10);
};

const getBool = (key: string, defaultValue?: boolean): boolean => {
  const proc = getProcessLike();
  const env = proc?.env ?? {};
  const value = env[key];
  if (value === undefined || value === null) return defaultValue ?? false;
  return value.toLowerCase() === 'true' || value === '1';
};

const getDefaultLogLevel = (): 'debug' | 'info' | 'warn' | 'error' => {
  const NODE_ENV_VALUE = get('NODE_ENV', 'development');
  if (NODE_ENV_VALUE === 'production') return 'info';
  if (NODE_ENV_VALUE === 'testing') return 'error';
  return 'debug';
};

// Sealed namespace with all environment configuration
export const Env = Object.freeze({
  // Helper functions
  get,
  getInt,
  getBool,

  // Core
  NODE_ENV: get('NODE_ENV', 'development'),
  // Prefer PORT, fallback to APP_PORT for compatibility
  PORT: getInt('PORT', getInt('APP_PORT', 3000)),
  HOST: get('HOST', 'localhost'),
  BASE_URL: get('BASE_URL', ''),
  APP_NAME: get('APP_NAME', 'ZinTrust '),
  APP_KEY: get('APP_KEY', ''),

  // Database
  DB_CONNECTION: get('DB_CONNECTION', 'sqlite'),
  DB_HOST: get('DB_HOST', 'localhost'),

Snapshot (bottom)

ts
  LAMBDA_TASK_ROOT: get('LAMBDA_TASK_ROOT'),

  // Microservices
  MICROSERVICES: get('MICROSERVICES'),
  SERVICES: get('SERVICES'),
  MICROSERVICES_TRACING: getBool('MICROSERVICES_TRACING'),
  MICROSERVICES_TRACING_RATE: Number.parseFloat(get('MICROSERVICES_TRACING_RATE', '1.0')),
  DATABASE_ISOLATION: get('DATABASE_ISOLATION', 'shared'),
  SERVICE_API_KEY: get('SERVICE_API_KEY'),
  SERVICE_JWT_SECRET: get('SERVICE_JWT_SECRET'),

  // Security
  DEBUG: getBool('DEBUG', false),
  ENABLE_MICROSERVICES: getBool('ENABLE_MICROSERVICES', false),
  TOKEN_TTL: getInt('TOKEN_TTL', 3600000),
  TOKEN_LENGTH: getInt('TOKEN_LENGTH', 32),

  // Deployment
  ENVIRONMENT: get('ENVIRONMENT', 'development'),
  REQUEST_TIMEOUT: getInt('REQUEST_TIMEOUT', 30000),
  MAX_BODY_SIZE: getInt('MAX_BODY_SIZE', 10485760),
  SHUTDOWN_TIMEOUT: getInt('SHUTDOWN_TIMEOUT', 10000),

  // Logging
  LOG_LEVEL: get('LOG_LEVEL', getDefaultLogLevel()) as 'debug' | 'info' | 'warn' | 'error',
  LOG_FORMAT: get('LOG_FORMAT', 'text'),
  DISABLE_LOGGING: getBool('DISABLE_LOGGING', false),
  LOG_HTTP_REQUEST: getBool('LOG_HTTP_REQUEST', false),
  LOG_TO_FILE: getBool('LOG_TO_FILE', false),
  LOG_ROTATION_SIZE: getInt('LOG_ROTATION_SIZE', 10485760),
  LOG_ROTATION_DAYS: getInt('LOG_ROTATION_DAYS', 7),

  // Paths (safely constructed for Node.js environments)
  NODE_BIN_DIR: (() => {
    try {
      const proc = getProcessLike();
      if (proc?.execPath === null || proc?.execPath === undefined) return '';
      return dirnameFromExecPath(proc.execPath, proc.platform);
    } catch {
      // Fallback for non-Node environments
      return '';
    }
  })(),
  SAFE_PATH: (() => {
    try {
      const proc = getProcessLike();
      if (proc?.execPath === null || proc?.execPath === undefined) return '';

      const binDir = dirnameFromExecPath(proc.execPath, proc.platform);
      if (proc.platform === 'win32') {
        return [String.raw`C:\Windows\System32`, String.raw`C:\Windows`, binDir].join(';');
      }
      return ['/usr/bin', '/bin', '/usr/sbin', '/sbin', binDir].join(':');
    } catch {
      // Fallback for non-Node environments
      return '';
    }
  })(),
});

Released under the MIT License.