src — i18n

Module: src-i18n Cohesion: 0.80 Members: 0

src — i18n

The src/i18n module provides the internationalization (i18n) system for the application, enabling locale-aware string translation and parameter interpolation. Its primary goal is to ensure all user-facing text can be presented in multiple languages, adapting to the user's environment or explicit settings.

Purpose

This module centralizes all application strings, allowing them to be translated into various languages. It handles:

Core Concepts

Supported Locales

The system supports the following 6 locales, defined by the Locale type:

Translation Keys (I18nStrings)

All translatable strings are identified by a unique key, defined in the I18nStrings interface. These keys are structured hierarchically (e.g., common.yes, cli.welcome, errors.api_error) to categorize strings logically.

export interface I18nStrings {
  'common.yes': string;
  'cli.welcome': string;
  'errors.api_error': string;
  class="hl-cmt">// ... other keys
}

Locale Tables

The localeTables object (Record) stores the complete set of translated strings for each supported locale.

How It Works

Locale Detection

The system attempts to determine the user's preferred locale automatically on its first use (either via t() or getLocale()). The autoDetectLocale() function follows this priority:

  1. process.env.CODEBUDDY_LOCALE
  2. process.env.LANG
  3. process.env.LC_ALL
  4. Defaults to 'en' if no environment variable is set or if the detected locale is not supported.

The detected locale code (e.g., en from en_US.UTF-8) is then checked against the list of supported locales. Once detected, the autoDetected flag is set to true to prevent re-detection unless explicitly reset.

Translation Process (t function)

The core of the i18n system is the t function. When called, it performs the following steps:

  1. Auto-detection Check: If autoDetected is false, it calls autoDetectLocale() to set currentLocale.
  2. String Retrieval: It attempts to find the string for the given key in the localeTables[currentLocale].
  3. Fallback: If the string is not found in the currentLocale table (which can happen for stubbed locales or if a translation is genuinely missing), it falls back to localeTables.en. If the key is still not found (indicating a missing key in the reference English table), it returns the key itself as a last resort.
  4. Parameter Interpolation: If params are provided, it replaces all occurrences of {paramKey} in the retrieved string with the corresponding paramValue.

The following diagram illustrates the flow of the t function:

graph TD
    A[Call t(key, params?)] --> B{autoDetected?};
    B -- No --> C[autoDetectLocale()];
    C --> D[Set currentLocale];
    B -- Yes --> D;
    D --> E[Get string from localeTables[currentLocale]];
    E -- Key not found --> F[Fallback to localeTables.en];
    F -- Key not found --> G[Return key itself];
    E -- Key found --> H[Interpolate params];
    F -- Key found --> H;
    H --> I[Return translated string];

Parameter Interpolation

Translated strings can include placeholders using the {name} syntax. The t function replaces these placeholders with values provided in the params object.

Example:

class="hl-cmt">// In en.ts:
class="hl-cmt">// 'tools.executing': 'Executing {tool}...'

t('tools.executing', { tool: 'CodeLinter' });
class="hl-cmt">// => "Executing CodeLinter..."

API Reference

t(key: keyof I18nStrings, params?: Record): string

The primary function for retrieving translated strings.

Returns: The translated and interpolated string.

setLocale(locale: Locale): void

Explicitly sets the active locale for the application. This overrides any auto-detected locale and prevents future auto-detection until resetI18n() is called.

getLocale(): Locale

Retrieves the currently active locale. If the locale has not yet been auto-detected or explicitly set, this function will trigger autoDetectLocale().

Returns: The current Locale.

isLocaleSupported(locale: string): locale is Locale

Checks if a given string corresponds to one of the supported Locale codes.

Returns: true if the locale is supported, false otherwise.

getSupportedLocales(): Locale[]

Returns an array of all Locale codes currently supported by the system.

Returns: An array of Locale strings.

resetI18n(): void

Resets the i18n system's internal state. This sets currentLocale back to 'en' and autoDetected to false, allowing auto-detection to run again on the next call to t() or getLocale(). This function is primarily intended for testing purposes.

Integration and Usage

To use the i18n system, simply import the t function from src/i18n/index.ts and call it with the desired key and any parameters.

import { t, setLocale, getLocale } from './i18n';

class="hl-cmt">// Example usage in a CLI command
export function greetUser() {
  console.log(t('cli.welcome')); class="hl-cmt">// "Welcome to Code Buddy!" (or French, etc.)
  console.log(t('cli.help'));
}

class="hl-cmt">// Example of dynamic error message
try {
  class="hl-cmt">// ... some API call
} catch (error: any) {
  console.error(t('errors.api_error', { message: error.message }));
}

class="hl-cmt">// Changing locale dynamically
setLocale('fr');
console.log(t('cli.welcome')); class="hl-cmt">// "Bienvenue dans Code Buddy !"

class="hl-cmt">// Getting current locale
console.log(`Current locale: ${getLocale()}`);

The t function is designed to be called anywhere a translated string is needed. The initial locale will be determined automatically based on environment variables, but can be overridden programmatically using setLocale().

Contributing to Translations

To add new translations or update existing ones:

  1. Update I18nStrings: If new keys are needed, add them to the I18nStrings interface in src/i18n/index.ts.
  2. Add/Update Locale Table:

  1. Create a new const : I18nStrings = { ... } object.
  2. Populate it with all keys from I18nStrings.
  3. Remove the locale code from the stubLocales array.
  4. Register it explicitly in localeTables (e.g., localeTables.de = de;).
  5. Ensure Completeness: The en locale must always be complete. For other locales, if a key is missing, it will fall back to the English translation.
  6. Testing: Run unit tests (i18n.test.ts) to ensure translations and locale switching work as expected.