i18n-ai-cli 1.0.0 → 1.0.2
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.
- package/README.md +21 -1
- package/dist/cli.js +2 -1
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -31,12 +31,32 @@ npm install -g i18n-ai-cli
|
|
|
31
31
|
npm install --save-dev i18n-ai-cli
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
When installed locally, the `i18n-ai-cli` command is not automatically available in your shell PATH. Use one of these methods:
|
|
35
35
|
|
|
36
|
+
**Option 1: Use npx (recommended)**
|
|
36
37
|
```bash
|
|
37
38
|
npx i18n-ai-cli --help
|
|
38
39
|
```
|
|
39
40
|
|
|
41
|
+
**Option 2: Add a script to your package.json**
|
|
42
|
+
```json
|
|
43
|
+
{
|
|
44
|
+
"scripts": {
|
|
45
|
+
"i18n": "i18n-ai-cli"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
Then run:
|
|
50
|
+
```bash
|
|
51
|
+
npm run i18n -- --help
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Option 3: Install globally**
|
|
55
|
+
```bash
|
|
56
|
+
npm install -g i18n-ai-cli
|
|
57
|
+
i18n-ai-cli --help
|
|
58
|
+
```
|
|
59
|
+
|
|
40
60
|
## Quick Start
|
|
41
61
|
|
|
42
62
|
```bash
|
package/dist/cli.js
CHANGED
|
@@ -423,9 +423,10 @@ async function maybeInitLocales(config, options) {
|
|
|
423
423
|
return;
|
|
424
424
|
}
|
|
425
425
|
await fs3.ensureDir(localesPath);
|
|
426
|
+
const defaultLocale = config.defaultLocale.replace(/\.json$/i, "");
|
|
426
427
|
const defaultLocaleFile = path3.join(
|
|
427
428
|
localesPath,
|
|
428
|
-
`${
|
|
429
|
+
`${defaultLocale}.json`
|
|
429
430
|
);
|
|
430
431
|
if (await fs3.pathExists(defaultLocaleFile)) {
|
|
431
432
|
return;
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/bin/cli.ts","../src/config/config-loader.ts","../src/core/file-manager.ts","../src/context/build-context.ts","../src/commands/init.ts","../src/core/confirmation.ts","../src/commands/add-lang.ts","../src/commands/remove-lang.ts","../src/commands/add-key.ts","../src/core/object-utils.ts","../src/core/key-validator.ts","../src/commands/update-key.ts","../src/commands/remove-key.ts","../src/commands/clean-unused.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { buildContext } from \"../context/build-context.js\";\nimport { initCommand } from \"../commands/init.js\";\nimport { addLang } from \"../commands/add-lang.js\";\nimport { removeLangCommand } from \"../commands/remove-lang.js\";\nimport { addKeyCommand } from \"../commands/add-key.js\";\nimport { updateKeyCommand } from \"../commands/update-key.js\";\nimport { removeKeyCommand } from \"../commands/remove-key.js\";\nimport { cleanUnusedCommand } from \"../commands/clean-unused.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"i18n-ai-cli\")\n .description(\"Professional CLI tool for managing translation files\")\n .version(\"1.0.0\");\n\n// Global options helper\nfunction withGlobalOptions(command: Command): Command {\n return command\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--dry-run\", \"Preview changes without writing files\")\n .option(\"--ci\", \"Run in CI mode (no prompts, exit on issues)\")\n .option(\"-f, --force\", \"Force operation even if validation fails\");\n}\n\n// Language Commands\nwithGlobalOptions(\n program\n .command(\"init\")\n .description(\"Create an i18n-cli configuration file\")\n .action(async (options) => {\n await initCommand(options);\n })\n);\n\nwithGlobalOptions(\n program\n .command(\"add:lang <lang>\")\n .option(\"--from <locale>\", \"Clone from existing locale\")\n .option(\"--strict\", \"Enable strict mode\")\n .description(\"Add new language locale\")\n .action(async (lang, options) => {\n const context = await buildContext(options);\n await addLang(lang, options, context);\n })\n);\n\nwithGlobalOptions(\n program\n .command(\"remove:lang\")\n .argument(\"<lang>\", \"Language code to remove\")\n .description(\"Remove a language translation file\")\n .action(async (lang, options) => {\n const context = await buildContext(options);\n await removeLangCommand(context, lang);\n })\n);\n\n//\n// Key Commands\n//\nwithGlobalOptions(\n program\n .command(\"add:key\")\n .argument(\"<key>\", \"Translation key (e.g., auth.login.title)\")\n .requiredOption(\"-v, --value <value>\", \"Value for default locale\")\n .description(\"Add new translation key to all locales\")\n .action(async (key, options) => {\n const context = await buildContext(options);\n await addKeyCommand(context, key, options);\n })\n);\n\nwithGlobalOptions(\n program\n .command(\"update:key\")\n .argument(\"<key>\", \"Translation key\")\n .requiredOption(\"-v, --value <value>\", \"New value\")\n .option(\"-l, --locale <locale>\", \"Specific locale to update\")\n .description(\"Update translation key\")\n .action(async (key, options) => {\n const context = await buildContext(options);\n await updateKeyCommand(context, key, options);\n })\n);\n\nwithGlobalOptions(\n program\n .command(\"remove:key\")\n .argument(\"<key>\", \"Translation key to remove\")\n .description(\"Remove translation key from all locales\")\n .action(async (key, options) => {\n const context = await buildContext(options);\n await removeKeyCommand(context, key);\n })\n);\n\n// Clean Command\nwithGlobalOptions(\n program\n .command(\"clean:unused\")\n .description(\"Remove unused translation keys from all locales\")\n .action(async (options) => {\n const context = await buildContext(options);\n await cleanUnusedCommand(context);\n })\n);\n\n// Global Error Handling\nprogram.exitOverride();\n\ntry {\n await program.parseAsync(process.argv);\n} catch (err: any) {\n console.error(chalk.red(\"❌ Error:\"), err.message);\n process.exitCode = 1;\n}\n","import fs from \"fs-extra\";\nimport path from \"path\";\nimport { z } from \"zod\";\nimport type { I18nConfig } from \"./types.js\";\n\nexport const CONFIG_FILE_NAME = \"i18n-cli.config.json\";\n\nconst ConfigSchema = z.object({\n localesPath: z.string().min(1),\n defaultLocale: z.string().min(2),\n supportedLocales: z.array(z.string().min(2)),\n keyStyle: z.enum([\"flat\", \"nested\"]).default(\"nested\"),\n usagePatterns: z.array(z.string()).default([]),\n autoSort: z.boolean().default(true)\n});\n\ntype ParsedConfig = z.infer<typeof ConfigSchema>;\n\nfunction resolveConfigPath(): string {\n const cwd = process.cwd();\n return path.join(cwd, CONFIG_FILE_NAME);\n}\n\nexport async function loadConfig(): Promise<I18nConfig> {\n const configPath = resolveConfigPath();\n\n if (!(await fs.pathExists(configPath))) {\n throw new Error(\n `Configuration file \"${CONFIG_FILE_NAME}\" not found in project root.\\n` +\n `Run \"i18n-cli init\" to create one.`\n );\n }\n\n let rawConfig: unknown;\n\n try {\n rawConfig = await fs.readJson(configPath);\n } catch (err) {\n throw new Error(\n `Failed to parse ${CONFIG_FILE_NAME}. Ensure it contains valid JSON.`\n );\n }\n\n const parsed = ConfigSchema.safeParse(rawConfig);\n\n if (!parsed.success) {\n const errors = parsed.error.issues\n .map(e => `• ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\");\n\n throw new Error(\n `Invalid configuration in ${CONFIG_FILE_NAME}:\\n${errors}`\n );\n }\n\n const config = parsed.data;\n\n validateConfigLogic(config);\n const compiledUsagePatterns = compileUsagePatterns(\n config.usagePatterns\n );\n\n return {\n ...config,\n compiledUsagePatterns\n };\n}\n\nfunction validateConfigLogic(config: ParsedConfig): void {\n if (!config.supportedLocales.includes(config.defaultLocale)) {\n throw new Error(\n `defaultLocale \"${config.defaultLocale}\" must be included in supportedLocales.`\n );\n }\n\n const duplicates = findDuplicates(config.supportedLocales);\n if (duplicates.length > 0) {\n throw new Error(\n `Duplicate locales found in supportedLocales: ${duplicates.join(\", \")}`\n );\n }\n}\n\nexport function compileUsagePatterns(patterns: string[]): RegExp[] {\n if (patterns.length === 0) {\n return [];\n }\n\n return patterns.map((pattern, index) => {\n let regex: RegExp;\n\n try {\n regex = new RegExp(pattern, \"g\");\n } catch (err) {\n throw new Error(\n `Invalid regex in usagePatterns[${index}]: ${String(err)}`\n );\n }\n\n const groupCount = countCapturingGroups(pattern);\n if (groupCount === 0) {\n throw new Error(\n `usagePatterns[${index}] must include a capturing group (use a named group like \"(?<key>...)\" or a standard \"(...)\").`\n );\n }\n\n return regex;\n });\n}\n\nfunction countCapturingGroups(pattern: string): number {\n let count = 0;\n let inCharClass = false;\n\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n\n if (char === \"\\\\\") {\n i += 1;\n continue;\n }\n\n if (char === \"[\") {\n inCharClass = true;\n continue;\n }\n\n if (char === \"]\" && inCharClass) {\n inCharClass = false;\n continue;\n }\n\n if (inCharClass) {\n continue;\n }\n\n if (char !== \"(\") {\n continue;\n }\n\n const next = pattern[i + 1];\n if (next !== \"?\") {\n count += 1;\n continue;\n }\n\n const next2 = pattern[i + 2];\n if (next2 !== \"<\") {\n continue;\n }\n\n const next3 = pattern[i + 3];\n if (next3 === \"=\" || next3 === \"!\") {\n continue;\n }\n\n count += 1;\n }\n\n return count;\n}\n\nfunction findDuplicates(arr: string[]): string[] {\n const seen = new Set<string>();\n const duplicates: string[] = [];\n\n for (const item of arr) {\n if (seen.has(item)) {\n duplicates.push(item);\n }\n seen.add(item);\n }\n\n return duplicates;\n}\n","import fs from \"fs-extra\";\nimport path from \"path\";\nimport type { I18nConfig } from \"../config/types.js\";\n\nexport class FileManager {\n private localesPath: string;\n private config: I18nConfig;\n\n constructor(config: I18nConfig) {\n this.config = config;\n this.localesPath = path.resolve(process.cwd(), config.localesPath);\n }\n\n getLocaleFilePath(locale: string): string {\n return path.join(this.localesPath, `${locale}.json`);\n }\n\n async ensureLocalesDirectory(): Promise<void> {\n await fs.ensureDir(this.localesPath);\n }\n\n async localeExists(locale: string): Promise<boolean> {\n const filePath = this.getLocaleFilePath(locale);\n return fs.pathExists(filePath);\n }\n\n async listLocales(): Promise<string[]> {\n return this.config.supportedLocales;\n }\n\n async readLocale(locale: string): Promise<Record<string, any>> {\n const filePath = this.getLocaleFilePath(locale);\n\n if (!(await fs.pathExists(filePath))) {\n throw new Error(`Locale file \"${locale}.json\" does not exist.`);\n }\n\n try {\n return await fs.readJson(filePath);\n } catch {\n throw new Error(`Invalid JSON in \"${locale}.json\".`);\n }\n }\n\n async writeLocale(\n locale: string,\n data: Record<string, any>,\n options?: { dryRun?: boolean }\n ): Promise<void> {\n const filePath = this.getLocaleFilePath(locale);\n\n const finalData = this.config.autoSort\n ? this.sortKeysRecursively(data)\n : data;\n\n if (options?.dryRun) {\n return;\n }\n\n await fs.writeJson(filePath, finalData, { spaces: 2 });\n }\n\n async deleteLocale(\n locale: string,\n options?: { dryRun?: boolean }\n ): Promise<void> {\n const filePath = this.getLocaleFilePath(locale);\n\n if (!(await fs.pathExists(filePath))) {\n throw new Error(`Locale \"${locale}\" does not exist.`);\n }\n\n if (options?.dryRun) {\n return;\n }\n\n await fs.remove(filePath);\n }\n\n async createLocale(\n locale: string,\n initialData: Record<string, any>,\n options?: { dryRun?: boolean }\n ): Promise<void> {\n await this.ensureLocalesDirectory();\n\n const filePath = this.getLocaleFilePath(locale);\n\n if (await fs.pathExists(filePath)) {\n throw new Error(`Locale \"${locale}\" already exists.`);\n }\n\n if (options?.dryRun) {\n return;\n }\n\n await fs.writeJson(filePath, initialData, { spaces: 2 });\n }\n\n private sortKeysRecursively(obj: any): any {\n if (Array.isArray(obj)) {\n return obj.map(item => this.sortKeysRecursively(item));\n }\n\n if (obj !== null && typeof obj === \"object\") {\n return Object.keys(obj)\n .sort()\n .reduce((acc: any, key) => {\n acc[key] = this.sortKeysRecursively(obj[key]);\n return acc;\n }, Object.create(null));\n }\n\n return obj;\n }\n \n}\n","import { loadConfig } from \"../config/config-loader.js\";\nimport { FileManager } from \"../core/file-manager.js\";\nimport type { CommandContext, GlobalOptions } from \"./types.js\";\n\nexport async function buildContext(\n options: GlobalOptions\n): Promise<CommandContext> {\n const config = await loadConfig();\n const fileManager = new FileManager(config);\n\n return {\n config,\n fileManager,\n options\n };\n}","import chalk from \"chalk\";\nimport fs from \"fs-extra\";\nimport inquirer from \"inquirer\";\nimport path from \"path\";\nimport { CONFIG_FILE_NAME, compileUsagePatterns } from \"../config/config-loader.js\";\nimport type { KeyStyle } from \"../config/types.js\";\nimport type { GlobalOptions } from \"../context/types.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\ninterface InitConfigFile {\n localesPath: string;\n defaultLocale: string;\n supportedLocales: string[];\n keyStyle: KeyStyle;\n usagePatterns: string[];\n autoSort: boolean;\n}\n\nconst DEFAULT_USAGE_PATTERNS = [\n \"t\\\\(['\\\"](.*?)['\\\"]\\\\)\",\n \"translate\\\\(['\\\"](.*?)['\\\"]\\\\)\",\n \"i18n\\\\.t\\\\(['\\\"](.*?)['\\\"]\\\\)\"\n];\n\nexport async function initCommand(\n options: GlobalOptions\n): Promise<void> {\n const { yes, dryRun, ci, force } = options;\n const configPath = path.join(process.cwd(), CONFIG_FILE_NAME);\n const configExists = await fs.pathExists(configPath);\n\n if (configExists && !force) {\n throw new Error(\n `Configuration file \"${CONFIG_FILE_NAME}\" already exists. ` +\n `Use --force to overwrite.`\n );\n }\n\n const canPrompt = process.stdout.isTTY && !yes && !ci;\n\n let config: InitConfigFile;\n\n if (canPrompt) {\n const answers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"localesPath\",\n message: \"Locales directory\",\n default: \"./locales\",\n validate: (input: string) =>\n input.trim().length > 0 || \"Please provide a locales path.\"\n },\n {\n type: \"input\",\n name: \"defaultLocale\",\n message: \"Default locale\",\n default: \"en\",\n validate: (input: string) =>\n input.trim().length >= 2 || \"Default locale must be at least 2 characters.\"\n },\n {\n type: \"input\",\n name: \"supportedLocales\",\n message: \"Supported locales (comma-separated)\",\n default: (answers: { defaultLocale: string }) =>\n answers.defaultLocale\n },\n {\n type: \"list\",\n name: \"keyStyle\",\n message: \"Key style\",\n choices: [\"nested\", \"flat\"],\n default: \"nested\"\n },\n {\n type: \"confirm\",\n name: \"autoSort\",\n message: \"Auto-sort keys?\",\n default: true\n },\n {\n type: \"confirm\",\n name: \"useDefaultUsagePatterns\",\n message: \"Use default usagePatterns?\",\n default: true\n }\n ]);\n\n let usagePatterns: string[] = DEFAULT_USAGE_PATTERNS;\n\n if (!answers.useDefaultUsagePatterns) {\n usagePatterns = [];\n let addMore = true;\n\n while (addMore) {\n const { pattern } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"pattern\",\n message: \"Add usage pattern (regex)\",\n validate: (input: string) =>\n input.trim().length > 0 || \"Pattern cannot be empty.\"\n }\n ]);\n\n usagePatterns.push(pattern.trim());\n\n const { again } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"again\",\n message: \"Add another pattern?\",\n default: false\n }\n ]);\n\n addMore = again;\n }\n }\n\n const supportedLocales = parseLocales(\n answers.supportedLocales\n );\n\n config = {\n localesPath: answers.localesPath.trim(),\n defaultLocale: answers.defaultLocale.trim(),\n supportedLocales,\n keyStyle: answers.keyStyle,\n usagePatterns,\n autoSort: answers.autoSort\n };\n } else {\n config = {\n localesPath: \"./locales\",\n defaultLocale: \"en\",\n supportedLocales: [\"en\"],\n keyStyle: \"nested\",\n usagePatterns: DEFAULT_USAGE_PATTERNS,\n autoSort: true\n };\n }\n\n config.supportedLocales = normalizeLocales(\n config.supportedLocales,\n config.defaultLocale\n );\n\n compileUsagePatterns(config.usagePatterns);\n\n if (ci && !yes) {\n const action = configExists ? \"overwritten\" : \"created\";\n throw new Error(\n `CI mode: configuration file would be ${action}. Re-run with --yes to apply.`\n );\n }\n\n if (configExists && !yes) {\n const confirmed = await confirmAction(\n `This will overwrite \"${CONFIG_FILE_NAME}\". Continue?`,\n { skip: false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n }\n\n if (dryRun) {\n console.log(chalk.yellow(\"\\n[DRY RUN] Configuration not written.\"));\n return;\n }\n\n await fs.writeJson(configPath, config, { spaces: 2 });\n\n await maybeInitLocales(config, { dryRun: false });\n\n console.log(\n chalk.green(`\\n✔ Created ${CONFIG_FILE_NAME} successfully.`)\n );\n}\n\nfunction parseLocales(input: string): string[] {\n return input\n .split(\",\")\n .map(locale => locale.trim())\n .filter(Boolean);\n}\n\nfunction normalizeLocales(\n locales: string[],\n defaultLocale: string\n): string[] {\n const unique = new Set<string>();\n\n for (const locale of locales) {\n if (locale.length > 0) {\n unique.add(locale);\n }\n }\n\n if (!unique.has(defaultLocale)) {\n unique.add(defaultLocale);\n }\n\n return Array.from(unique);\n}\n\nasync function maybeInitLocales(\n config: InitConfigFile,\n options: { dryRun: boolean }\n): Promise<void> {\n const localesPath = path.resolve(\n process.cwd(),\n config.localesPath\n );\n\n if (options.dryRun) {\n return;\n }\n\n await fs.ensureDir(localesPath);\n\n const defaultLocaleFile = path.join(\n localesPath,\n `${config.defaultLocale}.json`\n );\n\n if (await fs.pathExists(defaultLocaleFile)) {\n return;\n }\n\n await fs.writeJson(defaultLocaleFile, {}, { spaces: 2 });\n}\n","import inquirer from \"inquirer\";\n\ninterface ConfirmOptions {\n skip?: boolean; // used when --yes flag is passed\n defaultValue?: boolean;\n ci?: boolean;\n}\n\nexport async function confirmAction(\n message: string,\n options: ConfirmOptions = {}\n): Promise<boolean> {\n const { skip = false, defaultValue = false, ci = false } = options;\n\n // If --yes is passed, skip prompt\n if (skip) {\n return true;\n }\n\n // If running in CI mode, require explicit confirmation via --yes\n if (ci) {\n throw new Error(\n \"Confirmation required in CI mode. Re-run with --yes to proceed.\"\n );\n }\n\n // If running in non-interactive environment\n if (!process.stdout.isTTY) {\n return defaultValue;\n }\n\n const { confirmed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"confirmed\",\n message,\n default: defaultValue\n }\n ]);\n\n return confirmed;\n}\n","import chalk from \"chalk\";\nimport ISO6391 from \"iso-639-1\";\nimport type { CommandContext } from \"../context/types.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\ninterface AddLangOptions {\n from?: string;\n strict?: boolean;\n}\n\nfunction isValidLocale(code: string): boolean {\n // Accept en or en-US format\n const parts = code.split(\"-\");\n\n if (parts.length === 1) {\n return ISO6391.validate(parts[0]!);\n }\n\n if (parts.length === 2) {\n return ISO6391.validate(parts[0]!);\n }\n\n return false;\n}\n\nexport async function addLang(\n lang: string,\n options: AddLangOptions,\n context: CommandContext\n): Promise<void> {\n const { config, fileManager } = context;\n const { yes, dryRun, ci } = context.options;\n\n const locale = lang.trim();\n\n if (!isValidLocale(locale)) {\n throw new Error(`Invalid language code: ${locale}`);\n }\n\n if (config.supportedLocales.includes(locale)) {\n throw new Error(`Language ${locale} already exists`);\n }\n\n const exists = await fileManager.localeExists(locale);\n if (exists) {\n throw new Error(`File already exists: ${locale}.json`);\n }\n\n let baseContent: Record<string, unknown> = {};\n\n // If clone from existing locale\n if (options.from) {\n const baseLocale = options.from;\n\n if (!config.supportedLocales.includes(baseLocale)) {\n throw new Error(`Base locale ${baseLocale} does not exist`);\n }\n\n baseContent = await fileManager.readLocale(baseLocale);\n }\n\n console.log(chalk.cyan(`\\nPreparing to add locale:`));\n console.log(chalk.yellow(` ${locale}\\n`));\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: locale \"${locale}\" would be created. Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n `This will create new locale \"${locale}\". Continue?`,\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n await fileManager.createLocale(locale, baseContent, { dryRun: dryRun ?? false });\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n console.log(\n chalk.green(`\\n✔ Locale \"${locale}\" created successfully.`)\n );\n console.log(\n chalk.gray(\n `Note: Add \"${locale}\" to supportedLocales in config manually.`\n )\n );\n }\n}\n","import chalk from \"chalk\";\nimport type { CommandContext } from \"../context/types.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\nexport async function removeLangCommand(\n context: CommandContext,\n lang: string\n): Promise<void> {\n const { config, fileManager, options } = context;\n const { yes, dryRun, ci } = options;\n\n const locale = lang.trim();\n\n // Validate locale exists\n if (!config.supportedLocales.includes(locale)) {\n throw new Error(\n `Locale \"${locale}\" is not in supportedLocales.`\n );\n }\n\n // Prevent removing default locale\n if (locale === config.defaultLocale) {\n throw new Error(\n `Cannot remove default locale \"${locale}\". ` +\n `Change defaultLocale first.`\n );\n }\n\n // Check if file exists\n const exists = await fileManager.localeExists(locale);\n if (!exists) {\n throw new Error(\n `Locale file \"${locale}.json\" does not exist.`\n );\n }\n\n console.log(chalk.cyan(`\\nPreparing to remove locale:`));\n console.log(chalk.yellow(` ${locale}\\n`));\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: locale \"${locale}\" would be removed. Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n `This will permanently delete \"${locale}.json\". Continue?`,\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n // Delete the locale file\n await fileManager.deleteLocale(locale, { dryRun: dryRun ?? false });\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n console.log(\n chalk.green(`\\n✔ Locale \"${locale}\" removed successfully.`)\n );\n console.log(\n chalk.gray(\n `Note: Remove \"${locale}\" from supportedLocales in config manually.`\n )\n );\n }\n}\n","import chalk from \"chalk\";\nimport type { CommandContext } from \"../context/types.js\";\nimport { flattenObject, unflattenObject } from \"../core/object-utils.js\";\nimport { validateNoStructuralConflict } from \"../core/key-validator.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\nexport async function addKeyCommand(\n context: CommandContext,\n key: string,\n options: { value: string }\n): Promise<void> {\n const { config, fileManager } = context;\n const { yes, dryRun, ci } = context.options;\n\n const value = options.value;\n\n if (!key || !value) {\n throw new Error(\"Both key and --value are required.\");\n }\n\n const locales = config.supportedLocales;\n\n console.log(chalk.cyan(`\\nPreparing to add key:`));\n console.log(chalk.yellow(` ${key}\\n`));\n\n const updatedLocales: string[] = [];\n\n for (const locale of locales) {\n const nested = await fileManager.readLocale(locale);\n const flat = flattenObject(nested);\n\n // Strict mode validation\n validateNoStructuralConflict(flat, key);\n\n if (flat[key] !== undefined) {\n throw new Error(\n `Key \"${key}\" already exists in locale \"${locale}\". Use update:key instead.`\n );\n }\n\n updatedLocales.push(locale);\n }\n\n console.log(chalk.white(\"This operation will update:\"));\n updatedLocales.forEach(l =>\n console.log(chalk.gray(` • ${l}.json`))\n );\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: key \"${key}\" would be added to ${updatedLocales.length} locale(s). Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n \"\\nDo you want to continue?\",\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n for (const locale of locales) {\n const nested = await fileManager.readLocale(locale);\n const flat = flattenObject(nested);\n\n flat[key] = locale === config.defaultLocale ? value : \"\";\n\n const finalData =\n config.keyStyle === \"nested\"\n ? unflattenObject(flat)\n : flat;\n\n await fileManager.writeLocale(locale, finalData, { dryRun: dryRun ?? false });\n }\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n updatedLocales.forEach(l =>\n console.log(chalk.green(`✔ Updated ${l}.json`))\n );\n\n console.log(\n chalk.green(\"\\n✨ Key added successfully across all locales.\")\n );\n }\n}\n","export type FlatObject = Record<string, any>;\n\nconst DANGEROUS_KEY_SEGMENTS = new Set([\n \"__proto__\",\n \"constructor\",\n \"prototype\"\n]);\n\nfunction assertSafeKeySegment(segment: string): void {\n if (DANGEROUS_KEY_SEGMENTS.has(segment)) {\n throw new Error(\n `Unsafe key segment \"${segment}\" is not allowed.`\n );\n }\n}\n\nexport function flattenObject(\n obj: Record<string, any>,\n parentKey = \"\",\n result: FlatObject = Object.create(null)\n): FlatObject {\n for (const key of Object.keys(obj)) {\n assertSafeKeySegment(key);\n const value = obj[key];\n const newKey = parentKey ? `${parentKey}.${key}` : key;\n\n if (\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value)\n ) {\n flattenObject(value, newKey, result);\n } else {\n result[newKey] = value;\n }\n }\n\n return result;\n}\n\nexport function unflattenObject(flatObj: FlatObject): Record<string, any> {\n const result: Record<string, any> = Object.create(null);\n\n for (const flatKey of Object.keys(flatObj)) {\n const keys = flatKey.split(\".\");\n let current = result;\n\n keys.forEach((key, index) => {\n assertSafeKeySegment(key);\n const isLast = index === keys.length - 1;\n\n if (isLast) {\n current[key] = flatObj[flatKey];\n } else {\n if (!current[key] || typeof current[key] !== \"object\") {\n current[key] = Object.create(null);\n }\n current = current[key];\n }\n });\n }\n\n return result;\n}\n\nexport function getAllFlatKeys(obj: Record<string, any>): string[] {\n return Object.keys(flattenObject(obj));\n}\n\nexport function removeEmptyObjects(obj: any): any {\n if (Array.isArray(obj)) {\n return obj;\n }\n\n if (obj !== null && typeof obj === \"object\") {\n const cleaned: any = Object.create(null);\n\n for (const key of Object.keys(obj)) {\n assertSafeKeySegment(key);\n const value = removeEmptyObjects(obj[key]);\n\n if (\n value !== undefined &&\n (typeof value !== \"object\" || Object.keys(value).length > 0)\n ) {\n cleaned[key] = value;\n }\n }\n\n return cleaned;\n }\n\n return obj;\n}\n","export function validateNoStructuralConflict(\n flatObject: Record<string, any>,\n newKey: string\n): void {\n const parts = newKey.split(\".\");\n\n // Parent conflict check\n for (let i = 1; i < parts.length; i++) {\n const parentPath = parts.slice(0, i).join(\".\");\n\n if (flatObject[parentPath] !== undefined) {\n throw new Error(\n `Structural conflict detected:\\n\\n` +\n `Cannot create key \"${newKey}\" because \"${parentPath}\" ` +\n `is already defined as a non-object value.\\n\\n` +\n `Resolve conflict before proceeding.`\n );\n }\n }\n\n // Child conflict check\n const prefix = `${newKey}.`;\n\n for (const existingKey of Object.keys(flatObject)) {\n if (existingKey.startsWith(prefix)) {\n throw new Error(\n `Structural conflict detected:\\n\\n` +\n `Cannot create key \"${newKey}\" because it would overwrite nested keys like \"${existingKey}\".\\n\\n` +\n `Resolve conflict before proceeding.`\n );\n }\n }\n}","import chalk from \"chalk\";\nimport type { CommandContext } from \"../context/types.js\";\nimport {\n flattenObject,\n unflattenObject\n} from \"../core/object-utils.js\";\nimport { validateNoStructuralConflict } from \"../core/key-validator.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\ninterface UpdateKeyOptions {\n value: string;\n locale?: string;\n}\n\nexport async function updateKeyCommand(\n context: CommandContext,\n key: string,\n options: UpdateKeyOptions\n): Promise<void> {\n const { config, fileManager, options: globalOptions } = context;\n const { yes, dryRun, ci } = globalOptions;\n\n const { value, locale } = options;\n\n if (!key || value === undefined) {\n throw new Error(\"Both key and --value are required.\");\n }\n\n const targetLocale = locale ?? config.defaultLocale;\n\n if (!config.supportedLocales.includes(targetLocale)) {\n throw new Error(\n `Locale \"${targetLocale}\" is not defined in configuration.`\n );\n }\n\n console.log(chalk.cyan(`\\nPreparing to update key:`));\n console.log(chalk.yellow(` ${key}`));\n console.log(chalk.gray(` Locale: ${targetLocale}\\n`));\n\n const nested = await fileManager.readLocale(targetLocale);\n const flat = flattenObject(nested);\n\n // Strict structural validation\n validateNoStructuralConflict(flat, key);\n\n if (flat[key] === undefined) {\n throw new Error(\n `Key \"${key}\" does not exist in locale \"${targetLocale}\".`\n );\n }\n\n console.log(\n chalk.white(\n `Old value: ${chalk.gray(JSON.stringify(flat[key]))}`\n )\n );\n console.log(\n chalk.white(\n `New value: ${chalk.green(JSON.stringify(value))}`\n )\n );\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: key \"${key}\" in \"${targetLocale}\" would be updated. Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n \"\\nDo you want to continue?\",\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n flat[key] = value;\n\n const rebuilt =\n config.keyStyle === \"nested\"\n ? unflattenObject(flat)\n : flat;\n\n await fileManager.writeLocale(targetLocale, rebuilt, {\n dryRun: dryRun ?? false\n });\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n console.log(\n chalk.green(\n `\\n✔ Successfully updated \"${key}\" in ${targetLocale}.json`\n )\n );\n }\n}\n","import chalk from \"chalk\";\nimport type { CommandContext } from \"../context/types.js\";\nimport {\n flattenObject,\n unflattenObject,\n removeEmptyObjects\n} from \"../core/object-utils.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\nexport async function removeKeyCommand(\n context: CommandContext,\n key: string\n): Promise<void> {\n const { config, fileManager, options } = context;\n const { yes, dryRun, ci } = options;\n\n if (!key) {\n throw new Error(\"Key is required.\");\n }\n\n const locales = config.supportedLocales;\n\n console.log(chalk.cyan(`\\nPreparing to remove key:`));\n console.log(chalk.yellow(` ${key}\\n`));\n\n const localesContainingKey: string[] = [];\n\n // First pass: check existence\n for (const locale of locales) {\n const nested = await fileManager.readLocale(locale);\n const flat = flattenObject(nested);\n\n if (flat[key] !== undefined) {\n localesContainingKey.push(locale);\n }\n }\n\n if (localesContainingKey.length === 0) {\n throw new Error(\n `Key \"${key}\" does not exist in any locale.`\n );\n }\n\n console.log(chalk.white(\"This operation will update:\"));\n localesContainingKey.forEach(l =>\n console.log(chalk.gray(` • ${l}.json`))\n );\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: key \"${key}\" would be removed from ${localesContainingKey.length} locale(s). Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n \"\\nThis will remove the key from ALL locales. Continue?\",\n yes !== undefined ? { skip: yes, ci: ci ?? false } : { ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n // Second pass: remove\n for (const locale of locales) {\n const nested = await fileManager.readLocale(locale);\n const flat = flattenObject(nested);\n\n if (flat[key] !== undefined) {\n delete flat[key];\n }\n\n const rebuilt =\n config.keyStyle === \"nested\"\n ? removeEmptyObjects(unflattenObject(flat))\n : flat;\n\n await fileManager.writeLocale(locale, rebuilt, dryRun !== undefined ? { dryRun } : undefined);\n }\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n localesContainingKey.forEach(l =>\n console.log(chalk.green(`✔ Updated ${l}.json`))\n );\n\n console.log(\n chalk.green(\"\\n✨ Key removed successfully from all locales.\")\n );\n }\n}\n","import fs from \"fs-extra\";\nimport { glob } from \"glob\";\nimport chalk from \"chalk\";\nimport { flattenObject, unflattenObject } from \"../core/object-utils.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\nimport type { CommandContext } from \"../context/types.js\";\n\nexport async function cleanUnusedCommand(\n context: CommandContext\n) {\n const { config, fileManager, options } = context;\n\n const { dryRun, yes, ci } = options;\n\n console.log(chalk.cyan(\"\\nScanning project for translation usage...\\n\"));\n\n const patterns = config.compiledUsagePatterns;\n\n if (!patterns || patterns.length === 0) {\n throw new Error(\n \"No usagePatterns defined in config.\"\n );\n }\n\n // Scan project files\n const files = await glob(\"src/**/*.{ts,tsx,js,jsx,html}\");\n\n const usedKeys = new Set<string>();\n\n for (const file of files) {\n const content = await fs.readFile(file, \"utf8\");\n\n for (const regex of patterns) {\n regex.lastIndex = 0;\n\n let match;\n\n while ((match = regex.exec(content))) {\n const key = match.groups?.key ?? match[1];\n\n if (key) {\n usedKeys.add(key);\n }\n }\n }\n }\n\n console.log(\n chalk.gray(`Found ${usedKeys.size} used keys in project\\n`)\n );\n\n // Read default locale\n const defaultLocale = config.defaultLocale;\n const nested = await fileManager.readLocale(defaultLocale);\n const flat = flattenObject(nested);\n\n const localeKeys = Object.keys(flat);\n\n const unusedKeys = localeKeys.filter(\n key => !usedKeys.has(key)\n );\n\n if (unusedKeys.length === 0) {\n console.log(\n chalk.green(\"✔ No unused translation keys found.\\n\")\n );\n return;\n }\n\n console.log(\n chalk.yellow(`Unused keys (${unusedKeys.length}):`)\n );\n\n unusedKeys.slice(0, 20).forEach(key =>\n console.log(` - ${key}`)\n );\n\n if (unusedKeys.length > 20) {\n console.log(\n chalk.gray(\n `... and ${unusedKeys.length - 20} more`\n )\n );\n }\n\n console.log(\"\");\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: ${unusedKeys.length} unused key(s) would be removed. Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n `This will remove ${unusedKeys.length} keys from ALL locales. Continue?`,\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\\n\"));\n return;\n }\n\n const locales = config.supportedLocales;\n\n for (const locale of locales) {\n const nestedLocale = await fileManager.readLocale(locale);\n const flatLocale = flattenObject(nestedLocale);\n\n for (const key of unusedKeys) {\n delete flatLocale[key];\n }\n\n const rebuilt =\n config.keyStyle === \"nested\"\n ? unflattenObject(flatLocale)\n : flatLocale;\n\n await fileManager.writeLocale(locale, rebuilt, {\n dryRun: dryRun ?? false\n });\n\n console.log(chalk.green(`✔ Updated ${locale}.json`));\n }\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\\n\")\n );\n } else {\n console.log(\n chalk.green(\n `\\n✨ Removed ${unusedKeys.length} unused keys from all locales.\\n`\n )\n );\n }\n}\n"],"mappings":";;;AAEA,SAAS,eAAe;AACxB,OAAOA,YAAW;;;ACHlB,OAAO,QAAQ;AACf,OAAO,UAAU;AACjB,SAAS,SAAS;AAGX,IAAM,mBAAmB;AAEhC,IAAM,eAAe,EAAE,OAAO;AAAA,EAC5B,aAAa,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC7B,eAAe,EAAE,OAAO,EAAE,IAAI,CAAC;AAAA,EAC/B,kBAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;AAAA,EAC3C,UAAU,EAAE,KAAK,CAAC,QAAQ,QAAQ,CAAC,EAAE,QAAQ,QAAQ;AAAA,EACrD,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC;AAAA,EAC7C,UAAU,EAAE,QAAQ,EAAE,QAAQ,IAAI;AACpC,CAAC;AAID,SAAS,oBAA4B;AACnC,QAAM,MAAM,QAAQ,IAAI;AACxB,SAAO,KAAK,KAAK,KAAK,gBAAgB;AACxC;AAEA,eAAsB,aAAkC;AACtD,QAAM,aAAa,kBAAkB;AAErC,MAAI,CAAE,MAAM,GAAG,WAAW,UAAU,GAAI;AACtC,UAAM,IAAI;AAAA,MACR,uBAAuB,gBAAgB;AAAA;AAAA,IAEzC;AAAA,EACF;AAEA,MAAI;AAEJ,MAAI;AACF,gBAAY,MAAM,GAAG,SAAS,UAAU;AAAA,EAC1C,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,mBAAmB,gBAAgB;AAAA,IACrC;AAAA,EACF;AAEA,QAAM,SAAS,aAAa,UAAU,SAAS;AAE/C,MAAI,CAAC,OAAO,SAAS;AACnB,UAAM,SAAS,OAAO,MAAM,OACzB,IAAI,OAAK,UAAK,EAAE,KAAK,KAAK,GAAG,CAAC,KAAK,EAAE,OAAO,EAAE,EAC9C,KAAK,IAAI;AAEZ,UAAM,IAAI;AAAA,MACR,4BAA4B,gBAAgB;AAAA,EAAM,MAAM;AAAA,IAC1D;AAAA,EACF;AAEA,QAAM,SAAS,OAAO;AAEtB,sBAAoB,MAAM;AAC1B,QAAM,wBAAwB;AAAA,IAC5B,OAAO;AAAA,EACT;AAEA,SAAO;AAAA,IACL,GAAG;AAAA,IACH;AAAA,EACF;AACF;AAEA,SAAS,oBAAoB,QAA4B;AACvD,MAAI,CAAC,OAAO,iBAAiB,SAAS,OAAO,aAAa,GAAG;AAC3D,UAAM,IAAI;AAAA,MACR,kBAAkB,OAAO,aAAa;AAAA,IACxC;AAAA,EACF;AAEA,QAAM,aAAa,eAAe,OAAO,gBAAgB;AACzD,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,IAAI;AAAA,MACR,gDAAgD,WAAW,KAAK,IAAI,CAAC;AAAA,IACvE;AAAA,EACF;AACF;AAEO,SAAS,qBAAqB,UAA8B;AACjE,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,CAAC;AAAA,EACV;AAEA,SAAO,SAAS,IAAI,CAAC,SAAS,UAAU;AACtC,QAAI;AAEJ,QAAI;AACF,cAAQ,IAAI,OAAO,SAAS,GAAG;AAAA,IACjC,SAAS,KAAK;AACZ,YAAM,IAAI;AAAA,QACR,kCAAkC,KAAK,MAAM,OAAO,GAAG,CAAC;AAAA,MAC1D;AAAA,IACF;AAEA,UAAM,aAAa,qBAAqB,OAAO;AAC/C,QAAI,eAAe,GAAG;AACpB,YAAM,IAAI;AAAA,QACR,iBAAiB,KAAK;AAAA,MACxB;AAAA,IACF;AAEA,WAAO;AAAA,EACT,CAAC;AACH;AAEA,SAAS,qBAAqB,SAAyB;AACrD,MAAI,QAAQ;AACZ,MAAI,cAAc;AAElB,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,OAAO,QAAQ,CAAC;AAEtB,QAAI,SAAS,MAAM;AACjB,WAAK;AACL;AAAA,IACF;AAEA,QAAI,SAAS,KAAK;AAChB,oBAAc;AACd;AAAA,IACF;AAEA,QAAI,SAAS,OAAO,aAAa;AAC/B,oBAAc;AACd;AAAA,IACF;AAEA,QAAI,aAAa;AACf;AAAA,IACF;AAEA,QAAI,SAAS,KAAK;AAChB;AAAA,IACF;AAEA,UAAM,OAAO,QAAQ,IAAI,CAAC;AAC1B,QAAI,SAAS,KAAK;AAChB,eAAS;AACT;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,QAAI,UAAU,KAAK;AACjB;AAAA,IACF;AAEA,UAAM,QAAQ,QAAQ,IAAI,CAAC;AAC3B,QAAI,UAAU,OAAO,UAAU,KAAK;AAClC;AAAA,IACF;AAEA,aAAS;AAAA,EACX;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,KAAyB;AAC/C,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,aAAuB,CAAC;AAE9B,aAAW,QAAQ,KAAK;AACtB,QAAI,KAAK,IAAI,IAAI,GAAG;AAClB,iBAAW,KAAK,IAAI;AAAA,IACtB;AACA,SAAK,IAAI,IAAI;AAAA,EACf;AAEA,SAAO;AACT;;;AC9KA,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAGV,IAAM,cAAN,MAAkB;AAAA,EACf;AAAA,EACA;AAAA,EAER,YAAY,QAAoB;AAC9B,SAAK,SAAS;AACd,SAAK,cAAcA,MAAK,QAAQ,QAAQ,IAAI,GAAG,OAAO,WAAW;AAAA,EACnE;AAAA,EAEA,kBAAkB,QAAwB;AACxC,WAAOA,MAAK,KAAK,KAAK,aAAa,GAAG,MAAM,OAAO;AAAA,EACrD;AAAA,EAEA,MAAM,yBAAwC;AAC5C,UAAMD,IAAG,UAAU,KAAK,WAAW;AAAA,EACrC;AAAA,EAEA,MAAM,aAAa,QAAkC;AACnD,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,WAAOA,IAAG,WAAW,QAAQ;AAAA,EAC/B;AAAA,EAEA,MAAM,cAAiC;AACrC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEE,MAAM,WAAW,QAA8C;AAC/D,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAE9C,QAAI,CAAE,MAAMA,IAAG,WAAW,QAAQ,GAAI;AACpC,YAAM,IAAI,MAAM,gBAAgB,MAAM,wBAAwB;AAAA,IAChE;AAEA,QAAI;AACF,aAAO,MAAMA,IAAG,SAAS,QAAQ;AAAA,IACnC,QAAQ;AACN,YAAM,IAAI,MAAM,oBAAoB,MAAM,SAAS;AAAA,IACrD;AAAA,EACF;AAAA,EAEE,MAAM,YACN,QACA,MACA,SACe;AACf,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAE9C,UAAM,YAAY,KAAK,OAAO,WAC1B,KAAK,oBAAoB,IAAI,IAC7B;AAEJ,QAAI,SAAS,QAAQ;AACnB;AAAA,IACF;AAEA,UAAMA,IAAG,UAAU,UAAU,WAAW,EAAE,QAAQ,EAAE,CAAC;AAAA,EACvD;AAAA,EAEE,MAAM,aACN,QACA,SACe;AACf,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAE9C,QAAI,CAAE,MAAMA,IAAG,WAAW,QAAQ,GAAI;AACpC,YAAM,IAAI,MAAM,WAAW,MAAM,mBAAmB;AAAA,IACtD;AAEA,QAAI,SAAS,QAAQ;AACnB;AAAA,IACF;AAEA,UAAMA,IAAG,OAAO,QAAQ;AAAA,EAC1B;AAAA,EAEE,MAAM,aACN,QACA,aACA,SACe;AACf,UAAM,KAAK,uBAAuB;AAElC,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAE9C,QAAI,MAAMA,IAAG,WAAW,QAAQ,GAAG;AACjC,YAAM,IAAI,MAAM,WAAW,MAAM,mBAAmB;AAAA,IACtD;AAEA,QAAI,SAAS,QAAQ;AACnB;AAAA,IACF;AAEA,UAAMA,IAAG,UAAU,UAAU,aAAa,EAAE,QAAQ,EAAE,CAAC;AAAA,EACzD;AAAA,EAEU,oBAAoB,KAAe;AAC3C,QAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,aAAO,IAAI,IAAI,UAAQ,KAAK,oBAAoB,IAAI,CAAC;AAAA,IACvD;AAEA,QAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,aAAO,OAAO,KAAK,GAAG,EACnB,KAAK,EACL,OAAO,CAAC,KAAU,QAAQ;AACzB,YAAI,GAAG,IAAI,KAAK,oBAAoB,IAAI,GAAG,CAAC;AAC5C,eAAO;AAAA,MACT,GAAG,uBAAO,OAAO,IAAI,CAAC;AAAA,IAC1B;AAEA,WAAO;AAAA,EACT;AAEF;;;AChHA,eAAsB,aACpB,SACyB;AACzB,QAAM,SAAS,MAAM,WAAW;AAChC,QAAM,cAAc,IAAI,YAAY,MAAM;AAE1C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACfA,OAAO,WAAW;AAClB,OAAOE,SAAQ;AACf,OAAOC,eAAc;AACrB,OAAOC,WAAU;;;ACHjB,OAAO,cAAc;AAQrB,eAAsB,cACpB,SACA,UAA0B,CAAC,GACT;AAClB,QAAM,EAAE,OAAO,OAAO,eAAe,OAAO,KAAK,MAAM,IAAI;AAG3D,MAAI,MAAM;AACR,WAAO;AAAA,EACT;AAGA,MAAI,IAAI;AACN,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,MAAI,CAAC,QAAQ,OAAO,OAAO;AACzB,WAAO;AAAA,EACT;AAEA,QAAM,EAAE,UAAU,IAAI,MAAM,SAAS,OAAO;AAAA,IAC1C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,SAAO;AACT;;;ADvBA,IAAM,yBAAyB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAsB,YACpB,SACe;AACf,QAAM,EAAE,KAAK,QAAQ,IAAI,MAAM,IAAI;AACnC,QAAM,aAAaC,MAAK,KAAK,QAAQ,IAAI,GAAG,gBAAgB;AAC5D,QAAM,eAAe,MAAMC,IAAG,WAAW,UAAU;AAEnD,MAAI,gBAAgB,CAAC,OAAO;AAC1B,UAAM,IAAI;AAAA,MACR,uBAAuB,gBAAgB;AAAA,IAEzC;AAAA,EACF;AAEA,QAAM,YAAY,QAAQ,OAAO,SAAS,CAAC,OAAO,CAAC;AAEnD,MAAI;AAEJ,MAAI,WAAW;AACb,UAAM,UAAU,MAAMC,UAAS,OAAO;AAAA,MACpC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,UACT,MAAM,KAAK,EAAE,SAAS,KAAK;AAAA,MAC/B;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,UAAU,CAAC,UACT,MAAM,KAAK,EAAE,UAAU,KAAK;AAAA,MAChC;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS,CAACC,aACRA,SAAQ;AAAA,MACZ;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS,CAAC,UAAU,MAAM;AAAA,QAC1B,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AAED,QAAI,gBAA0B;AAE9B,QAAI,CAAC,QAAQ,yBAAyB;AACpC,sBAAgB,CAAC;AACjB,UAAI,UAAU;AAEd,aAAO,SAAS;AACd,cAAM,EAAE,QAAQ,IAAI,MAAMD,UAAS,OAAO;AAAA,UACxC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,UAAU,CAAC,UACT,MAAM,KAAK,EAAE,SAAS,KAAK;AAAA,UAC/B;AAAA,QACF,CAAC;AAED,sBAAc,KAAK,QAAQ,KAAK,CAAC;AAEjC,cAAM,EAAE,MAAM,IAAI,MAAMA,UAAS,OAAO;AAAA,UACtC;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF,CAAC;AAED,kBAAU;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,mBAAmB;AAAA,MACvB,QAAQ;AAAA,IACV;AAEA,aAAS;AAAA,MACP,aAAa,QAAQ,YAAY,KAAK;AAAA,MACtC,eAAe,QAAQ,cAAc,KAAK;AAAA,MAC1C;AAAA,MACA,UAAU,QAAQ;AAAA,MAClB;AAAA,MACA,UAAU,QAAQ;AAAA,IACpB;AAAA,EACF,OAAO;AACL,aAAS;AAAA,MACP,aAAa;AAAA,MACb,eAAe;AAAA,MACf,kBAAkB,CAAC,IAAI;AAAA,MACvB,UAAU;AAAA,MACV,eAAe;AAAA,MACf,UAAU;AAAA,IACZ;AAAA,EACF;AAEA,SAAO,mBAAmB;AAAA,IACxB,OAAO;AAAA,IACP,OAAO;AAAA,EACT;AAEA,uBAAqB,OAAO,aAAa;AAEzC,MAAI,MAAM,CAAC,KAAK;AACd,UAAM,SAAS,eAAe,gBAAgB;AAC9C,UAAM,IAAI;AAAA,MACR,wCAAwC,MAAM;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,gBAAgB,CAAC,KAAK;AACxB,UAAM,YAAY,MAAM;AAAA,MACtB,wBAAwB,gBAAgB;AAAA,MACxC,EAAE,MAAM,OAAO,IAAI,MAAM,MAAM;AAAA,IACjC;AAEA,QAAI,CAAC,WAAW;AACd,cAAQ,IAAI,MAAM,IAAI,wBAAwB,CAAC;AAC/C;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ;AACV,YAAQ,IAAI,MAAM,OAAO,wCAAwC,CAAC;AAClE;AAAA,EACF;AAEA,QAAMD,IAAG,UAAU,YAAY,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAEpD,QAAM,iBAAiB,QAAQ,EAAE,QAAQ,MAAM,CAAC;AAEhD,UAAQ;AAAA,IACN,MAAM,MAAM;AAAA,iBAAe,gBAAgB,gBAAgB;AAAA,EAC7D;AACF;AAEA,SAAS,aAAa,OAAyB;AAC7C,SAAO,MACJ,MAAM,GAAG,EACT,IAAI,YAAU,OAAO,KAAK,CAAC,EAC3B,OAAO,OAAO;AACnB;AAEA,SAAS,iBACP,SACA,eACU;AACV,QAAM,SAAS,oBAAI,IAAY;AAE/B,aAAW,UAAU,SAAS;AAC5B,QAAI,OAAO,SAAS,GAAG;AACrB,aAAO,IAAI,MAAM;AAAA,IACnB;AAAA,EACF;AAEA,MAAI,CAAC,OAAO,IAAI,aAAa,GAAG;AAC9B,WAAO,IAAI,aAAa;AAAA,EAC1B;AAEA,SAAO,MAAM,KAAK,MAAM;AAC1B;AAEA,eAAe,iBACb,QACA,SACe;AACf,QAAM,cAAcD,MAAK;AAAA,IACvB,QAAQ,IAAI;AAAA,IACZ,OAAO;AAAA,EACT;AAEA,MAAI,QAAQ,QAAQ;AAClB;AAAA,EACF;AAEA,QAAMC,IAAG,UAAU,WAAW;AAE9B,QAAM,oBAAoBD,MAAK;AAAA,IAC7B;AAAA,IACA,GAAG,OAAO,aAAa;AAAA,EACzB;AAEA,MAAI,MAAMC,IAAG,WAAW,iBAAiB,GAAG;AAC1C;AAAA,EACF;AAEA,QAAMA,IAAG,UAAU,mBAAmB,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;AACzD;;;AE1OA,OAAOG,YAAW;AAClB,OAAO,aAAa;AASpB,SAAS,cAAc,MAAuB;AAE5C,QAAM,QAAQ,KAAK,MAAM,GAAG;AAE5B,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,QAAQ,SAAS,MAAM,CAAC,CAAE;AAAA,EACnC;AAEA,MAAI,MAAM,WAAW,GAAG;AACtB,WAAO,QAAQ,SAAS,MAAM,CAAC,CAAE;AAAA,EACnC;AAEA,SAAO;AACT;AAEA,eAAsB,QACpB,MACA,SACA,SACe;AACf,QAAM,EAAE,QAAQ,YAAY,IAAI;AAChC,QAAM,EAAE,KAAK,QAAQ,GAAG,IAAI,QAAQ;AAEpC,QAAM,SAAS,KAAK,KAAK;AAEzB,MAAI,CAAC,cAAc,MAAM,GAAG;AAC1B,UAAM,IAAI,MAAM,0BAA0B,MAAM,EAAE;AAAA,EACpD;AAEA,MAAI,OAAO,iBAAiB,SAAS,MAAM,GAAG;AAC5C,UAAM,IAAI,MAAM,YAAY,MAAM,iBAAiB;AAAA,EACrD;AAEA,QAAM,SAAS,MAAM,YAAY,aAAa,MAAM;AACpD,MAAI,QAAQ;AACV,UAAM,IAAI,MAAM,wBAAwB,MAAM,OAAO;AAAA,EACvD;AAEA,MAAI,cAAuC,CAAC;AAG5C,MAAI,QAAQ,MAAM;AAChB,UAAM,aAAa,QAAQ;AAE3B,QAAI,CAAC,OAAO,iBAAiB,SAAS,UAAU,GAAG;AACjD,YAAM,IAAI,MAAM,eAAe,UAAU,iBAAiB;AAAA,IAC5D;AAEA,kBAAc,MAAM,YAAY,WAAW,UAAU;AAAA,EACvD;AAEA,UAAQ,IAAIC,OAAM,KAAK;AAAA,yBAA4B,CAAC;AACpD,UAAQ,IAAIA,OAAM,OAAO,KAAK,MAAM;AAAA,CAAI,CAAC;AAEzC,MAAI,MAAM,CAAC,KAAK;AACd,UAAM,IAAI;AAAA,MACR,oBAAoB,MAAM;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,YAAY,MAAM;AAAA,IACtB,gCAAgC,MAAM;AAAA,IACtC,EAAE,MAAM,OAAO,OAAO,IAAI,MAAM,MAAM;AAAA,EACxC;AAEA,MAAI,CAAC,WAAW;AACd,YAAQ,IAAIA,OAAM,IAAI,wBAAwB,CAAC;AAC/C;AAAA,EACF;AAEA,QAAM,YAAY,aAAa,QAAQ,aAAa,EAAE,QAAQ,UAAU,MAAM,CAAC;AAE/E,MAAI,QAAQ;AACV,YAAQ;AAAA,MACNA,OAAM,OAAO,qCAAqC;AAAA,IACpD;AAAA,EACF,OAAO;AACL,YAAQ;AAAA,MACNA,OAAM,MAAM;AAAA,iBAAe,MAAM,yBAAyB;AAAA,IAC5D;AACA,YAAQ;AAAA,MACNA,OAAM;AAAA,QACJ,cAAc,MAAM;AAAA,MACtB;AAAA,IACF;AAAA,EACF;AACF;;;AChGA,OAAOC,YAAW;AAIlB,eAAsB,kBACpB,SACA,MACe;AACf,QAAM,EAAE,QAAQ,aAAa,QAAQ,IAAI;AACzC,QAAM,EAAE,KAAK,QAAQ,GAAG,IAAI;AAE5B,QAAM,SAAS,KAAK,KAAK;AAGzB,MAAI,CAAC,OAAO,iBAAiB,SAAS,MAAM,GAAG;AAC7C,UAAM,IAAI;AAAA,MACR,WAAW,MAAM;AAAA,IACnB;AAAA,EACF;AAGA,MAAI,WAAW,OAAO,eAAe;AACnC,UAAM,IAAI;AAAA,MACR,iCAAiC,MAAM;AAAA,IAEzC;AAAA,EACF;AAGA,QAAM,SAAS,MAAM,YAAY,aAAa,MAAM;AACpD,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI;AAAA,MACR,gBAAgB,MAAM;AAAA,IACxB;AAAA,EACF;AAEA,UAAQ,IAAIC,OAAM,KAAK;AAAA,4BAA+B,CAAC;AACvD,UAAQ,IAAIA,OAAM,OAAO,KAAK,MAAM;AAAA,CAAI,CAAC;AAEzC,MAAI,MAAM,CAAC,KAAK;AACd,UAAM,IAAI;AAAA,MACR,oBAAoB,MAAM;AAAA,IAC5B;AAAA,EACF;AAEA,QAAM,YAAY,MAAM;AAAA,IACtB,iCAAiC,MAAM;AAAA,IACvC,EAAE,MAAM,OAAO,OAAO,IAAI,MAAM,MAAM;AAAA,EACxC;AAEA,MAAI,CAAC,WAAW;AACd,YAAQ,IAAIA,OAAM,IAAI,wBAAwB,CAAC;AAC/C;AAAA,EACF;AAGA,QAAM,YAAY,aAAa,QAAQ,EAAE,QAAQ,UAAU,MAAM,CAAC;AAElE,MAAI,QAAQ;AACV,YAAQ;AAAA,MACNA,OAAM,OAAO,qCAAqC;AAAA,IACpD;AAAA,EACF,OAAO;AACL,YAAQ;AAAA,MACNA,OAAM,MAAM;AAAA,iBAAe,MAAM,yBAAyB;AAAA,IAC5D;AACA,YAAQ;AAAA,MACNA,OAAM;AAAA,QACJ,iBAAiB,MAAM;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AACF;;;ACxEA,OAAOC,YAAW;;;ACElB,IAAM,yBAAyB,oBAAI,IAAI;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,qBAAqB,SAAuB;AACnD,MAAI,uBAAuB,IAAI,OAAO,GAAG;AACvC,UAAM,IAAI;AAAA,MACR,uBAAuB,OAAO;AAAA,IAChC;AAAA,EACF;AACF;AAEO,SAAS,cACd,KACA,YAAY,IACZ,SAAqB,uBAAO,OAAO,IAAI,GAC3B;AACZ,aAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAClC,yBAAqB,GAAG;AACxB,UAAM,QAAQ,IAAI,GAAG;AACrB,UAAM,SAAS,YAAY,GAAG,SAAS,IAAI,GAAG,KAAK;AAEnD,QACE,SACA,OAAO,UAAU,YACjB,CAAC,MAAM,QAAQ,KAAK,GACpB;AACA,oBAAc,OAAO,QAAQ,MAAM;AAAA,IACrC,OAAO;AACL,aAAO,MAAM,IAAI;AAAA,IACnB;AAAA,EACF;AAEA,SAAO;AACT;AAEO,SAAS,gBAAgB,SAA0C;AACxE,QAAM,SAA8B,uBAAO,OAAO,IAAI;AAEtD,aAAW,WAAW,OAAO,KAAK,OAAO,GAAG;AAC1C,UAAM,OAAO,QAAQ,MAAM,GAAG;AAC9B,QAAI,UAAU;AAEd,SAAK,QAAQ,CAAC,KAAK,UAAU;AAC3B,2BAAqB,GAAG;AACxB,YAAM,SAAS,UAAU,KAAK,SAAS;AAEvC,UAAI,QAAQ;AACV,gBAAQ,GAAG,IAAI,QAAQ,OAAO;AAAA,MAChC,OAAO;AACL,YAAI,CAAC,QAAQ,GAAG,KAAK,OAAO,QAAQ,GAAG,MAAM,UAAU;AACrD,kBAAQ,GAAG,IAAI,uBAAO,OAAO,IAAI;AAAA,QACnC;AACA,kBAAU,QAAQ,GAAG;AAAA,MACvB;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAMO,SAAS,mBAAmB,KAAe;AAChD,MAAI,MAAM,QAAQ,GAAG,GAAG;AACtB,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,QAAQ,OAAO,QAAQ,UAAU;AAC3C,UAAM,UAAe,uBAAO,OAAO,IAAI;AAEvC,eAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAClC,2BAAqB,GAAG;AACxB,YAAM,QAAQ,mBAAmB,IAAI,GAAG,CAAC;AAEzC,UACE,UAAU,WACT,OAAO,UAAU,YAAY,OAAO,KAAK,KAAK,EAAE,SAAS,IAC1D;AACA,gBAAQ,GAAG,IAAI;AAAA,MACjB;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAEA,SAAO;AACT;;;AC7FO,SAAS,6BACd,YACA,QACM;AACN,QAAM,QAAQ,OAAO,MAAM,GAAG;AAG9B,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,aAAa,MAAM,MAAM,GAAG,CAAC,EAAE,KAAK,GAAG;AAE7C,QAAI,WAAW,UAAU,MAAM,QAAW;AACxC,YAAM,IAAI;AAAA,QACR;AAAA;AAAA,qBACsB,MAAM,cAAc,UAAU;AAAA;AAAA;AAAA,MAGtD;AAAA,IACF;AAAA,EACF;AAGA,QAAM,SAAS,GAAG,MAAM;AAExB,aAAW,eAAe,OAAO,KAAK,UAAU,GAAG;AACjD,QAAI,YAAY,WAAW,MAAM,GAAG;AAClC,YAAM,IAAI;AAAA,QACR;AAAA;AAAA,qBACsB,MAAM,kDAAkD,WAAW;AAAA;AAAA;AAAA,MAE3F;AAAA,IACF;AAAA,EACF;AACF;;;AF1BA,eAAsB,cACpB,SACA,KACA,SACe;AACf,QAAM,EAAE,QAAQ,YAAY,IAAI;AAChC,QAAM,EAAE,KAAK,QAAQ,GAAG,IAAI,QAAQ;AAEpC,QAAM,QAAQ,QAAQ;AAEtB,MAAI,CAAC,OAAO,CAAC,OAAO;AAClB,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,QAAM,UAAU,OAAO;AAEvB,UAAQ,IAAIC,OAAM,KAAK;AAAA,sBAAyB,CAAC;AACjD,UAAQ,IAAIA,OAAM,OAAO,KAAK,GAAG;AAAA,CAAI,CAAC;AAEtC,QAAM,iBAA2B,CAAC;AAElC,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,MAAM,YAAY,WAAW,MAAM;AAClD,UAAM,OAAO,cAAc,MAAM;AAGjC,iCAA6B,MAAM,GAAG;AAEtC,QAAI,KAAK,GAAG,MAAM,QAAW;AAC3B,YAAM,IAAI;AAAA,QACR,QAAQ,GAAG,+BAA+B,MAAM;AAAA,MAClD;AAAA,IACF;AAEA,mBAAe,KAAK,MAAM;AAAA,EAC5B;AAEA,UAAQ,IAAIA,OAAM,MAAM,6BAA6B,CAAC;AACtD,iBAAe;AAAA,IAAQ,OACrB,QAAQ,IAAIA,OAAM,KAAK,YAAO,CAAC,OAAO,CAAC;AAAA,EACzC;AAEA,MAAI,MAAM,CAAC,KAAK;AACd,UAAM,IAAI;AAAA,MACR,iBAAiB,GAAG,uBAAuB,eAAe,MAAM;AAAA,IAClE;AAAA,EACF;AAEA,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA,EAAE,MAAM,OAAO,OAAO,IAAI,MAAM,MAAM;AAAA,EACxC;AAEA,MAAI,CAAC,WAAW;AACd,YAAQ,IAAIA,OAAM,IAAI,wBAAwB,CAAC;AAC/C;AAAA,EACF;AAEA,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,MAAM,YAAY,WAAW,MAAM;AAClD,UAAM,OAAO,cAAc,MAAM;AAEjC,SAAK,GAAG,IAAI,WAAW,OAAO,gBAAgB,QAAQ;AAEtD,UAAM,YACJ,OAAO,aAAa,WAChB,gBAAgB,IAAI,IACpB;AAEN,UAAM,YAAY,YAAY,QAAQ,WAAW,EAAE,QAAQ,UAAU,MAAM,CAAC;AAAA,EAC9E;AAEA,MAAI,QAAQ;AACV,YAAQ;AAAA,MACNA,OAAM,OAAO,qCAAqC;AAAA,IACpD;AAAA,EACF,OAAO;AACL,mBAAe;AAAA,MAAQ,OACrB,QAAQ,IAAIA,OAAM,MAAM,kBAAa,CAAC,OAAO,CAAC;AAAA,IAChD;AAEA,YAAQ;AAAA,MACNA,OAAM,MAAM,qDAAgD;AAAA,IAC9D;AAAA,EACF;AACF;;;AG3FA,OAAOC,YAAW;AAclB,eAAsB,iBACpB,SACA,KACA,SACe;AACf,QAAM,EAAE,QAAQ,aAAa,SAAS,cAAc,IAAI;AACxD,QAAM,EAAE,KAAK,QAAQ,GAAG,IAAI;AAE5B,QAAM,EAAE,OAAO,OAAO,IAAI;AAE1B,MAAI,CAAC,OAAO,UAAU,QAAW;AAC/B,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,QAAM,eAAe,UAAU,OAAO;AAEtC,MAAI,CAAC,OAAO,iBAAiB,SAAS,YAAY,GAAG;AACnD,UAAM,IAAI;AAAA,MACR,WAAW,YAAY;AAAA,IACzB;AAAA,EACF;AAEA,UAAQ,IAAIC,OAAM,KAAK;AAAA,yBAA4B,CAAC;AACpD,UAAQ,IAAIA,OAAM,OAAO,KAAK,GAAG,EAAE,CAAC;AACpC,UAAQ,IAAIA,OAAM,KAAK,aAAa,YAAY;AAAA,CAAI,CAAC;AAErD,QAAM,SAAS,MAAM,YAAY,WAAW,YAAY;AACxD,QAAM,OAAO,cAAc,MAAM;AAGjC,+BAA6B,MAAM,GAAG;AAEtC,MAAI,KAAK,GAAG,MAAM,QAAW;AAC3B,UAAM,IAAI;AAAA,MACR,QAAQ,GAAG,+BAA+B,YAAY;AAAA,IACxD;AAAA,EACF;AAEA,UAAQ;AAAA,IACNA,OAAM;AAAA,MACJ,cAAcA,OAAM,KAAK,KAAK,UAAU,KAAK,GAAG,CAAC,CAAC,CAAC;AAAA,IACrD;AAAA,EACF;AACA,UAAQ;AAAA,IACNA,OAAM;AAAA,MACJ,cAAcA,OAAM,MAAM,KAAK,UAAU,KAAK,CAAC,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,MAAI,MAAM,CAAC,KAAK;AACd,UAAM,IAAI;AAAA,MACR,iBAAiB,GAAG,SAAS,YAAY;AAAA,IAC3C;AAAA,EACF;AAEA,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA,EAAE,MAAM,OAAO,OAAO,IAAI,MAAM,MAAM;AAAA,EACxC;AAEA,MAAI,CAAC,WAAW;AACd,YAAQ,IAAIA,OAAM,IAAI,wBAAwB,CAAC;AAC/C;AAAA,EACF;AAEA,OAAK,GAAG,IAAI;AAEZ,QAAM,UACJ,OAAO,aAAa,WAChB,gBAAgB,IAAI,IACpB;AAEN,QAAM,YAAY,YAAY,cAAc,SAAS;AAAA,IACnD,QAAQ,UAAU;AAAA,EACpB,CAAC;AAED,MAAI,QAAQ;AACV,YAAQ;AAAA,MACNA,OAAM,OAAO,qCAAqC;AAAA,IACpD;AAAA,EACF,OAAO;AACL,YAAQ;AAAA,MACNA,OAAM;AAAA,QACJ;AAAA,+BAA6B,GAAG,QAAQ,YAAY;AAAA,MACtD;AAAA,IACF;AAAA,EACF;AACF;;;ACrGA,OAAOC,YAAW;AASlB,eAAsB,iBACpB,SACA,KACe;AACf,QAAM,EAAE,QAAQ,aAAa,QAAQ,IAAI;AACzC,QAAM,EAAE,KAAK,QAAQ,GAAG,IAAI;AAE5B,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,kBAAkB;AAAA,EACpC;AAEA,QAAM,UAAU,OAAO;AAEvB,UAAQ,IAAIC,OAAM,KAAK;AAAA,yBAA4B,CAAC;AACpD,UAAQ,IAAIA,OAAM,OAAO,KAAK,GAAG;AAAA,CAAI,CAAC;AAEtC,QAAM,uBAAiC,CAAC;AAGxC,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,MAAM,YAAY,WAAW,MAAM;AAClD,UAAM,OAAO,cAAc,MAAM;AAEjC,QAAI,KAAK,GAAG,MAAM,QAAW;AAC3B,2BAAqB,KAAK,MAAM;AAAA,IAClC;AAAA,EACF;AAEA,MAAI,qBAAqB,WAAW,GAAG;AACrC,UAAM,IAAI;AAAA,MACR,QAAQ,GAAG;AAAA,IACb;AAAA,EACF;AAEA,UAAQ,IAAIA,OAAM,MAAM,6BAA6B,CAAC;AACtD,uBAAqB;AAAA,IAAQ,OAC3B,QAAQ,IAAIA,OAAM,KAAK,YAAO,CAAC,OAAO,CAAC;AAAA,EACzC;AAEA,MAAI,MAAM,CAAC,KAAK;AACd,UAAM,IAAI;AAAA,MACR,iBAAiB,GAAG,2BAA2B,qBAAqB,MAAM;AAAA,IAC5E;AAAA,EACF;AAEA,QAAM,YAAY,MAAM;AAAA,IACtB;AAAA,IACA,QAAQ,SAAY,EAAE,MAAM,KAAK,IAAI,MAAM,MAAM,IAAI,EAAE,IAAI,MAAM,MAAM;AAAA,EACzE;AAEA,MAAI,CAAC,WAAW;AACd,YAAQ,IAAIA,OAAM,IAAI,wBAAwB,CAAC;AAC/C;AAAA,EACF;AAGA,aAAW,UAAU,SAAS;AAC5B,UAAM,SAAS,MAAM,YAAY,WAAW,MAAM;AAClD,UAAM,OAAO,cAAc,MAAM;AAEjC,QAAI,KAAK,GAAG,MAAM,QAAW;AAC3B,aAAO,KAAK,GAAG;AAAA,IACjB;AAEA,UAAM,UACJ,OAAO,aAAa,WAChB,mBAAmB,gBAAgB,IAAI,CAAC,IACxC;AAEN,UAAM,YAAY,YAAY,QAAQ,SAAS,WAAW,SAAY,EAAE,OAAO,IAAI,MAAS;AAAA,EAC9F;AAEA,MAAI,QAAQ;AACV,YAAQ;AAAA,MACNA,OAAM,OAAO,qCAAqC;AAAA,IACpD;AAAA,EACF,OAAO;AACL,yBAAqB;AAAA,MAAQ,OAC3B,QAAQ,IAAIA,OAAM,MAAM,kBAAa,CAAC,OAAO,CAAC;AAAA,IAChD;AAEA,YAAQ;AAAA,MACNA,OAAM,MAAM,qDAAgD;AAAA,IAC9D;AAAA,EACF;AACF;;;AC9FA,OAAOC,SAAQ;AACf,SAAS,YAAY;AACrB,OAAOC,YAAW;AAKlB,eAAsB,mBACpB,SACA;AACA,QAAM,EAAE,QAAQ,aAAa,QAAQ,IAAI;AAEzC,QAAM,EAAE,QAAQ,KAAK,GAAG,IAAI;AAE5B,UAAQ,IAAIC,OAAM,KAAK,+CAA+C,CAAC;AAEvE,QAAM,WAAW,OAAO;AAExB,MAAI,CAAC,YAAY,SAAS,WAAW,GAAG;AACtC,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAGA,QAAM,QAAQ,MAAM,KAAK,+BAA+B;AAExD,QAAM,WAAW,oBAAI,IAAY;AAEjC,aAAW,QAAQ,OAAO;AACxB,UAAM,UAAU,MAAMC,IAAG,SAAS,MAAM,MAAM;AAE9C,eAAW,SAAS,UAAU;AAC5B,YAAM,YAAY;AAElB,UAAI;AAEJ,aAAQ,QAAQ,MAAM,KAAK,OAAO,GAAI;AACpC,cAAM,MAAM,MAAM,QAAQ,OAAO,MAAM,CAAC;AAExC,YAAI,KAAK;AACP,mBAAS,IAAI,GAAG;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,UAAQ;AAAA,IACND,OAAM,KAAK,SAAS,SAAS,IAAI;AAAA,CAAyB;AAAA,EAC5D;AAGA,QAAM,gBAAgB,OAAO;AAC7B,QAAM,SAAS,MAAM,YAAY,WAAW,aAAa;AACzD,QAAM,OAAO,cAAc,MAAM;AAEjC,QAAM,aAAa,OAAO,KAAK,IAAI;AAEnC,QAAM,aAAa,WAAW;AAAA,IAC5B,SAAO,CAAC,SAAS,IAAI,GAAG;AAAA,EAC1B;AAEA,MAAI,WAAW,WAAW,GAAG;AAC3B,YAAQ;AAAA,MACNA,OAAM,MAAM,4CAAuC;AAAA,IACrD;AACA;AAAA,EACF;AAEA,UAAQ;AAAA,IACNA,OAAM,OAAO,gBAAgB,WAAW,MAAM,IAAI;AAAA,EACpD;AAEA,aAAW,MAAM,GAAG,EAAE,EAAE;AAAA,IAAQ,SAC9B,QAAQ,IAAI,OAAO,GAAG,EAAE;AAAA,EAC1B;AAEA,MAAI,WAAW,SAAS,IAAI;AAC1B,YAAQ;AAAA,MACNA,OAAM;AAAA,QACJ,WAAW,WAAW,SAAS,EAAE;AAAA,MACnC;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AAEd,MAAI,MAAM,CAAC,KAAK;AACd,UAAM,IAAI;AAAA,MACR,YAAY,WAAW,MAAM;AAAA,IAC/B;AAAA,EACF;AAEA,QAAM,YAAY,MAAM;AAAA,IACtB,oBAAoB,WAAW,MAAM;AAAA,IACrC,EAAE,MAAM,OAAO,OAAO,IAAI,MAAM,MAAM;AAAA,EACxC;AAEA,MAAI,CAAC,WAAW;AACd,YAAQ,IAAIA,OAAM,IAAI,0BAA0B,CAAC;AACjD;AAAA,EACF;AAEA,QAAM,UAAU,OAAO;AAEvB,aAAW,UAAU,SAAS;AAC5B,UAAM,eAAe,MAAM,YAAY,WAAW,MAAM;AACxD,UAAM,aAAa,cAAc,YAAY;AAE7C,eAAW,OAAO,YAAY;AAC5B,aAAO,WAAW,GAAG;AAAA,IACvB;AAEA,UAAM,UACJ,OAAO,aAAa,WAChB,gBAAgB,UAAU,IAC1B;AAEN,UAAM,YAAY,YAAY,QAAQ,SAAS;AAAA,MAC7C,QAAQ,UAAU;AAAA,IACpB,CAAC;AAED,YAAQ,IAAIA,OAAM,MAAM,kBAAa,MAAM,OAAO,CAAC;AAAA,EACrD;AAEA,MAAI,QAAQ;AACV,YAAQ;AAAA,MACNA,OAAM,OAAO,uCAAuC;AAAA,IACtD;AAAA,EACF,OAAO;AACL,YAAQ;AAAA,MACNA,OAAM;AAAA,QACJ;AAAA,iBAAe,WAAW,MAAM;AAAA;AAAA,MAClC;AAAA,IACF;AAAA,EACF;AACF;;;Ab3HA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,aAAa,EAClB,YAAY,sDAAsD,EAClE,QAAQ,OAAO;AAGlB,SAAS,kBAAkB,SAA2B;AACpD,SAAO,QACJ,OAAO,aAAa,2BAA2B,EAC/C,OAAO,aAAa,uCAAuC,EAC3D,OAAO,QAAQ,6CAA6C,EAC5D,OAAO,eAAe,0CAA0C;AACrE;AAGA;AAAA,EACE,QACG,QAAQ,MAAM,EACd,YAAY,uCAAuC,EACnD,OAAO,OAAO,YAAY;AACzB,UAAM,YAAY,OAAO;AAAA,EAC3B,CAAC;AACL;AAEA;AAAA,EACE,QACG,QAAQ,iBAAiB,EACzB,OAAO,mBAAmB,4BAA4B,EACtD,OAAO,YAAY,oBAAoB,EACvC,YAAY,yBAAyB,EACrC,OAAO,OAAO,MAAM,YAAY;AAC/B,UAAM,UAAU,MAAM,aAAa,OAAO;AAC1C,UAAM,QAAQ,MAAM,SAAS,OAAO;AAAA,EACtC,CAAC;AACL;AAEA;AAAA,EACE,QACG,QAAQ,aAAa,EACrB,SAAS,UAAU,yBAAyB,EAC5C,YAAY,oCAAoC,EAChD,OAAO,OAAO,MAAM,YAAY;AAC7B,UAAM,UAAU,MAAM,aAAa,OAAO;AAC1C,UAAM,kBAAkB,SAAS,IAAI;AAAA,EACzC,CAAC;AACL;AAKA;AAAA,EACE,QACG,QAAQ,SAAS,EACjB,SAAS,SAAS,0CAA0C,EAC5D,eAAe,uBAAuB,0BAA0B,EAChE,YAAY,wCAAwC,EACpD,OAAO,OAAO,KAAK,YAAY;AAC5B,UAAM,UAAU,MAAM,aAAa,OAAO;AAC1C,UAAM,cAAc,SAAS,KAAK,OAAO;AAAA,EAC7C,CAAC;AACL;AAEA;AAAA,EACE,QACG,QAAQ,YAAY,EACpB,SAAS,SAAS,iBAAiB,EACnC,eAAe,uBAAuB,WAAW,EACjD,OAAO,yBAAyB,2BAA2B,EAC3D,YAAY,wBAAwB,EACpC,OAAO,OAAO,KAAK,YAAY;AAC5B,UAAM,UAAU,MAAM,aAAa,OAAO;AAC1C,UAAM,iBAAiB,SAAS,KAAK,OAAO;AAAA,EAChD,CAAC;AACL;AAEA;AAAA,EACE,QACG,QAAQ,YAAY,EACpB,SAAS,SAAS,2BAA2B,EAC7C,YAAY,yCAAyC,EACrD,OAAO,OAAO,KAAK,YAAY;AAC5B,UAAM,UAAU,MAAM,aAAa,OAAO;AAC1C,UAAM,iBAAiB,SAAS,GAAG;AAAA,EACvC,CAAC;AACL;AAGA;AAAA,EACE,QACG,QAAQ,cAAc,EACtB,YAAY,iDAAiD,EAC7D,OAAO,OAAO,YAAY;AACvB,UAAM,UAAU,MAAM,aAAa,OAAO;AAC1C,UAAM,mBAAmB,OAAO;AAAA,EACpC,CAAC;AACL;AAGA,QAAQ,aAAa;AAErB,IAAI;AACF,QAAM,QAAQ,WAAW,QAAQ,IAAI;AACvC,SAAS,KAAU;AACjB,UAAQ,MAAME,OAAM,IAAI,eAAU,GAAG,IAAI,OAAO;AAChD,UAAQ,WAAW;AACrB;","names":["chalk","fs","path","fs","inquirer","path","path","fs","inquirer","answers","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","fs","chalk","chalk","fs","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../src/bin/cli.ts","../src/config/config-loader.ts","../src/core/file-manager.ts","../src/context/build-context.ts","../src/commands/init.ts","../src/core/confirmation.ts","../src/commands/add-lang.ts","../src/commands/remove-lang.ts","../src/commands/add-key.ts","../src/core/object-utils.ts","../src/core/key-validator.ts","../src/commands/update-key.ts","../src/commands/remove-key.ts","../src/commands/clean-unused.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport chalk from \"chalk\";\nimport { buildContext } from \"../context/build-context.js\";\nimport { initCommand } from \"../commands/init.js\";\nimport { addLang } from \"../commands/add-lang.js\";\nimport { removeLangCommand } from \"../commands/remove-lang.js\";\nimport { addKeyCommand } from \"../commands/add-key.js\";\nimport { updateKeyCommand } from \"../commands/update-key.js\";\nimport { removeKeyCommand } from \"../commands/remove-key.js\";\nimport { cleanUnusedCommand } from \"../commands/clean-unused.js\";\n\nconst program = new Command();\n\nprogram\n .name(\"i18n-ai-cli\")\n .description(\"Professional CLI tool for managing translation files\")\n .version(\"1.0.0\");\n\n// Global options helper\nfunction withGlobalOptions(command: Command): Command {\n return command\n .option(\"-y, --yes\", \"Skip confirmation prompts\")\n .option(\"--dry-run\", \"Preview changes without writing files\")\n .option(\"--ci\", \"Run in CI mode (no prompts, exit on issues)\")\n .option(\"-f, --force\", \"Force operation even if validation fails\");\n}\n\n// Language Commands\nwithGlobalOptions(\n program\n .command(\"init\")\n .description(\"Create an i18n-cli configuration file\")\n .action(async (options) => {\n await initCommand(options);\n })\n);\n\nwithGlobalOptions(\n program\n .command(\"add:lang <lang>\")\n .option(\"--from <locale>\", \"Clone from existing locale\")\n .option(\"--strict\", \"Enable strict mode\")\n .description(\"Add new language locale\")\n .action(async (lang, options) => {\n const context = await buildContext(options);\n await addLang(lang, options, context);\n })\n);\n\nwithGlobalOptions(\n program\n .command(\"remove:lang\")\n .argument(\"<lang>\", \"Language code to remove\")\n .description(\"Remove a language translation file\")\n .action(async (lang, options) => {\n const context = await buildContext(options);\n await removeLangCommand(context, lang);\n })\n);\n\n//\n// Key Commands\n//\nwithGlobalOptions(\n program\n .command(\"add:key\")\n .argument(\"<key>\", \"Translation key (e.g., auth.login.title)\")\n .requiredOption(\"-v, --value <value>\", \"Value for default locale\")\n .description(\"Add new translation key to all locales\")\n .action(async (key, options) => {\n const context = await buildContext(options);\n await addKeyCommand(context, key, options);\n })\n);\n\nwithGlobalOptions(\n program\n .command(\"update:key\")\n .argument(\"<key>\", \"Translation key\")\n .requiredOption(\"-v, --value <value>\", \"New value\")\n .option(\"-l, --locale <locale>\", \"Specific locale to update\")\n .description(\"Update translation key\")\n .action(async (key, options) => {\n const context = await buildContext(options);\n await updateKeyCommand(context, key, options);\n })\n);\n\nwithGlobalOptions(\n program\n .command(\"remove:key\")\n .argument(\"<key>\", \"Translation key to remove\")\n .description(\"Remove translation key from all locales\")\n .action(async (key, options) => {\n const context = await buildContext(options);\n await removeKeyCommand(context, key);\n })\n);\n\n// Clean Command\nwithGlobalOptions(\n program\n .command(\"clean:unused\")\n .description(\"Remove unused translation keys from all locales\")\n .action(async (options) => {\n const context = await buildContext(options);\n await cleanUnusedCommand(context);\n })\n);\n\n// Global Error Handling\nprogram.exitOverride();\n\ntry {\n await program.parseAsync(process.argv);\n} catch (err: any) {\n console.error(chalk.red(\"❌ Error:\"), err.message);\n process.exitCode = 1;\n}\n","import fs from \"fs-extra\";\nimport path from \"path\";\nimport { z } from \"zod\";\nimport type { I18nConfig } from \"./types.js\";\n\nexport const CONFIG_FILE_NAME = \"i18n-cli.config.json\";\n\nconst ConfigSchema = z.object({\n localesPath: z.string().min(1),\n defaultLocale: z.string().min(2),\n supportedLocales: z.array(z.string().min(2)),\n keyStyle: z.enum([\"flat\", \"nested\"]).default(\"nested\"),\n usagePatterns: z.array(z.string()).default([]),\n autoSort: z.boolean().default(true)\n});\n\ntype ParsedConfig = z.infer<typeof ConfigSchema>;\n\nfunction resolveConfigPath(): string {\n const cwd = process.cwd();\n return path.join(cwd, CONFIG_FILE_NAME);\n}\n\nexport async function loadConfig(): Promise<I18nConfig> {\n const configPath = resolveConfigPath();\n\n if (!(await fs.pathExists(configPath))) {\n throw new Error(\n `Configuration file \"${CONFIG_FILE_NAME}\" not found in project root.\\n` +\n `Run \"i18n-cli init\" to create one.`\n );\n }\n\n let rawConfig: unknown;\n\n try {\n rawConfig = await fs.readJson(configPath);\n } catch (err) {\n throw new Error(\n `Failed to parse ${CONFIG_FILE_NAME}. Ensure it contains valid JSON.`\n );\n }\n\n const parsed = ConfigSchema.safeParse(rawConfig);\n\n if (!parsed.success) {\n const errors = parsed.error.issues\n .map(e => `• ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\");\n\n throw new Error(\n `Invalid configuration in ${CONFIG_FILE_NAME}:\\n${errors}`\n );\n }\n\n const config = parsed.data;\n\n validateConfigLogic(config);\n const compiledUsagePatterns = compileUsagePatterns(\n config.usagePatterns\n );\n\n return {\n ...config,\n compiledUsagePatterns\n };\n}\n\nfunction validateConfigLogic(config: ParsedConfig): void {\n if (!config.supportedLocales.includes(config.defaultLocale)) {\n throw new Error(\n `defaultLocale \"${config.defaultLocale}\" must be included in supportedLocales.`\n );\n }\n\n const duplicates = findDuplicates(config.supportedLocales);\n if (duplicates.length > 0) {\n throw new Error(\n `Duplicate locales found in supportedLocales: ${duplicates.join(\", \")}`\n );\n }\n}\n\nexport function compileUsagePatterns(patterns: string[]): RegExp[] {\n if (patterns.length === 0) {\n return [];\n }\n\n return patterns.map((pattern, index) => {\n let regex: RegExp;\n\n try {\n regex = new RegExp(pattern, \"g\");\n } catch (err) {\n throw new Error(\n `Invalid regex in usagePatterns[${index}]: ${String(err)}`\n );\n }\n\n const groupCount = countCapturingGroups(pattern);\n if (groupCount === 0) {\n throw new Error(\n `usagePatterns[${index}] must include a capturing group (use a named group like \"(?<key>...)\" or a standard \"(...)\").`\n );\n }\n\n return regex;\n });\n}\n\nfunction countCapturingGroups(pattern: string): number {\n let count = 0;\n let inCharClass = false;\n\n for (let i = 0; i < pattern.length; i++) {\n const char = pattern[i];\n\n if (char === \"\\\\\") {\n i += 1;\n continue;\n }\n\n if (char === \"[\") {\n inCharClass = true;\n continue;\n }\n\n if (char === \"]\" && inCharClass) {\n inCharClass = false;\n continue;\n }\n\n if (inCharClass) {\n continue;\n }\n\n if (char !== \"(\") {\n continue;\n }\n\n const next = pattern[i + 1];\n if (next !== \"?\") {\n count += 1;\n continue;\n }\n\n const next2 = pattern[i + 2];\n if (next2 !== \"<\") {\n continue;\n }\n\n const next3 = pattern[i + 3];\n if (next3 === \"=\" || next3 === \"!\") {\n continue;\n }\n\n count += 1;\n }\n\n return count;\n}\n\nfunction findDuplicates(arr: string[]): string[] {\n const seen = new Set<string>();\n const duplicates: string[] = [];\n\n for (const item of arr) {\n if (seen.has(item)) {\n duplicates.push(item);\n }\n seen.add(item);\n }\n\n return duplicates;\n}\n","import fs from \"fs-extra\";\nimport path from \"path\";\nimport type { I18nConfig } from \"../config/types.js\";\n\nexport class FileManager {\n private localesPath: string;\n private config: I18nConfig;\n\n constructor(config: I18nConfig) {\n this.config = config;\n this.localesPath = path.resolve(process.cwd(), config.localesPath);\n }\n\n getLocaleFilePath(locale: string): string {\n return path.join(this.localesPath, `${locale}.json`);\n }\n\n async ensureLocalesDirectory(): Promise<void> {\n await fs.ensureDir(this.localesPath);\n }\n\n async localeExists(locale: string): Promise<boolean> {\n const filePath = this.getLocaleFilePath(locale);\n return fs.pathExists(filePath);\n }\n\n async listLocales(): Promise<string[]> {\n return this.config.supportedLocales;\n }\n\n async readLocale(locale: string): Promise<Record<string, any>> {\n const filePath = this.getLocaleFilePath(locale);\n\n if (!(await fs.pathExists(filePath))) {\n throw new Error(`Locale file \"${locale}.json\" does not exist.`);\n }\n\n try {\n return await fs.readJson(filePath);\n } catch {\n throw new Error(`Invalid JSON in \"${locale}.json\".`);\n }\n }\n\n async writeLocale(\n locale: string,\n data: Record<string, any>,\n options?: { dryRun?: boolean }\n ): Promise<void> {\n const filePath = this.getLocaleFilePath(locale);\n\n const finalData = this.config.autoSort\n ? this.sortKeysRecursively(data)\n : data;\n\n if (options?.dryRun) {\n return;\n }\n\n await fs.writeJson(filePath, finalData, { spaces: 2 });\n }\n\n async deleteLocale(\n locale: string,\n options?: { dryRun?: boolean }\n ): Promise<void> {\n const filePath = this.getLocaleFilePath(locale);\n\n if (!(await fs.pathExists(filePath))) {\n throw new Error(`Locale \"${locale}\" does not exist.`);\n }\n\n if (options?.dryRun) {\n return;\n }\n\n await fs.remove(filePath);\n }\n\n async createLocale(\n locale: string,\n initialData: Record<string, any>,\n options?: { dryRun?: boolean }\n ): Promise<void> {\n await this.ensureLocalesDirectory();\n\n const filePath = this.getLocaleFilePath(locale);\n\n if (await fs.pathExists(filePath)) {\n throw new Error(`Locale \"${locale}\" already exists.`);\n }\n\n if (options?.dryRun) {\n return;\n }\n\n await fs.writeJson(filePath, initialData, { spaces: 2 });\n }\n\n private sortKeysRecursively(obj: any): any {\n if (Array.isArray(obj)) {\n return obj.map(item => this.sortKeysRecursively(item));\n }\n\n if (obj !== null && typeof obj === \"object\") {\n return Object.keys(obj)\n .sort()\n .reduce((acc: any, key) => {\n acc[key] = this.sortKeysRecursively(obj[key]);\n return acc;\n }, Object.create(null));\n }\n\n return obj;\n }\n \n}\n","import { loadConfig } from \"../config/config-loader.js\";\nimport { FileManager } from \"../core/file-manager.js\";\nimport type { CommandContext, GlobalOptions } from \"./types.js\";\n\nexport async function buildContext(\n options: GlobalOptions\n): Promise<CommandContext> {\n const config = await loadConfig();\n const fileManager = new FileManager(config);\n\n return {\n config,\n fileManager,\n options\n };\n}","import chalk from \"chalk\";\nimport fs from \"fs-extra\";\nimport inquirer from \"inquirer\";\nimport path from \"path\";\nimport { CONFIG_FILE_NAME, compileUsagePatterns } from \"../config/config-loader.js\";\nimport type { KeyStyle } from \"../config/types.js\";\nimport type { GlobalOptions } from \"../context/types.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\ninterface InitConfigFile {\n localesPath: string;\n defaultLocale: string;\n supportedLocales: string[];\n keyStyle: KeyStyle;\n usagePatterns: string[];\n autoSort: boolean;\n}\n\nconst DEFAULT_USAGE_PATTERNS = [\n \"t\\\\(['\\\"](.*?)['\\\"]\\\\)\",\n \"translate\\\\(['\\\"](.*?)['\\\"]\\\\)\",\n \"i18n\\\\.t\\\\(['\\\"](.*?)['\\\"]\\\\)\"\n];\n\nexport async function initCommand(\n options: GlobalOptions\n): Promise<void> {\n const { yes, dryRun, ci, force } = options;\n const configPath = path.join(process.cwd(), CONFIG_FILE_NAME);\n const configExists = await fs.pathExists(configPath);\n\n if (configExists && !force) {\n throw new Error(\n `Configuration file \"${CONFIG_FILE_NAME}\" already exists. ` +\n `Use --force to overwrite.`\n );\n }\n\n const canPrompt = process.stdout.isTTY && !yes && !ci;\n\n let config: InitConfigFile;\n\n if (canPrompt) {\n const answers = await inquirer.prompt([\n {\n type: \"input\",\n name: \"localesPath\",\n message: \"Locales directory\",\n default: \"./locales\",\n validate: (input: string) =>\n input.trim().length > 0 || \"Please provide a locales path.\"\n },\n {\n type: \"input\",\n name: \"defaultLocale\",\n message: \"Default locale\",\n default: \"en\",\n validate: (input: string) =>\n input.trim().length >= 2 || \"Default locale must be at least 2 characters.\"\n },\n {\n type: \"input\",\n name: \"supportedLocales\",\n message: \"Supported locales (comma-separated)\",\n default: (answers: { defaultLocale: string }) =>\n answers.defaultLocale\n },\n {\n type: \"list\",\n name: \"keyStyle\",\n message: \"Key style\",\n choices: [\"nested\", \"flat\"],\n default: \"nested\"\n },\n {\n type: \"confirm\",\n name: \"autoSort\",\n message: \"Auto-sort keys?\",\n default: true\n },\n {\n type: \"confirm\",\n name: \"useDefaultUsagePatterns\",\n message: \"Use default usagePatterns?\",\n default: true\n }\n ]);\n\n let usagePatterns: string[] = DEFAULT_USAGE_PATTERNS;\n\n if (!answers.useDefaultUsagePatterns) {\n usagePatterns = [];\n let addMore = true;\n\n while (addMore) {\n const { pattern } = await inquirer.prompt([\n {\n type: \"input\",\n name: \"pattern\",\n message: \"Add usage pattern (regex)\",\n validate: (input: string) =>\n input.trim().length > 0 || \"Pattern cannot be empty.\"\n }\n ]);\n\n usagePatterns.push(pattern.trim());\n\n const { again } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"again\",\n message: \"Add another pattern?\",\n default: false\n }\n ]);\n\n addMore = again;\n }\n }\n\n const supportedLocales = parseLocales(\n answers.supportedLocales\n );\n\n config = {\n localesPath: answers.localesPath.trim(),\n defaultLocale: answers.defaultLocale.trim(),\n supportedLocales,\n keyStyle: answers.keyStyle,\n usagePatterns,\n autoSort: answers.autoSort\n };\n } else {\n config = {\n localesPath: \"./locales\",\n defaultLocale: \"en\",\n supportedLocales: [\"en\"],\n keyStyle: \"nested\",\n usagePatterns: DEFAULT_USAGE_PATTERNS,\n autoSort: true\n };\n }\n\n config.supportedLocales = normalizeLocales(\n config.supportedLocales,\n config.defaultLocale\n );\n\n compileUsagePatterns(config.usagePatterns);\n\n if (ci && !yes) {\n const action = configExists ? \"overwritten\" : \"created\";\n throw new Error(\n `CI mode: configuration file would be ${action}. Re-run with --yes to apply.`\n );\n }\n\n if (configExists && !yes) {\n const confirmed = await confirmAction(\n `This will overwrite \"${CONFIG_FILE_NAME}\". Continue?`,\n { skip: false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n }\n\n if (dryRun) {\n console.log(chalk.yellow(\"\\n[DRY RUN] Configuration not written.\"));\n return;\n }\n\n await fs.writeJson(configPath, config, { spaces: 2 });\n\n await maybeInitLocales(config, { dryRun: false });\n\n console.log(\n chalk.green(`\\n✔ Created ${CONFIG_FILE_NAME} successfully.`)\n );\n}\n\nfunction parseLocales(input: string): string[] {\n return input\n .split(\",\")\n .map(locale => locale.trim())\n .filter(Boolean);\n}\n\nfunction normalizeLocales(\n locales: string[],\n defaultLocale: string\n): string[] {\n const unique = new Set<string>();\n\n for (const locale of locales) {\n if (locale.length > 0) {\n unique.add(locale);\n }\n }\n\n if (!unique.has(defaultLocale)) {\n unique.add(defaultLocale);\n }\n\n return Array.from(unique);\n}\n\nasync function maybeInitLocales(\n config: InitConfigFile,\n options: { dryRun: boolean }\n): Promise<void> {\n const localesPath = path.resolve(\n process.cwd(),\n config.localesPath\n );\n\n if (options.dryRun) {\n return;\n }\n\n await fs.ensureDir(localesPath);\n\n // Strip .json extension if present to avoid double extension\n const defaultLocale = config.defaultLocale.replace(/\\.json$/i, '');\n\n const defaultLocaleFile = path.join(\n localesPath,\n `${defaultLocale}.json`\n );\n\n if (await fs.pathExists(defaultLocaleFile)) {\n return;\n }\n\n await fs.writeJson(defaultLocaleFile, {}, { spaces: 2 });\n}\n","import inquirer from \"inquirer\";\n\ninterface ConfirmOptions {\n skip?: boolean; // used when --yes flag is passed\n defaultValue?: boolean;\n ci?: boolean;\n}\n\nexport async function confirmAction(\n message: string,\n options: ConfirmOptions = {}\n): Promise<boolean> {\n const { skip = false, defaultValue = false, ci = false } = options;\n\n // If --yes is passed, skip prompt\n if (skip) {\n return true;\n }\n\n // If running in CI mode, require explicit confirmation via --yes\n if (ci) {\n throw new Error(\n \"Confirmation required in CI mode. Re-run with --yes to proceed.\"\n );\n }\n\n // If running in non-interactive environment\n if (!process.stdout.isTTY) {\n return defaultValue;\n }\n\n const { confirmed } = await inquirer.prompt([\n {\n type: \"confirm\",\n name: \"confirmed\",\n message,\n default: defaultValue\n }\n ]);\n\n return confirmed;\n}\n","import chalk from \"chalk\";\nimport ISO6391 from \"iso-639-1\";\nimport type { CommandContext } from \"../context/types.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\ninterface AddLangOptions {\n from?: string;\n strict?: boolean;\n}\n\nfunction isValidLocale(code: string): boolean {\n // Accept en or en-US format\n const parts = code.split(\"-\");\n\n if (parts.length === 1) {\n return ISO6391.validate(parts[0]!);\n }\n\n if (parts.length === 2) {\n return ISO6391.validate(parts[0]!);\n }\n\n return false;\n}\n\nexport async function addLang(\n lang: string,\n options: AddLangOptions,\n context: CommandContext\n): Promise<void> {\n const { config, fileManager } = context;\n const { yes, dryRun, ci } = context.options;\n\n const locale = lang.trim();\n\n if (!isValidLocale(locale)) {\n throw new Error(`Invalid language code: ${locale}`);\n }\n\n if (config.supportedLocales.includes(locale)) {\n throw new Error(`Language ${locale} already exists`);\n }\n\n const exists = await fileManager.localeExists(locale);\n if (exists) {\n throw new Error(`File already exists: ${locale}.json`);\n }\n\n let baseContent: Record<string, unknown> = {};\n\n // If clone from existing locale\n if (options.from) {\n const baseLocale = options.from;\n\n if (!config.supportedLocales.includes(baseLocale)) {\n throw new Error(`Base locale ${baseLocale} does not exist`);\n }\n\n baseContent = await fileManager.readLocale(baseLocale);\n }\n\n console.log(chalk.cyan(`\\nPreparing to add locale:`));\n console.log(chalk.yellow(` ${locale}\\n`));\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: locale \"${locale}\" would be created. Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n `This will create new locale \"${locale}\". Continue?`,\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n await fileManager.createLocale(locale, baseContent, { dryRun: dryRun ?? false });\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n console.log(\n chalk.green(`\\n✔ Locale \"${locale}\" created successfully.`)\n );\n console.log(\n chalk.gray(\n `Note: Add \"${locale}\" to supportedLocales in config manually.`\n )\n );\n }\n}\n","import chalk from \"chalk\";\nimport type { CommandContext } from \"../context/types.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\nexport async function removeLangCommand(\n context: CommandContext,\n lang: string\n): Promise<void> {\n const { config, fileManager, options } = context;\n const { yes, dryRun, ci } = options;\n\n const locale = lang.trim();\n\n // Validate locale exists\n if (!config.supportedLocales.includes(locale)) {\n throw new Error(\n `Locale \"${locale}\" is not in supportedLocales.`\n );\n }\n\n // Prevent removing default locale\n if (locale === config.defaultLocale) {\n throw new Error(\n `Cannot remove default locale \"${locale}\". ` +\n `Change defaultLocale first.`\n );\n }\n\n // Check if file exists\n const exists = await fileManager.localeExists(locale);\n if (!exists) {\n throw new Error(\n `Locale file \"${locale}.json\" does not exist.`\n );\n }\n\n console.log(chalk.cyan(`\\nPreparing to remove locale:`));\n console.log(chalk.yellow(` ${locale}\\n`));\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: locale \"${locale}\" would be removed. Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n `This will permanently delete \"${locale}.json\". Continue?`,\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n // Delete the locale file\n await fileManager.deleteLocale(locale, { dryRun: dryRun ?? false });\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n console.log(\n chalk.green(`\\n✔ Locale \"${locale}\" removed successfully.`)\n );\n console.log(\n chalk.gray(\n `Note: Remove \"${locale}\" from supportedLocales in config manually.`\n )\n );\n }\n}\n","import chalk from \"chalk\";\nimport type { CommandContext } from \"../context/types.js\";\nimport { flattenObject, unflattenObject } from \"../core/object-utils.js\";\nimport { validateNoStructuralConflict } from \"../core/key-validator.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\nexport async function addKeyCommand(\n context: CommandContext,\n key: string,\n options: { value: string }\n): Promise<void> {\n const { config, fileManager } = context;\n const { yes, dryRun, ci } = context.options;\n\n const value = options.value;\n\n if (!key || !value) {\n throw new Error(\"Both key and --value are required.\");\n }\n\n const locales = config.supportedLocales;\n\n console.log(chalk.cyan(`\\nPreparing to add key:`));\n console.log(chalk.yellow(` ${key}\\n`));\n\n const updatedLocales: string[] = [];\n\n for (const locale of locales) {\n const nested = await fileManager.readLocale(locale);\n const flat = flattenObject(nested);\n\n // Strict mode validation\n validateNoStructuralConflict(flat, key);\n\n if (flat[key] !== undefined) {\n throw new Error(\n `Key \"${key}\" already exists in locale \"${locale}\". Use update:key instead.`\n );\n }\n\n updatedLocales.push(locale);\n }\n\n console.log(chalk.white(\"This operation will update:\"));\n updatedLocales.forEach(l =>\n console.log(chalk.gray(` • ${l}.json`))\n );\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: key \"${key}\" would be added to ${updatedLocales.length} locale(s). Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n \"\\nDo you want to continue?\",\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n for (const locale of locales) {\n const nested = await fileManager.readLocale(locale);\n const flat = flattenObject(nested);\n\n flat[key] = locale === config.defaultLocale ? value : \"\";\n\n const finalData =\n config.keyStyle === \"nested\"\n ? unflattenObject(flat)\n : flat;\n\n await fileManager.writeLocale(locale, finalData, { dryRun: dryRun ?? false });\n }\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n updatedLocales.forEach(l =>\n console.log(chalk.green(`✔ Updated ${l}.json`))\n );\n\n console.log(\n chalk.green(\"\\n✨ Key added successfully across all locales.\")\n );\n }\n}\n","export type FlatObject = Record<string, any>;\n\nconst DANGEROUS_KEY_SEGMENTS = new Set([\n \"__proto__\",\n \"constructor\",\n \"prototype\"\n]);\n\nfunction assertSafeKeySegment(segment: string): void {\n if (DANGEROUS_KEY_SEGMENTS.has(segment)) {\n throw new Error(\n `Unsafe key segment \"${segment}\" is not allowed.`\n );\n }\n}\n\nexport function flattenObject(\n obj: Record<string, any>,\n parentKey = \"\",\n result: FlatObject = Object.create(null)\n): FlatObject {\n for (const key of Object.keys(obj)) {\n assertSafeKeySegment(key);\n const value = obj[key];\n const newKey = parentKey ? `${parentKey}.${key}` : key;\n\n if (\n value &&\n typeof value === \"object\" &&\n !Array.isArray(value)\n ) {\n flattenObject(value, newKey, result);\n } else {\n result[newKey] = value;\n }\n }\n\n return result;\n}\n\nexport function unflattenObject(flatObj: FlatObject): Record<string, any> {\n const result: Record<string, any> = Object.create(null);\n\n for (const flatKey of Object.keys(flatObj)) {\n const keys = flatKey.split(\".\");\n let current = result;\n\n keys.forEach((key, index) => {\n assertSafeKeySegment(key);\n const isLast = index === keys.length - 1;\n\n if (isLast) {\n current[key] = flatObj[flatKey];\n } else {\n if (!current[key] || typeof current[key] !== \"object\") {\n current[key] = Object.create(null);\n }\n current = current[key];\n }\n });\n }\n\n return result;\n}\n\nexport function getAllFlatKeys(obj: Record<string, any>): string[] {\n return Object.keys(flattenObject(obj));\n}\n\nexport function removeEmptyObjects(obj: any): any {\n if (Array.isArray(obj)) {\n return obj;\n }\n\n if (obj !== null && typeof obj === \"object\") {\n const cleaned: any = Object.create(null);\n\n for (const key of Object.keys(obj)) {\n assertSafeKeySegment(key);\n const value = removeEmptyObjects(obj[key]);\n\n if (\n value !== undefined &&\n (typeof value !== \"object\" || Object.keys(value).length > 0)\n ) {\n cleaned[key] = value;\n }\n }\n\n return cleaned;\n }\n\n return obj;\n}\n","export function validateNoStructuralConflict(\n flatObject: Record<string, any>,\n newKey: string\n): void {\n const parts = newKey.split(\".\");\n\n // Parent conflict check\n for (let i = 1; i < parts.length; i++) {\n const parentPath = parts.slice(0, i).join(\".\");\n\n if (flatObject[parentPath] !== undefined) {\n throw new Error(\n `Structural conflict detected:\\n\\n` +\n `Cannot create key \"${newKey}\" because \"${parentPath}\" ` +\n `is already defined as a non-object value.\\n\\n` +\n `Resolve conflict before proceeding.`\n );\n }\n }\n\n // Child conflict check\n const prefix = `${newKey}.`;\n\n for (const existingKey of Object.keys(flatObject)) {\n if (existingKey.startsWith(prefix)) {\n throw new Error(\n `Structural conflict detected:\\n\\n` +\n `Cannot create key \"${newKey}\" because it would overwrite nested keys like \"${existingKey}\".\\n\\n` +\n `Resolve conflict before proceeding.`\n );\n }\n }\n}","import chalk from \"chalk\";\nimport type { CommandContext } from \"../context/types.js\";\nimport {\n flattenObject,\n unflattenObject\n} from \"../core/object-utils.js\";\nimport { validateNoStructuralConflict } from \"../core/key-validator.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\ninterface UpdateKeyOptions {\n value: string;\n locale?: string;\n}\n\nexport async function updateKeyCommand(\n context: CommandContext,\n key: string,\n options: UpdateKeyOptions\n): Promise<void> {\n const { config, fileManager, options: globalOptions } = context;\n const { yes, dryRun, ci } = globalOptions;\n\n const { value, locale } = options;\n\n if (!key || value === undefined) {\n throw new Error(\"Both key and --value are required.\");\n }\n\n const targetLocale = locale ?? config.defaultLocale;\n\n if (!config.supportedLocales.includes(targetLocale)) {\n throw new Error(\n `Locale \"${targetLocale}\" is not defined in configuration.`\n );\n }\n\n console.log(chalk.cyan(`\\nPreparing to update key:`));\n console.log(chalk.yellow(` ${key}`));\n console.log(chalk.gray(` Locale: ${targetLocale}\\n`));\n\n const nested = await fileManager.readLocale(targetLocale);\n const flat = flattenObject(nested);\n\n // Strict structural validation\n validateNoStructuralConflict(flat, key);\n\n if (flat[key] === undefined) {\n throw new Error(\n `Key \"${key}\" does not exist in locale \"${targetLocale}\".`\n );\n }\n\n console.log(\n chalk.white(\n `Old value: ${chalk.gray(JSON.stringify(flat[key]))}`\n )\n );\n console.log(\n chalk.white(\n `New value: ${chalk.green(JSON.stringify(value))}`\n )\n );\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: key \"${key}\" in \"${targetLocale}\" would be updated. Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n \"\\nDo you want to continue?\",\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n flat[key] = value;\n\n const rebuilt =\n config.keyStyle === \"nested\"\n ? unflattenObject(flat)\n : flat;\n\n await fileManager.writeLocale(targetLocale, rebuilt, {\n dryRun: dryRun ?? false\n });\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n console.log(\n chalk.green(\n `\\n✔ Successfully updated \"${key}\" in ${targetLocale}.json`\n )\n );\n }\n}\n","import chalk from \"chalk\";\nimport type { CommandContext } from \"../context/types.js\";\nimport {\n flattenObject,\n unflattenObject,\n removeEmptyObjects\n} from \"../core/object-utils.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\n\nexport async function removeKeyCommand(\n context: CommandContext,\n key: string\n): Promise<void> {\n const { config, fileManager, options } = context;\n const { yes, dryRun, ci } = options;\n\n if (!key) {\n throw new Error(\"Key is required.\");\n }\n\n const locales = config.supportedLocales;\n\n console.log(chalk.cyan(`\\nPreparing to remove key:`));\n console.log(chalk.yellow(` ${key}\\n`));\n\n const localesContainingKey: string[] = [];\n\n // First pass: check existence\n for (const locale of locales) {\n const nested = await fileManager.readLocale(locale);\n const flat = flattenObject(nested);\n\n if (flat[key] !== undefined) {\n localesContainingKey.push(locale);\n }\n }\n\n if (localesContainingKey.length === 0) {\n throw new Error(\n `Key \"${key}\" does not exist in any locale.`\n );\n }\n\n console.log(chalk.white(\"This operation will update:\"));\n localesContainingKey.forEach(l =>\n console.log(chalk.gray(` • ${l}.json`))\n );\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: key \"${key}\" would be removed from ${localesContainingKey.length} locale(s). Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n \"\\nThis will remove the key from ALL locales. Continue?\",\n yes !== undefined ? { skip: yes, ci: ci ?? false } : { ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\"));\n return;\n }\n\n // Second pass: remove\n for (const locale of locales) {\n const nested = await fileManager.readLocale(locale);\n const flat = flattenObject(nested);\n\n if (flat[key] !== undefined) {\n delete flat[key];\n }\n\n const rebuilt =\n config.keyStyle === \"nested\"\n ? removeEmptyObjects(unflattenObject(flat))\n : flat;\n\n await fileManager.writeLocale(locale, rebuilt, dryRun !== undefined ? { dryRun } : undefined);\n }\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\")\n );\n } else {\n localesContainingKey.forEach(l =>\n console.log(chalk.green(`✔ Updated ${l}.json`))\n );\n\n console.log(\n chalk.green(\"\\n✨ Key removed successfully from all locales.\")\n );\n }\n}\n","import fs from \"fs-extra\";\nimport { glob } from \"glob\";\nimport chalk from \"chalk\";\nimport { flattenObject, unflattenObject } from \"../core/object-utils.js\";\nimport { confirmAction } from \"../core/confirmation.js\";\nimport type { CommandContext } from \"../context/types.js\";\n\nexport async function cleanUnusedCommand(\n context: CommandContext\n) {\n const { config, fileManager, options } = context;\n\n const { dryRun, yes, ci } = options;\n\n console.log(chalk.cyan(\"\\nScanning project for translation usage...\\n\"));\n\n const patterns = config.compiledUsagePatterns;\n\n if (!patterns || patterns.length === 0) {\n throw new Error(\n \"No usagePatterns defined in config.\"\n );\n }\n\n // Scan project files\n const files = await glob(\"src/**/*.{ts,tsx,js,jsx,html}\");\n\n const usedKeys = new Set<string>();\n\n for (const file of files) {\n const content = await fs.readFile(file, \"utf8\");\n\n for (const regex of patterns) {\n regex.lastIndex = 0;\n\n let match;\n\n while ((match = regex.exec(content))) {\n const key = match.groups?.key ?? match[1];\n\n if (key) {\n usedKeys.add(key);\n }\n }\n }\n }\n\n console.log(\n chalk.gray(`Found ${usedKeys.size} used keys in project\\n`)\n );\n\n // Read default locale\n const defaultLocale = config.defaultLocale;\n const nested = await fileManager.readLocale(defaultLocale);\n const flat = flattenObject(nested);\n\n const localeKeys = Object.keys(flat);\n\n const unusedKeys = localeKeys.filter(\n key => !usedKeys.has(key)\n );\n\n if (unusedKeys.length === 0) {\n console.log(\n chalk.green(\"✔ No unused translation keys found.\\n\")\n );\n return;\n }\n\n console.log(\n chalk.yellow(`Unused keys (${unusedKeys.length}):`)\n );\n\n unusedKeys.slice(0, 20).forEach(key =>\n console.log(` - ${key}`)\n );\n\n if (unusedKeys.length > 20) {\n console.log(\n chalk.gray(\n `... and ${unusedKeys.length - 20} more`\n )\n );\n }\n\n console.log(\"\");\n\n if (ci && !yes) {\n throw new Error(\n `CI mode: ${unusedKeys.length} unused key(s) would be removed. Re-run with --yes to apply.`\n );\n }\n\n const confirmed = await confirmAction(\n `This will remove ${unusedKeys.length} keys from ALL locales. Continue?`,\n { skip: yes ?? false, ci: ci ?? false }\n );\n\n if (!confirmed) {\n console.log(chalk.red(\"\\nOperation cancelled.\\n\"));\n return;\n }\n\n const locales = config.supportedLocales;\n\n for (const locale of locales) {\n const nestedLocale = await fileManager.readLocale(locale);\n const flatLocale = flattenObject(nestedLocale);\n\n for (const key of unusedKeys) {\n delete flatLocale[key];\n }\n\n const rebuilt =\n config.keyStyle === \"nested\"\n ? unflattenObject(flatLocale)\n : flatLocale;\n\n await fileManager.writeLocale(locale, rebuilt, {\n dryRun: dryRun ?? false\n });\n\n console.log(chalk.green(`✔ Updated ${locale}.json`));\n }\n\n if (dryRun) {\n console.log(\n chalk.yellow(\"\\n[DRY RUN] No files were modified.\\n\")\n );\n } else {\n console.log(\n chalk.green(\n `\\n✨ Removed ${unusedKeys.length} unused keys from all locales.\\n`\n )\n );\n }\n}\n"],"mappings":"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","names":["chalk","fs","path","fs","inquirer","path","path","fs","inquirer","answers","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","chalk","fs","chalk","chalk","fs","chalk"]}
|