@i18n-auto/core 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/scanner/extractor.ts","../src/providers/google.provider.ts","../src/providers/provider.factory.ts","../src/cache/file-cache.ts","../src/cli.ts"],"names":["readFile"],"mappings":"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","file":"cli.js","sourcesContent":["import { readFile } from 'fs/promises';\nimport { parse } from '@babel/parser';\nimport traverseImport from \"@babel/traverse\";\nimport type { CallExpression, File, ObjectExpression } from '@babel/types';\n\n\nconst traverse =\n typeof traverseImport === \"function\"\n ? traverseImport\n : (traverseImport as any).default;\n\n\n\n/** Function name to scan for */\nconst FUNCTION_NAME = 'i18nTranslate';\n\n/** Package name to detect imports from */\nconst PACKAGE_NAME = '@i18n-auto/core';\n\n\n/**\n * Represents an extracted i18nTranslate() call from source code.\n */\nexport interface ExtractedEntry {\n /** The source text (first argument) */\n readonly text: string;\n\n /** The translation key from the options object */\n readonly key: string;\n\n /** Whether the key is locked for manual translation */\n readonly lock: boolean;\n\n /** The file path where this call was found */\n readonly filePath: string;\n\n /** The line number in the source file */\n readonly line: number;\n}\n\n/**\n * Extracts all i18nTranslate() calls from the given source files.\n * Only extracts from files that import i18nTranslate from '@i18n-auto/core'.\n *\n * Uses a fast string pre-filter to skip files that don't contain the function name,\n * then performs AST parsing only on matching files.\n *\n * @param filePaths - Array of absolute file paths to scan\n * @returns Array of extracted entries with text, key, file path, and line number\n */\nexport async function extractTranslations(filePaths: string[]): Promise<ExtractedEntry[]> {\n const entries: ExtractedEntry[] = [];\n const seenKeys = new Set<string>();\n\n for (const filePath of filePaths) {\n const fileEntries = await extractFromFile(filePath);\n\n for (const entry of fileEntries) {\n if (seenKeys.has(entry.key)) {\n continue;\n }\n seenKeys.add(entry.key);\n entries.push(entry);\n }\n }\n\n return entries;\n}\n\n/**\n * Extracts i18nTranslate() calls from a single source file.\n * Uses string pre-filter before expensive AST parsing.\n * @param filePath - Absolute path to the source file\n * @returns Array of extracted entries from this file\n */\nasync function extractFromFile(filePath: string): Promise<ExtractedEntry[]> {\n const code = await readFile(filePath, 'utf-8');\n\n // Fast pre-filter: skip AST parsing if file doesn't contain the function name\n if (!code.includes(FUNCTION_NAME)) {\n return [];\n }\n\n let ast;\n try {\n ast = parse(code, {\n sourceType: 'module',\n plugins: ['typescript', 'jsx', 'decorators-legacy'],\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[i18n-auto] Failed to parse ${filePath}: ${message}`);\n return [];\n }\n\n // Step 1: Check if file imports i18nTranslate from our package\n if (!hasI18nImport(ast)) {\n return [];\n }\n\n // Step 2: Find all i18nTranslate() calls\n const entries: ExtractedEntry[] = [];\n\n \n traverse(ast, {\n CallExpression(path: any) {\n const result = extractCall(path.node, filePath);\n if (result) {\n entries.push(result);\n }\n },\n });\n\n return entries;\n}\n\n/**\n * Checks if the file imports i18nTranslate from '@i18n-auto/core'.\n * @param ast - The parsed AST\n * @returns True if the import exists\n */\nfunction hasI18nImport(ast: File): boolean {\n let found = false;\n\n traverse(ast, {\n ImportDeclaration(path: any) {\n if (path.node.source.value !== PACKAGE_NAME) {\n return;\n }\n\n for (const specifier of path.node.specifiers) {\n if (\n specifier.type === 'ImportSpecifier' &&\n specifier.imported.type === 'Identifier' &&\n specifier.imported.name === FUNCTION_NAME\n ) {\n found = true;\n path.stop();\n }\n }\n },\n });\n\n return found;\n}\n\n/**\n * Checks if a CallExpression is an i18nTranslate() call\n * and extracts the text and key.\n * @param node - The CallExpression AST node\n * @param filePath - Current file path (for warnings)\n * @returns ExtractedEntry if valid, null otherwise\n */\nfunction extractCall(node: CallExpression, filePath: string): ExtractedEntry | null {\n // Must be a direct i18nTranslate() call\n if (node.callee.type !== 'Identifier' || node.callee.name !== FUNCTION_NAME) {\n return null;\n }\n\n const args = node.arguments;\n const line = node.loc?.start.line ?? 0;\n\n // First argument must be a string literal (source text)\n if (args.length < 2 || args[0].type !== 'StringLiteral') {\n console.warn(\n `[i18n-auto] Skipping i18nTranslate() at ${filePath}:${line} — first argument is not a string literal`,\n );\n return null;\n }\n\n // Second argument must be an object with a 'key' property\n if (args[1].type !== 'ObjectExpression') {\n console.warn(\n `[i18n-auto] Skipping i18nTranslate() at ${filePath}:${line} — second argument is not an object`,\n );\n return null;\n }\n\n const key = extractKeyFromObject(args[1] as ObjectExpression);\n if (!key) {\n console.warn(\n `[i18n-auto] Skipping i18nTranslate() at ${filePath}:${line} — missing or non-literal 'key' property`,\n );\n return null;\n }\n\n const lock = extractLockFromObject(args[1] as ObjectExpression);\n\n return {\n text: args[0].value,\n key,\n lock,\n filePath,\n line,\n };\n}\n\n/**\n * Extracts the 'key' string value from an ObjectExpression AST node.\n * @param node - The ObjectExpression AST node\n * @returns The key string value, or null if not found\n */\nfunction extractKeyFromObject(node: ObjectExpression): string | null {\n for (const prop of node.properties) {\n if (\n prop.type === 'ObjectProperty' &&\n prop.key.type === 'Identifier' &&\n prop.key.name === 'key' &&\n prop.value.type === 'StringLiteral'\n ) {\n return prop.value.value;\n }\n }\n\n return null;\n}\n\n/**\n * Extracts the 'lock' boolean value from an ObjectExpression AST node.\n * @param node - The ObjectExpression AST node\n * @returns True if lock is set to true, false otherwise\n */\nfunction extractLockFromObject(node: ObjectExpression): boolean {\n for (const prop of node.properties) {\n if (\n prop.type === 'ObjectProperty' &&\n prop.key.type === 'Identifier' &&\n prop.key.name === 'lock' &&\n prop.value.type === 'BooleanLiteral'\n ) {\n return prop.value.value;\n }\n }\n\n return false;\n}\n\n/**\n * Represents the config extracted from an initI18n() call.\n */\nexport interface ExtractedConfig {\n readonly provider?: string;\n readonly apiKeyEnvVar?: string;\n readonly defaultLocale?: string;\n readonly cachePath?: string;\n readonly locales?: string[];\n readonly sourcePath?: string;\n}\n\n/**\n * Extracts the initI18n() config from a single file.\n * Parses the file, finds the initI18n() call, and reads its config object.\n * For apiKey: if it's process.env.SOMETHING, extracts 'SOMETHING' as the env var name.\n *\n * @param filePath - Absolute path to the file containing initI18n() call\n * @returns Extracted config, or null if no valid initI18n() call found\n */\nexport async function extractConfig(filePath: string): Promise<ExtractedConfig | null> {\n const code = await readFile(filePath, 'utf-8');\n\n if (!code.includes('initI18n')) {\n return null;\n }\n\n let ast;\n try {\n ast = parse(code, {\n sourceType: 'module',\n plugins: ['typescript', 'jsx', 'decorators-legacy'],\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.warn(`[i18n-auto] Failed to parse ${filePath}: ${message}`);\n return null;\n }\n\n if (!hasInitImport(ast)) {\n return null;\n }\n\n return findInitConfig(ast);\n}\n\n/**\n * Checks if the file imports initI18n from '@i18n-auto/core'.\n */\nfunction hasInitImport(ast: File): boolean {\n let found = false;\n\n traverse(ast, {\n ImportDeclaration(path: any) {\n if (path.node.source.value !== PACKAGE_NAME) {\n return;\n }\n\n for (const specifier of path.node.specifiers) {\n if (\n specifier.type === 'ImportSpecifier' &&\n specifier.imported.type === 'Identifier' &&\n specifier.imported.name === 'initI18n'\n ) {\n found = true;\n path.stop();\n }\n }\n },\n });\n\n return found;\n}\n\n/**\n * Finds initI18n() call and extracts the config object.\n */\nfunction findInitConfig(ast: File): ExtractedConfig | null {\n let config: ExtractedConfig | null = null;\n\n traverse(ast, {\n CallExpression(path: any) {\n if (\n path.node.callee.type !== 'Identifier' ||\n path.node.callee.name !== 'initI18n'\n ) {\n return;\n }\n\n const args = path.node.arguments;\n if (args.length === 0 || args[0].type !== 'ObjectExpression') {\n return;\n }\n\n config = parseConfigObject(args[0] as ObjectExpression);\n path.stop();\n },\n });\n\n return config;\n}\n\n/**\n * Parses the ObjectExpression from initI18n({ ... }) into an ExtractedConfig.\n * Handles string literals, array literals, and process.env.* expressions.\n */\nfunction parseConfigObject(node: ObjectExpression): ExtractedConfig {\n const config: Record<string, unknown> = {};\n\n for (const prop of node.properties) {\n if (prop.type !== 'ObjectProperty' || prop.key.type !== 'Identifier') {\n continue;\n }\n\n const name = prop.key.name;\n const value = prop.value;\n\n // String literal: provider: 'google'\n if (value.type === 'StringLiteral') {\n config[name] = value.value;\n continue;\n }\n\n // Array of strings: locales: ['ur', 'fr', 'de']\n if (value.type === 'ArrayExpression') {\n const items: string[] = [];\n for (const element of value.elements) {\n if (element && element.type === 'StringLiteral') {\n items.push(element.value);\n }\n }\n if (items.length > 0) {\n config[name] = items;\n }\n continue;\n }\n\n // process.env.SOMETHING: apiKey: process.env.GOOGLE_TRANSLATE_API_KEY\n if (\n value.type === 'MemberExpression' &&\n value.object.type === 'MemberExpression' &&\n value.object.object.type === 'Identifier' &&\n value.object.object.name === 'process' &&\n value.object.property.type === 'Identifier' &&\n value.object.property.name === 'env' &&\n value.property.type === 'Identifier'\n ) {\n if (name === 'apiKey') {\n config['apiKeyEnvVar'] = value.property.name;\n }\n continue;\n }\n }\n\n return config as ExtractedConfig;\n}\n","import { v2 } from '@google-cloud/translate';\n\nimport { TranslationProvider } from '../interfaces/index.js';\n\n/** Maximum number of strings per Google Translate API request */\nconst GOOGLE_BATCH_LIMIT = 128;\n\n/**\n * Google Translate provider implementation.\n * Uses the Google Cloud Translation API v2 for batch translation.\n */\nexport class GoogleProvider implements TranslationProvider {\n private readonly client: v2.Translate;\n\n /**\n * @param apiKey - Google Cloud API key for authentication\n */\n constructor(apiKey: string) {\n this.client = new v2.Translate({ key: apiKey });\n }\n\n /**\n * Translates an array of strings from one locale to another using Google Translate.\n * Automatically chunks large arrays to respect API limits.\n * @param texts - Array of source strings to translate\n * @param from - Source locale (e.g., 'en')\n * @param to - Target locale (e.g., 'ur')\n * @returns Array of translated strings in the same order\n * @throws Error if the Google Translate API call fails\n */\n async translateBatch(texts: string[], from: string, to: string): Promise<string[]> {\n if (texts.length === 0) {\n return [];\n }\n\n // Protect {{placeholder}} patterns before sending to Google\n const protected_ = texts.map((text) => this.protectPlaceholders(text));\n const protectedTexts = protected_.map((p) => p.protected);\n\n const chunks = this.chunk(protectedTexts, GOOGLE_BATCH_LIMIT);\n const results: string[] = [];\n\n for (const chunk of chunks) {\n try {\n const [translations] = await this.client.translate(chunk, { from, to });\n const translated = Array.isArray(translations) ? translations : [translations];\n results.push(...translated);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`[i18n-auto] Google Translate API error: ${message}`);\n throw new Error(`[i18n-auto] Failed to translate batch: ${message}`);\n }\n }\n\n // Restore {{placeholder}} patterns in translated strings\n return results.map((text, i) =>\n this.restorePlaceholders(text, protected_[i].placeholders),\n );\n }\n\n /**\n * Replaces {{placeholder}} patterns with XML tokens that Google Translate preserves.\n * @param text - The source string containing {{placeholder}} patterns\n * @returns The protected string and an array of original placeholders\n */\n private protectPlaceholders(text: string): { protected: string; placeholders: string[] } {\n const placeholders: string[] = [];\n\n const protectedText = text.replace(/\\{\\{\\s*\\w+\\s*\\}\\}/g, (match) => {\n const index = placeholders.length;\n placeholders.push(match);\n return `<x${index}>`;\n });\n\n return { protected: protectedText, placeholders };\n }\n\n /**\n * Restores XML tokens back to original {{placeholder}} patterns.\n * @param text - The translated string containing XML tokens\n * @param placeholders - The original placeholder patterns in order\n * @returns The string with {{placeholder}} patterns restored\n */\n private restorePlaceholders(text: string, placeholders: string[]): string {\n return text.replace(/<x(\\d+)>/g, (_, index: string) => {\n return placeholders[Number(index)] ?? `<x${index}>`;\n });\n }\n\n /**\n * Splits an array into smaller chunks of a given size.\n * @param items - Array to split\n * @param size - Maximum chunk size\n * @returns Array of chunks\n */\n private chunk<T>(items: T[], size: number): T[][] {\n const chunks: T[][] = [];\n\n for (let i = 0; i < items.length; i += size) {\n chunks.push(items.slice(i, i + size));\n }\n\n return chunks;\n }\n}\n","import { TranslationProvider } from '../interfaces/index.js';\nimport { GoogleProvider } from './google.provider.js';\n\n/** Supported provider names */\nexport type ProviderName = 'google';\n\n/** List of all supported provider names */\nconst SUPPORTED_PROVIDERS: ProviderName[] = ['google'];\n\n/**\n * Returns the list of all supported provider names.\n * Useful for CLI help text and validation.\n * @returns Array of supported provider name strings\n */\nexport function getSupportedProviders(): ProviderName[] {\n return [...SUPPORTED_PROVIDERS];\n}\n\n/**\n * Factory that creates a translation provider instance by name.\n * To add a new provider:\n * 1. Create a new class implementing TranslationProvider\n * 2. Add its name to the ProviderName type\n * 3. Add it to the SUPPORTED_PROVIDERS array\n * 4. Add a case in the createProvider switch\n *\n * @param name - The provider name\n * @param apiKey - API key for the provider\n * @returns A TranslationProvider instance\n * @throws Error if the provider name is not supported\n */\nexport function createProvider(name: string, apiKey: string): TranslationProvider {\n switch (name) {\n case 'google':\n return new GoogleProvider(apiKey);\n default:\n throw new Error(\n `[i18n-auto] Provider '${name}' is not supported. Available: ${SUPPORTED_PROVIDERS.join(', ')}`,\n );\n }\n}\n","import { createHash } from 'crypto';\nimport { readFile, writeFile, mkdir } from 'fs/promises';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\n\n/**\n * Manages reading and writing of locale JSON cache files.\n * Each locale has a separate JSON file: {cachePath}/{locale}.json\n */\nexport class FileCache {\n private readonly cachePath: string;\n\n /**\n * @param cachePath - Directory path where locale JSON files are stored\n */\n constructor(cachePath: string) {\n this.cachePath = cachePath;\n }\n\n /**\n * Loads all translations for a given locale from its JSON file.\n * @param locale - The locale to load (e.g., 'ur', 'fr')\n * @returns Key-value map of translations, or empty object if file doesn't exist\n */\n async load(locale: string): Promise<Record<string, string>> {\n const filePath = this.getFilePath(locale);\n\n if (!existsSync(filePath)) {\n return {};\n }\n\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as Record<string, string>;\n }\n\n /**\n * Synchronously loads all translations for a given locale.\n * Used by the runtime t() method for fast, synchronous lookups.\n * @param locale - The locale to load\n * @returns Key-value map of translations, or empty object if file doesn't exist\n */\n loadSync(locale: string): Record<string, string> {\n const filePath = this.getFilePath(locale);\n\n if (!existsSync(filePath)) {\n return {};\n }\n\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as Record<string, string>;\n }\n\n /**\n * Saves translations for a locale to its JSON file.\n * Creates the directory if it doesn't exist.\n * @param locale - The locale to save\n * @param data - Key-value map of translations\n */\n async save(locale: string, data: Record<string, string>): Promise<void> {\n await mkdir(this.cachePath, { recursive: true });\n\n const filePath = this.getFilePath(locale);\n const content = JSON.stringify(data, null, 2);\n await writeFile(filePath, content, 'utf-8');\n }\n\n /**\n * Returns the set of keys that already have translations for a locale.\n * Used by CLI to determine which strings are new and need translating.\n * @param locale - The locale to check\n * @returns Set of existing translation keys\n */\n async getExistingKeys(locale: string): Promise<Set<string>> {\n const data = await this.load(locale);\n return new Set(Object.keys(data));\n }\n\n /**\n * Computes a short SHA-256 hash of a string.\n * Used to detect source text changes without storing full text.\n * @param text - The source text to hash\n * @returns 8-character hex hash\n */\n static hash(text: string): string {\n return createHash('sha256').update(text).digest('hex').slice(0, 8);\n }\n\n /**\n * Loads the metadata file (.meta.json) containing source text hashes.\n * Used by CLI to detect when source text has changed for an existing key.\n * @returns Key-value map of translation key to source text hash\n */\n async loadMeta(): Promise<Record<string, string>> {\n const filePath = join(this.cachePath, '.meta.json');\n\n if (!existsSync(filePath)) {\n return {};\n }\n\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as Record<string, string>;\n }\n\n /**\n * Saves the metadata file (.meta.json) with updated source text hashes.\n * @param data - Key-value map of translation key to source text hash\n */\n async saveMeta(data: Record<string, string>): Promise<void> {\n await mkdir(this.cachePath, { recursive: true });\n\n const filePath = join(this.cachePath, '.meta.json');\n const content = JSON.stringify(data, null, 2);\n await writeFile(filePath, content, 'utf-8');\n }\n\n /**\n * Builds the file path for a locale's JSON file.\n * @param locale - The locale identifier\n * @returns Full file path\n */\n private getFilePath(locale: string): string {\n return join(this.cachePath, `${locale}.json`);\n }\n}\n","#!/usr/bin/env node\n\nimport { resolve } from 'path';\nimport { Command } from 'commander';\nimport { glob } from 'tinyglobby';\n\nimport { extractTranslations, extractConfig } from './scanner/index.js';\nimport { createProvider, getSupportedProviders } from './providers/index.js';\nimport { FileCache } from './cache/file-cache.js';\n\nconst program = new Command();\n\nprogram\n .name('i18n-auto')\n .description('Auto-translate i18n strings by scanning source code')\n .version('0.1.0');\n\nprogram\n .command('translate')\n .description('Scan source files and translate extracted strings')\n .requiredOption('--config <path>', 'Path to the file containing initI18n() call')\n .option('--force', 'Re-translate all strings, ignoring cache')\n .action(async (options) => {\n try {\n await runTranslate(options.config, options.force ?? false);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`[i18n-auto] ${message}`);\n process.exit(1);\n }\n });\n\nprogram\n .command('stats')\n .description('Show translation statistics per locale')\n .requiredOption('--config <path>', 'Path to the file containing initI18n() call')\n .action(async (options) => {\n try {\n await runStats(options.config);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(`[i18n-auto] ${message}`);\n process.exit(1);\n }\n });\n\nprogram.parse();\n\n/** Supported source file extensions */\nconst SOURCE_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx'];\n\n/**\n * Reads and validates the config from initI18n() call.\n */\nasync function readConfig(configPath: string): Promise<{\n provider: string;\n apiKey: string;\n defaultLocale: string;\n cachePath: string;\n locales: string[];\n sourcePath: string;\n}> {\n const absolutePath = resolve(configPath);\n const config = await extractConfig(absolutePath);\n\n if (!config) {\n throw new Error(\n `No initI18n() call found in ${configPath}. Make sure the file imports initI18n from '@i18n-auto/core'.`,\n );\n }\n\n // Validate provider\n const provider = config.provider ?? 'google';\n const supported = getSupportedProviders();\n if (!supported.includes(provider as never)) {\n throw new Error(\n `Provider '${provider}' is not supported. Available: ${supported.join(', ')}`,\n );\n }\n\n // Validate API key\n if (!config.apiKeyEnvVar) {\n throw new Error(\n 'No apiKey found in initI18n() config. Use: apiKey: process.env.YOUR_API_KEY',\n );\n }\n\n const apiKey = process.env[config.apiKeyEnvVar];\n if (!apiKey) {\n throw new Error(\n `Environment variable '${config.apiKeyEnvVar}' is not set. Set it before running the CLI.`,\n );\n }\n\n // Validate locales\n const locales = config.locales ?? [];\n if (locales.length === 0) {\n throw new Error(\n 'No locales found in initI18n() config. Add: locales: [\\'ur\\', \\'fr\\', \\'de\\']',\n );\n }\n\n return {\n provider,\n apiKey,\n defaultLocale: config.defaultLocale ?? 'en',\n cachePath: resolve(config.cachePath ?? './locales'),\n locales,\n sourcePath: resolve(config.sourcePath ?? './src'),\n };\n}\n\n/**\n * Main translate command.\n * 1. Read config from initI18n()\n * 2. Glob source files\n * 3. Extract i18nTranslate() calls\n * 4. For each locale: diff (with hash-based change detection), batch translate, write JSON\n * 5. Update .meta.json with source text hashes\n */\nasync function runTranslate(configPath: string, force: boolean): Promise<void> {\n const config = await readConfig(configPath);\n\n // Step 1: Find source files\n const patterns = SOURCE_EXTENSIONS.map((ext) => `**/*.${ext}`);\n const filePaths = await glob(patterns, {\n cwd: config.sourcePath,\n absolute: true,\n ignore: ['**/node_modules/**', '**/dist/**'],\n });\n\n if (filePaths.length === 0) {\n console.warn(`[i18n-auto] No source files found in ${config.sourcePath}`);\n return;\n }\n\n console.warn(`[i18n-auto] Scanning ${filePaths.length} files...`);\n\n // Step 2: Extract i18nTranslate() calls\n const entries = await extractTranslations(filePaths);\n\n if (entries.length === 0) {\n console.warn('[i18n-auto] No i18nTranslate() calls found');\n return;\n }\n\n // Separate locked entries from translatable entries\n const lockedEntries = entries.filter((entry) => entry.lock);\n const translatableEntries = entries.filter((entry) => !entry.lock);\n\n console.warn(`[i18n-auto] Found ${translatableEntries.length} translatable entries`);\n if (lockedEntries.length > 0) {\n console.warn(`[i18n-auto] Found ${lockedEntries.length} locked key(s) (manual translation)`);\n }\n\n // Step 3: Create provider and cache\n const provider = createProvider(config.provider, config.apiKey);\n const cache = new FileCache(config.cachePath);\n\n // Load source text hashes for change detection\n const meta = await cache.loadMeta();\n const updatedMeta = { ...meta };\n\n // Mark locked entries in meta\n for (const entry of lockedEntries) {\n updatedMeta[entry.key] = 'locked';\n }\n\n // Step 4: For each locale, handle locked keys and translate new/changed strings\n let totalTranslated = 0;\n\n for (const locale of config.locales) {\n if (locale === config.defaultLocale) {\n console.warn(`[i18n-auto] Skipping source locale '${locale}'`);\n continue;\n }\n\n // Handle locked keys: add with empty string if not yet in locale JSON\n const existingData = await cache.load(locale);\n let lockedAdded = 0;\n\n for (const entry of lockedEntries) {\n if (!(entry.key in existingData)) {\n existingData[entry.key] = '';\n lockedAdded++;\n }\n }\n\n if (lockedAdded > 0) {\n await cache.save(locale, existingData);\n console.warn(`[i18n-auto] ${locale}: Added ${lockedAdded} locked key(s) for manual translation`);\n }\n\n // Determine which translatable entries need translation\n let entriesToTranslate;\n\n if (force) {\n entriesToTranslate = translatableEntries;\n console.warn(`[i18n-auto] ${locale}: Force mode — re-translating all ${translatableEntries.length} strings...`);\n } else {\n const existingKeys = await cache.getExistingKeys(locale);\n\n const newEntries = translatableEntries.filter((entry) => !existingKeys.has(entry.key));\n const changedEntries = translatableEntries.filter(\n (entry) =>\n existingKeys.has(entry.key) &&\n meta[entry.key] !== undefined &&\n meta[entry.key] !== 'locked' &&\n meta[entry.key] !== FileCache.hash(entry.text),\n );\n\n entriesToTranslate = [...newEntries, ...changedEntries];\n\n if (newEntries.length > 0) {\n console.warn(`[i18n-auto] ${locale}: Translating ${newEntries.length} new strings...`);\n }\n if (changedEntries.length > 0) {\n console.warn(`[i18n-auto] ${locale}: Re-translating ${changedEntries.length} changed strings...`);\n }\n }\n\n if (entriesToTranslate.length === 0 && lockedAdded === 0) {\n console.warn(`[i18n-auto] ${locale}: All ${entries.length} strings up to date`);\n continue;\n }\n\n if (entriesToTranslate.length === 0) {\n continue;\n }\n\n // Batch translate\n const textsToTranslate = entriesToTranslate.map((entry) => entry.text);\n const translated = await provider.translateBatch(textsToTranslate, config.defaultLocale, locale);\n\n // Merge with existing translations (reuse existingData already loaded above)\n for (let i = 0; i < entriesToTranslate.length; i++) {\n existingData[entriesToTranslate[i].key] = translated[i];\n }\n\n // Write updated locale file\n await cache.save(locale, existingData);\n\n console.warn(`[i18n-auto] ${locale}: Translated ${entriesToTranslate.length} strings`);\n totalTranslated += entriesToTranslate.length;\n }\n\n // Step 5: Update meta hashes for translatable entries (locked keys already set above)\n for (const entry of translatableEntries) {\n updatedMeta[entry.key] = FileCache.hash(entry.text);\n }\n await cache.saveMeta(updatedMeta);\n\n console.warn(\n `[i18n-auto] Done! Translated ${totalTranslated} strings for ${config.locales.length} locale(s)`,\n );\n}\n\n/**\n * Stats command — shows translation counts per locale.\n */\nasync function runStats(configPath: string): Promise<void> {\n const config = await readConfig(configPath);\n const cache = new FileCache(config.cachePath);\n\n // Extract total entries for comparison\n const patterns = SOURCE_EXTENSIONS.map((ext) => `**/*.${ext}`);\n const filePaths = await glob(patterns, {\n cwd: config.sourcePath,\n absolute: true,\n ignore: ['**/node_modules/**', '**/dist/**'],\n });\n\n const entries = await extractTranslations(filePaths);\n const totalKeys = entries.length;\n\n console.warn(`[i18n-auto] Total translation keys found: ${totalKeys}`);\n console.warn('');\n\n for (const locale of config.locales) {\n if (locale === config.defaultLocale) {\n continue;\n }\n\n const existingKeys = await cache.getExistingKeys(locale);\n const translated = existingKeys.size;\n const missing = totalKeys - translated;\n\n console.warn(\n ` ${locale}: ${translated}/${totalKeys} translated` +\n (missing > 0 ? ` (${missing} missing)` : ' ✓'),\n );\n }\n}\n"]}
package/dist/index.cjs ADDED
@@ -0,0 +1,172 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var crypto = require('crypto');
5
+ var promises = require('fs/promises');
6
+ var path = require('path');
7
+
8
+ // src/i18n-auto.ts
9
+ var FileCache = class {
10
+ cachePath;
11
+ /**
12
+ * @param cachePath - Directory path where locale JSON files are stored
13
+ */
14
+ constructor(cachePath) {
15
+ this.cachePath = cachePath;
16
+ }
17
+ /**
18
+ * Loads all translations for a given locale from its JSON file.
19
+ * @param locale - The locale to load (e.g., 'ur', 'fr')
20
+ * @returns Key-value map of translations, or empty object if file doesn't exist
21
+ */
22
+ async load(locale) {
23
+ const filePath = this.getFilePath(locale);
24
+ if (!fs.existsSync(filePath)) {
25
+ return {};
26
+ }
27
+ const content = await promises.readFile(filePath, "utf-8");
28
+ return JSON.parse(content);
29
+ }
30
+ /**
31
+ * Synchronously loads all translations for a given locale.
32
+ * Used by the runtime t() method for fast, synchronous lookups.
33
+ * @param locale - The locale to load
34
+ * @returns Key-value map of translations, or empty object if file doesn't exist
35
+ */
36
+ loadSync(locale) {
37
+ const filePath = this.getFilePath(locale);
38
+ if (!fs.existsSync(filePath)) {
39
+ return {};
40
+ }
41
+ const content = fs.readFileSync(filePath, "utf-8");
42
+ return JSON.parse(content);
43
+ }
44
+ /**
45
+ * Saves translations for a locale to its JSON file.
46
+ * Creates the directory if it doesn't exist.
47
+ * @param locale - The locale to save
48
+ * @param data - Key-value map of translations
49
+ */
50
+ async save(locale, data) {
51
+ await promises.mkdir(this.cachePath, { recursive: true });
52
+ const filePath = this.getFilePath(locale);
53
+ const content = JSON.stringify(data, null, 2);
54
+ await promises.writeFile(filePath, content, "utf-8");
55
+ }
56
+ /**
57
+ * Returns the set of keys that already have translations for a locale.
58
+ * Used by CLI to determine which strings are new and need translating.
59
+ * @param locale - The locale to check
60
+ * @returns Set of existing translation keys
61
+ */
62
+ async getExistingKeys(locale) {
63
+ const data = await this.load(locale);
64
+ return new Set(Object.keys(data));
65
+ }
66
+ /**
67
+ * Computes a short SHA-256 hash of a string.
68
+ * Used to detect source text changes without storing full text.
69
+ * @param text - The source text to hash
70
+ * @returns 8-character hex hash
71
+ */
72
+ static hash(text) {
73
+ return crypto.createHash("sha256").update(text).digest("hex").slice(0, 8);
74
+ }
75
+ /**
76
+ * Loads the metadata file (.meta.json) containing source text hashes.
77
+ * Used by CLI to detect when source text has changed for an existing key.
78
+ * @returns Key-value map of translation key to source text hash
79
+ */
80
+ async loadMeta() {
81
+ const filePath = path.join(this.cachePath, ".meta.json");
82
+ if (!fs.existsSync(filePath)) {
83
+ return {};
84
+ }
85
+ const content = await promises.readFile(filePath, "utf-8");
86
+ return JSON.parse(content);
87
+ }
88
+ /**
89
+ * Saves the metadata file (.meta.json) with updated source text hashes.
90
+ * @param data - Key-value map of translation key to source text hash
91
+ */
92
+ async saveMeta(data) {
93
+ await promises.mkdir(this.cachePath, { recursive: true });
94
+ const filePath = path.join(this.cachePath, ".meta.json");
95
+ const content = JSON.stringify(data, null, 2);
96
+ await promises.writeFile(filePath, content, "utf-8");
97
+ }
98
+ /**
99
+ * Builds the file path for a locale's JSON file.
100
+ * @param locale - The locale identifier
101
+ * @returns Full file path
102
+ */
103
+ getFilePath(locale) {
104
+ return path.join(this.cachePath, `${locale}.json`);
105
+ }
106
+ };
107
+
108
+ // src/i18n-auto.ts
109
+ var DEFAULT_CACHE_PATH = "./locales";
110
+ var DEFAULT_LOCALE = "en";
111
+ var translations = /* @__PURE__ */ new Map();
112
+ var config = {
113
+ defaultLocale: DEFAULT_LOCALE,
114
+ cachePath: DEFAULT_CACHE_PATH
115
+ };
116
+ function initI18n(options = {}) {
117
+ config = {
118
+ defaultLocale: options.defaultLocale ?? DEFAULT_LOCALE,
119
+ cachePath: options.cachePath ?? DEFAULT_CACHE_PATH
120
+ };
121
+ translations = /* @__PURE__ */ new Map();
122
+ const cache = new FileCache(config.cachePath);
123
+ try {
124
+ const files = fs.readdirSync(config.cachePath);
125
+ for (const file of files) {
126
+ if (!file.endsWith(".json")) {
127
+ continue;
128
+ }
129
+ const locale = file.replace(".json", "");
130
+ const data = cache.loadSync(locale);
131
+ translations.set(locale, data);
132
+ }
133
+ } catch {
134
+ }
135
+ }
136
+ function i18nTranslate(text, options) {
137
+ const { key, locale, params } = options;
138
+ if (locale === config.defaultLocale) {
139
+ return interpolate(text, params);
140
+ }
141
+ const localeData = translations.get(locale);
142
+ if (!localeData) {
143
+ return interpolate(text, params);
144
+ }
145
+ const translated = localeData[key] || text;
146
+ return interpolate(translated, params);
147
+ }
148
+ function interpolate(text, params) {
149
+ if (!params) {
150
+ return text;
151
+ }
152
+ return text.replace(/\{\{\s*(\w+)\s*\}\}/g, (match, name) => {
153
+ return name in params ? String(params[name]) : match;
154
+ });
155
+ }
156
+ function reloadTranslations() {
157
+ initI18n(config);
158
+ }
159
+ function getTranslationStats() {
160
+ const stats = {};
161
+ for (const [locale, data] of translations) {
162
+ stats[locale] = Object.keys(data).length;
163
+ }
164
+ return stats;
165
+ }
166
+
167
+ exports.getTranslationStats = getTranslationStats;
168
+ exports.i18nTranslate = i18nTranslate;
169
+ exports.initI18n = initI18n;
170
+ exports.reloadTranslations = reloadTranslations;
171
+ //# sourceMappingURL=index.cjs.map
172
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/cache/file-cache.ts","../src/i18n-auto.ts"],"names":["existsSync","readFile","readFileSync","mkdir","writeFile","createHash","join","readdirSync"],"mappings":"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","file":"index.cjs","sourcesContent":["import { createHash } from 'crypto';\nimport { readFile, writeFile, mkdir } from 'fs/promises';\nimport { readFileSync, existsSync } from 'fs';\nimport { join } from 'path';\n\n/**\n * Manages reading and writing of locale JSON cache files.\n * Each locale has a separate JSON file: {cachePath}/{locale}.json\n */\nexport class FileCache {\n private readonly cachePath: string;\n\n /**\n * @param cachePath - Directory path where locale JSON files are stored\n */\n constructor(cachePath: string) {\n this.cachePath = cachePath;\n }\n\n /**\n * Loads all translations for a given locale from its JSON file.\n * @param locale - The locale to load (e.g., 'ur', 'fr')\n * @returns Key-value map of translations, or empty object if file doesn't exist\n */\n async load(locale: string): Promise<Record<string, string>> {\n const filePath = this.getFilePath(locale);\n\n if (!existsSync(filePath)) {\n return {};\n }\n\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as Record<string, string>;\n }\n\n /**\n * Synchronously loads all translations for a given locale.\n * Used by the runtime t() method for fast, synchronous lookups.\n * @param locale - The locale to load\n * @returns Key-value map of translations, or empty object if file doesn't exist\n */\n loadSync(locale: string): Record<string, string> {\n const filePath = this.getFilePath(locale);\n\n if (!existsSync(filePath)) {\n return {};\n }\n\n const content = readFileSync(filePath, 'utf-8');\n return JSON.parse(content) as Record<string, string>;\n }\n\n /**\n * Saves translations for a locale to its JSON file.\n * Creates the directory if it doesn't exist.\n * @param locale - The locale to save\n * @param data - Key-value map of translations\n */\n async save(locale: string, data: Record<string, string>): Promise<void> {\n await mkdir(this.cachePath, { recursive: true });\n\n const filePath = this.getFilePath(locale);\n const content = JSON.stringify(data, null, 2);\n await writeFile(filePath, content, 'utf-8');\n }\n\n /**\n * Returns the set of keys that already have translations for a locale.\n * Used by CLI to determine which strings are new and need translating.\n * @param locale - The locale to check\n * @returns Set of existing translation keys\n */\n async getExistingKeys(locale: string): Promise<Set<string>> {\n const data = await this.load(locale);\n return new Set(Object.keys(data));\n }\n\n /**\n * Computes a short SHA-256 hash of a string.\n * Used to detect source text changes without storing full text.\n * @param text - The source text to hash\n * @returns 8-character hex hash\n */\n static hash(text: string): string {\n return createHash('sha256').update(text).digest('hex').slice(0, 8);\n }\n\n /**\n * Loads the metadata file (.meta.json) containing source text hashes.\n * Used by CLI to detect when source text has changed for an existing key.\n * @returns Key-value map of translation key to source text hash\n */\n async loadMeta(): Promise<Record<string, string>> {\n const filePath = join(this.cachePath, '.meta.json');\n\n if (!existsSync(filePath)) {\n return {};\n }\n\n const content = await readFile(filePath, 'utf-8');\n return JSON.parse(content) as Record<string, string>;\n }\n\n /**\n * Saves the metadata file (.meta.json) with updated source text hashes.\n * @param data - Key-value map of translation key to source text hash\n */\n async saveMeta(data: Record<string, string>): Promise<void> {\n await mkdir(this.cachePath, { recursive: true });\n\n const filePath = join(this.cachePath, '.meta.json');\n const content = JSON.stringify(data, null, 2);\n await writeFile(filePath, content, 'utf-8');\n }\n\n /**\n * Builds the file path for a locale's JSON file.\n * @param locale - The locale identifier\n * @returns Full file path\n */\n private getFilePath(locale: string): string {\n return join(this.cachePath, `${locale}.json`);\n }\n}\n","import { readdirSync } from 'fs';\n\nimport { FileCache } from './cache/file-cache.js';\nimport type { I18nAutoOptions } from './interfaces/index.js';\nimport type { TranslateOptions } from './interfaces/index.js';\n\n/** Default path to locale JSON files */\nconst DEFAULT_CACHE_PATH = './locales';\n\n/** Default source locale */\nconst DEFAULT_LOCALE = 'en';\n\n/** In-memory store of all loaded translations: locale → { key → translation } */\nlet translations: Map<string, Record<string, string>> = new Map();\n\n/** Configured options */\nlet config: Required<Pick<I18nAutoOptions, 'defaultLocale' | 'cachePath'>> = {\n defaultLocale: DEFAULT_LOCALE,\n cachePath: DEFAULT_CACHE_PATH,\n};\n\n/**\n * Initializes the i18n runtime by loading all locale JSON files into memory.\n * Must be called once at application startup before using i18nTranslate().\n *\n * @param options - Configuration options\n */\nexport function initI18n(options: I18nAutoOptions = {}): void {\n config = {\n defaultLocale: options.defaultLocale ?? DEFAULT_LOCALE,\n cachePath: options.cachePath ?? DEFAULT_CACHE_PATH,\n };\n\n translations = new Map();\n const cache = new FileCache(config.cachePath);\n\n try {\n const files = readdirSync(config.cachePath);\n\n for (const file of files) {\n if (!file.endsWith('.json')) {\n continue;\n }\n\n const locale = file.replace('.json', '');\n const data = cache.loadSync(locale);\n translations.set(locale, data);\n }\n } catch {\n // Cache directory doesn't exist yet — that's fine, no translations loaded\n }\n}\n\n/**\n * Translates a string by looking up the key in the loaded locale data.\n * This is a synchronous function — all data is pre-loaded in memory.\n *\n * If the translation is not found, returns the original source text as fallback.\n * If the requested locale matches the default locale, returns the source text.\n *\n * @param text - The source text (used as fallback if translation not found)\n * @param options - Must include key and locale\n * @returns The translated string, or the original text if not found\n */\nexport function i18nTranslate(text: string, options: TranslateOptions): string {\n const { key, locale, params } = options;\n\n // If requesting the default locale, return source text\n if (locale === config.defaultLocale) {\n return interpolate(text, params);\n }\n\n const localeData = translations.get(locale);\n if (!localeData) {\n return interpolate(text, params);\n }\n\n const translated = localeData[key] || text;\n return interpolate(translated, params);\n}\n\n/**\n * Replaces {{placeholder}} patterns in a string with values from params.\n * Supports optional whitespace inside braces: {{ name }} and {{name}} both work.\n * If a placeholder has no matching param, it is left unchanged.\n *\n * @param text - The string containing {{placeholder}} patterns\n * @param params - Key-value map of placeholder names to values\n * @returns The interpolated string\n */\nfunction interpolate(text: string, params?: Record<string, string | number>): string {\n if (!params) {\n return text;\n }\n\n return text.replace(/\\{\\{\\s*(\\w+)\\s*\\}\\}/g, (match, name: string) => {\n return name in params ? String(params[name]) : match;\n });\n}\n\n/**\n * Reloads all locale JSON files from disk into memory.\n * Call this after running the CLI to pick up new translations\n * without restarting the application.\n */\nexport function reloadTranslations(): void {\n initI18n(config);\n}\n\n/**\n * Returns the number of loaded translations per locale.\n * Useful for debugging and health checks.\n * @returns Map of locale → translation count\n */\nexport function getTranslationStats(): Record<string, number> {\n const stats: Record<string, number> = {};\n\n for (const [locale, data] of translations) {\n stats[locale] = Object.keys(data).length;\n }\n\n return stats;\n}\n"]}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Configuration options for the I18nAuto instance.
3
+ * These options are also read by the CLI from the initI18n() call in source code.
4
+ */
5
+ interface I18nAutoOptions {
6
+ /** Translation provider to use (default: 'google') */
7
+ readonly provider?: string;
8
+ /** API key for the translation provider */
9
+ readonly apiKey?: string;
10
+ /** Default locale of the source text (default: 'en') */
11
+ readonly defaultLocale?: string;
12
+ /** Path to the directory where locale JSON files are stored (default: './locales') */
13
+ readonly cachePath?: string;
14
+ /** Target locales to translate into (e.g., ['ur', 'fr', 'de']) */
15
+ readonly locales?: string[];
16
+ /** Path to the source directory to scan for i18nTranslate() calls (default: './src') */
17
+ readonly sourcePath?: string;
18
+ }
19
+
20
+ /**
21
+ * Options for the t() translation method.
22
+ */
23
+ interface TranslateOptions {
24
+ /** The key to store/retrieve the translation under */
25
+ readonly key: string;
26
+ /** The target locale to translate into (e.g., 'ur', 'fr', 'de') */
27
+ readonly locale: string;
28
+ /** Dynamic values to interpolate into {{placeholder}} patterns */
29
+ readonly params?: Record<string, string | number>;
30
+ /** If true, the CLI will not auto-translate this key. The user provides the translation manually. */
31
+ readonly lock?: boolean;
32
+ }
33
+
34
+ /**
35
+ * Contract for translation providers.
36
+ * Any translation service (Google, DeepL, etc.) must implement this interface.
37
+ */
38
+ interface TranslationProvider {
39
+ /**
40
+ * Translates an array of strings from one locale to another.
41
+ * @param texts - Array of source strings to translate
42
+ * @param from - Source locale (e.g., 'en')
43
+ * @param to - Target locale (e.g., 'ur')
44
+ * @returns Array of translated strings in the same order
45
+ */
46
+ translateBatch(texts: string[], from: string, to: string): Promise<string[]>;
47
+ }
48
+
49
+ /**
50
+ * Initializes the i18n runtime by loading all locale JSON files into memory.
51
+ * Must be called once at application startup before using i18nTranslate().
52
+ *
53
+ * @param options - Configuration options
54
+ */
55
+ declare function initI18n(options?: I18nAutoOptions): void;
56
+ /**
57
+ * Translates a string by looking up the key in the loaded locale data.
58
+ * This is a synchronous function — all data is pre-loaded in memory.
59
+ *
60
+ * If the translation is not found, returns the original source text as fallback.
61
+ * If the requested locale matches the default locale, returns the source text.
62
+ *
63
+ * @param text - The source text (used as fallback if translation not found)
64
+ * @param options - Must include key and locale
65
+ * @returns The translated string, or the original text if not found
66
+ */
67
+ declare function i18nTranslate(text: string, options: TranslateOptions): string;
68
+ /**
69
+ * Reloads all locale JSON files from disk into memory.
70
+ * Call this after running the CLI to pick up new translations
71
+ * without restarting the application.
72
+ */
73
+ declare function reloadTranslations(): void;
74
+ /**
75
+ * Returns the number of loaded translations per locale.
76
+ * Useful for debugging and health checks.
77
+ * @returns Map of locale → translation count
78
+ */
79
+ declare function getTranslationStats(): Record<string, number>;
80
+
81
+ /**
82
+ * Represents an extracted i18nTranslate() call from source code.
83
+ */
84
+ interface ExtractedEntry {
85
+ /** The source text (first argument) */
86
+ readonly text: string;
87
+ /** The translation key from the options object */
88
+ readonly key: string;
89
+ /** Whether the key is locked for manual translation */
90
+ readonly lock: boolean;
91
+ /** The file path where this call was found */
92
+ readonly filePath: string;
93
+ /** The line number in the source file */
94
+ readonly line: number;
95
+ }
96
+ /**
97
+ * Represents the config extracted from an initI18n() call.
98
+ */
99
+ interface ExtractedConfig {
100
+ readonly provider?: string;
101
+ readonly apiKeyEnvVar?: string;
102
+ readonly defaultLocale?: string;
103
+ readonly cachePath?: string;
104
+ readonly locales?: string[];
105
+ readonly sourcePath?: string;
106
+ }
107
+
108
+ export { type ExtractedConfig, type ExtractedEntry, type I18nAutoOptions, type TranslateOptions, type TranslationProvider, getTranslationStats, i18nTranslate, initI18n, reloadTranslations };
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Configuration options for the I18nAuto instance.
3
+ * These options are also read by the CLI from the initI18n() call in source code.
4
+ */
5
+ interface I18nAutoOptions {
6
+ /** Translation provider to use (default: 'google') */
7
+ readonly provider?: string;
8
+ /** API key for the translation provider */
9
+ readonly apiKey?: string;
10
+ /** Default locale of the source text (default: 'en') */
11
+ readonly defaultLocale?: string;
12
+ /** Path to the directory where locale JSON files are stored (default: './locales') */
13
+ readonly cachePath?: string;
14
+ /** Target locales to translate into (e.g., ['ur', 'fr', 'de']) */
15
+ readonly locales?: string[];
16
+ /** Path to the source directory to scan for i18nTranslate() calls (default: './src') */
17
+ readonly sourcePath?: string;
18
+ }
19
+
20
+ /**
21
+ * Options for the t() translation method.
22
+ */
23
+ interface TranslateOptions {
24
+ /** The key to store/retrieve the translation under */
25
+ readonly key: string;
26
+ /** The target locale to translate into (e.g., 'ur', 'fr', 'de') */
27
+ readonly locale: string;
28
+ /** Dynamic values to interpolate into {{placeholder}} patterns */
29
+ readonly params?: Record<string, string | number>;
30
+ /** If true, the CLI will not auto-translate this key. The user provides the translation manually. */
31
+ readonly lock?: boolean;
32
+ }
33
+
34
+ /**
35
+ * Contract for translation providers.
36
+ * Any translation service (Google, DeepL, etc.) must implement this interface.
37
+ */
38
+ interface TranslationProvider {
39
+ /**
40
+ * Translates an array of strings from one locale to another.
41
+ * @param texts - Array of source strings to translate
42
+ * @param from - Source locale (e.g., 'en')
43
+ * @param to - Target locale (e.g., 'ur')
44
+ * @returns Array of translated strings in the same order
45
+ */
46
+ translateBatch(texts: string[], from: string, to: string): Promise<string[]>;
47
+ }
48
+
49
+ /**
50
+ * Initializes the i18n runtime by loading all locale JSON files into memory.
51
+ * Must be called once at application startup before using i18nTranslate().
52
+ *
53
+ * @param options - Configuration options
54
+ */
55
+ declare function initI18n(options?: I18nAutoOptions): void;
56
+ /**
57
+ * Translates a string by looking up the key in the loaded locale data.
58
+ * This is a synchronous function — all data is pre-loaded in memory.
59
+ *
60
+ * If the translation is not found, returns the original source text as fallback.
61
+ * If the requested locale matches the default locale, returns the source text.
62
+ *
63
+ * @param text - The source text (used as fallback if translation not found)
64
+ * @param options - Must include key and locale
65
+ * @returns The translated string, or the original text if not found
66
+ */
67
+ declare function i18nTranslate(text: string, options: TranslateOptions): string;
68
+ /**
69
+ * Reloads all locale JSON files from disk into memory.
70
+ * Call this after running the CLI to pick up new translations
71
+ * without restarting the application.
72
+ */
73
+ declare function reloadTranslations(): void;
74
+ /**
75
+ * Returns the number of loaded translations per locale.
76
+ * Useful for debugging and health checks.
77
+ * @returns Map of locale → translation count
78
+ */
79
+ declare function getTranslationStats(): Record<string, number>;
80
+
81
+ /**
82
+ * Represents an extracted i18nTranslate() call from source code.
83
+ */
84
+ interface ExtractedEntry {
85
+ /** The source text (first argument) */
86
+ readonly text: string;
87
+ /** The translation key from the options object */
88
+ readonly key: string;
89
+ /** Whether the key is locked for manual translation */
90
+ readonly lock: boolean;
91
+ /** The file path where this call was found */
92
+ readonly filePath: string;
93
+ /** The line number in the source file */
94
+ readonly line: number;
95
+ }
96
+ /**
97
+ * Represents the config extracted from an initI18n() call.
98
+ */
99
+ interface ExtractedConfig {
100
+ readonly provider?: string;
101
+ readonly apiKeyEnvVar?: string;
102
+ readonly defaultLocale?: string;
103
+ readonly cachePath?: string;
104
+ readonly locales?: string[];
105
+ readonly sourcePath?: string;
106
+ }
107
+
108
+ export { type ExtractedConfig, type ExtractedEntry, type I18nAutoOptions, type TranslateOptions, type TranslationProvider, getTranslationStats, i18nTranslate, initI18n, reloadTranslations };