i18nsmith 0.1.0
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/dist/commands/audit.d.ts +3 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +180 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/backup.d.ts +6 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +85 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/check.d.ts +3 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +151 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/config.d.ts +3 -0
- package/dist/commands/config.d.ts.map +1 -0
- package/dist/commands/config.js +235 -0
- package/dist/commands/config.js.map +1 -0
- package/dist/commands/debug-patterns.d.ts +3 -0
- package/dist/commands/debug-patterns.d.ts.map +1 -0
- package/dist/commands/debug-patterns.js +192 -0
- package/dist/commands/debug-patterns.js.map +1 -0
- package/dist/commands/debug-patterns.test.d.ts +2 -0
- package/dist/commands/debug-patterns.test.d.ts.map +1 -0
- package/dist/commands/debug-patterns.test.js +109 -0
- package/dist/commands/debug-patterns.test.js.map +1 -0
- package/dist/commands/diagnose.d.ts +3 -0
- package/dist/commands/diagnose.d.ts.map +1 -0
- package/dist/commands/diagnose.js +117 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/init.d.ts +8 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +450 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.test.d.ts +2 -0
- package/dist/commands/init.test.d.ts.map +1 -0
- package/dist/commands/init.test.js +74 -0
- package/dist/commands/init.test.js.map +1 -0
- package/dist/commands/install-hooks.d.ts +3 -0
- package/dist/commands/install-hooks.d.ts.map +1 -0
- package/dist/commands/install-hooks.js +52 -0
- package/dist/commands/install-hooks.js.map +1 -0
- package/dist/commands/preflight.d.ts +7 -0
- package/dist/commands/preflight.d.ts.map +1 -0
- package/dist/commands/preflight.js +417 -0
- package/dist/commands/preflight.js.map +1 -0
- package/dist/commands/preflight.test.d.ts +5 -0
- package/dist/commands/preflight.test.d.ts.map +1 -0
- package/dist/commands/preflight.test.js +108 -0
- package/dist/commands/preflight.test.js.map +1 -0
- package/dist/commands/rename.d.ts +6 -0
- package/dist/commands/rename.d.ts.map +1 -0
- package/dist/commands/rename.js +204 -0
- package/dist/commands/rename.js.map +1 -0
- package/dist/commands/scaffold-adapter.d.ts +3 -0
- package/dist/commands/scaffold-adapter.d.ts.map +1 -0
- package/dist/commands/scaffold-adapter.js +204 -0
- package/dist/commands/scaffold-adapter.js.map +1 -0
- package/dist/commands/scaffold-adapter.test.d.ts +2 -0
- package/dist/commands/scaffold-adapter.test.d.ts.map +1 -0
- package/dist/commands/scaffold-adapter.test.js +102 -0
- package/dist/commands/scaffold-adapter.test.js.map +1 -0
- package/dist/commands/scan.d.ts +3 -0
- package/dist/commands/scan.d.ts.map +1 -0
- package/dist/commands/scan.js +93 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/commands/sync-seed.test.d.ts +2 -0
- package/dist/commands/sync-seed.test.d.ts.map +1 -0
- package/dist/commands/sync-seed.test.js +86 -0
- package/dist/commands/sync-seed.test.js.map +1 -0
- package/dist/commands/sync.d.ts +3 -0
- package/dist/commands/sync.d.ts.map +1 -0
- package/dist/commands/sync.js +590 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/transform.d.ts +3 -0
- package/dist/commands/transform.d.ts.map +1 -0
- package/dist/commands/transform.js +114 -0
- package/dist/commands/transform.js.map +1 -0
- package/dist/commands/translate/csv-handler.d.ts +21 -0
- package/dist/commands/translate/csv-handler.d.ts.map +1 -0
- package/dist/commands/translate/csv-handler.js +270 -0
- package/dist/commands/translate/csv-handler.js.map +1 -0
- package/dist/commands/translate/executor.d.ts +31 -0
- package/dist/commands/translate/executor.d.ts.map +1 -0
- package/dist/commands/translate/executor.js +117 -0
- package/dist/commands/translate/executor.js.map +1 -0
- package/dist/commands/translate/index.d.ts +10 -0
- package/dist/commands/translate/index.d.ts.map +1 -0
- package/dist/commands/translate/index.js +170 -0
- package/dist/commands/translate/index.js.map +1 -0
- package/dist/commands/translate/reporter.d.ts +29 -0
- package/dist/commands/translate/reporter.d.ts.map +1 -0
- package/dist/commands/translate/reporter.js +103 -0
- package/dist/commands/translate/reporter.js.map +1 -0
- package/dist/commands/translate/types.d.ts +50 -0
- package/dist/commands/translate/types.d.ts.map +1 -0
- package/dist/commands/translate/types.js +5 -0
- package/dist/commands/translate/types.js.map +1 -0
- package/dist/commands/translate.d.ts +7 -0
- package/dist/commands/translate.d.ts.map +1 -0
- package/dist/commands/translate.js +7 -0
- package/dist/commands/translate.js.map +1 -0
- package/dist/commands/translate.test.d.ts +2 -0
- package/dist/commands/translate.test.d.ts.map +1 -0
- package/dist/commands/translate.test.js +118 -0
- package/dist/commands/translate.test.js.map +1 -0
- package/dist/e2e.test.d.ts +6 -0
- package/dist/e2e.test.d.ts.map +1 -0
- package/dist/e2e.test.js +376 -0
- package/dist/e2e.test.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/integration.test.d.ts +6 -0
- package/dist/integration.test.d.ts.map +1 -0
- package/dist/integration.test.js +320 -0
- package/dist/integration.test.js.map +1 -0
- package/dist/utils/diagnostics-exit.d.ts +12 -0
- package/dist/utils/diagnostics-exit.d.ts.map +1 -0
- package/dist/utils/diagnostics-exit.js +49 -0
- package/dist/utils/diagnostics-exit.js.map +1 -0
- package/dist/utils/diagnostics-exit.test.d.ts +2 -0
- package/dist/utils/diagnostics-exit.test.d.ts.map +1 -0
- package/dist/utils/diagnostics-exit.test.js +40 -0
- package/dist/utils/diagnostics-exit.test.js.map +1 -0
- package/dist/utils/diff-utils.d.ts +4 -0
- package/dist/utils/diff-utils.d.ts.map +1 -0
- package/dist/utils/diff-utils.js +30 -0
- package/dist/utils/diff-utils.js.map +1 -0
- package/dist/utils/diff-utils.test.d.ts +2 -0
- package/dist/utils/diff-utils.test.d.ts.map +1 -0
- package/dist/utils/diff-utils.test.js +30 -0
- package/dist/utils/diff-utils.test.js.map +1 -0
- package/dist/utils/exit-codes.d.ts +142 -0
- package/dist/utils/exit-codes.d.ts.map +1 -0
- package/dist/utils/exit-codes.js +168 -0
- package/dist/utils/exit-codes.js.map +1 -0
- package/dist/utils/package-manager.d.ts +4 -0
- package/dist/utils/package-manager.d.ts.map +1 -0
- package/dist/utils/package-manager.js +40 -0
- package/dist/utils/package-manager.js.map +1 -0
- package/dist/utils/pkg.d.ts +3 -0
- package/dist/utils/pkg.d.ts.map +1 -0
- package/dist/utils/pkg.js +24 -0
- package/dist/utils/pkg.js.map +1 -0
- package/dist/utils/provider-injector.d.ts +36 -0
- package/dist/utils/provider-injector.d.ts.map +1 -0
- package/dist/utils/provider-injector.js +223 -0
- package/dist/utils/provider-injector.js.map +1 -0
- package/dist/utils/provider-injector.test.d.ts +2 -0
- package/dist/utils/provider-injector.test.d.ts.map +1 -0
- package/dist/utils/provider-injector.test.js +67 -0
- package/dist/utils/provider-injector.test.js.map +1 -0
- package/dist/utils/scaffold.d.ts +20 -0
- package/dist/utils/scaffold.d.ts.map +1 -0
- package/dist/utils/scaffold.js +197 -0
- package/dist/utils/scaffold.js.map +1 -0
- package/package.json +35 -0
- package/src/commands/audit.ts +234 -0
- package/src/commands/backup.ts +96 -0
- package/src/commands/check.ts +191 -0
- package/src/commands/config.ts +263 -0
- package/src/commands/debug-patterns.test.ts +134 -0
- package/src/commands/debug-patterns.ts +257 -0
- package/src/commands/diagnose.ts +136 -0
- package/src/commands/init.test.ts +82 -0
- package/src/commands/init.ts +536 -0
- package/src/commands/install-hooks.ts +66 -0
- package/src/commands/preflight.test.ts +139 -0
- package/src/commands/preflight.ts +488 -0
- package/src/commands/rename.ts +264 -0
- package/src/commands/scaffold-adapter.test.ts +110 -0
- package/src/commands/scaffold-adapter.ts +250 -0
- package/src/commands/scan.ts +125 -0
- package/src/commands/sync-seed.test.ts +116 -0
- package/src/commands/sync.ts +736 -0
- package/src/commands/transform.ts +151 -0
- package/src/commands/translate/README.md +75 -0
- package/src/commands/translate/csv-handler.ts +301 -0
- package/src/commands/translate/executor.ts +188 -0
- package/src/commands/translate/index.ts +220 -0
- package/src/commands/translate/reporter.ts +138 -0
- package/src/commands/translate/types.ts +56 -0
- package/src/commands/translate.test.ts +173 -0
- package/src/commands/translate.ts +6 -0
- package/src/e2e.test.ts +479 -0
- package/src/fixtures/README.md +61 -0
- package/src/fixtures/basic-react/i18n.config.json +15 -0
- package/src/fixtures/basic-react/locales/de.json +8 -0
- package/src/fixtures/basic-react/locales/en.json +8 -0
- package/src/fixtures/basic-react/locales/fr.json +8 -0
- package/src/fixtures/basic-react/src/App.tsx +15 -0
- package/src/fixtures/basic-react/src/Messages.tsx +12 -0
- package/src/fixtures/nested-locales/i18n.config.json +9 -0
- package/src/fixtures/nested-locales/locales/en.json +23 -0
- package/src/fixtures/nested-locales/locales/fr.json +23 -0
- package/src/fixtures/nested-locales/src/HomePage.tsx +13 -0
- package/src/fixtures/suspicious-keys/i18n.config.json +9 -0
- package/src/fixtures/suspicious-keys/locales/en.json +11 -0
- package/src/fixtures/suspicious-keys/locales/fr.json +11 -0
- package/src/fixtures/suspicious-keys/src/BadKeys.tsx +19 -0
- package/src/index.ts +43 -0
- package/src/integration.test.ts +438 -0
- package/src/utils/diagnostics-exit.test.ts +47 -0
- package/src/utils/diagnostics-exit.ts +63 -0
- package/src/utils/diff-utils.test.ts +36 -0
- package/src/utils/diff-utils.ts +42 -0
- package/src/utils/exit-codes.ts +201 -0
- package/src/utils/package-manager.ts +44 -0
- package/src/utils/pkg.ts +23 -0
- package/src/utils/provider-injector.test.ts +79 -0
- package/src/utils/provider-injector.ts +315 -0
- package/src/utils/scaffold.ts +240 -0
- package/tsconfig.json +17 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translate command - fill missing locale entries via translation adapters
|
|
3
|
+
*/
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
import { DEFAULT_PLACEHOLDER_FORMATS, PlaceholderValidator, loadConfig, TranslationService, } from '@i18nsmith/core';
|
|
7
|
+
import { TranslatorLoadError } from '@i18nsmith/translation';
|
|
8
|
+
import { emitTranslateOutput, maybePrintEstimate } from './reporter.js';
|
|
9
|
+
import { handleCsvExport, handleCsvImport } from './csv-handler.js';
|
|
10
|
+
import { executeTranslations } from './executor.js';
|
|
11
|
+
// Re-export types for external use
|
|
12
|
+
export * from './types.js';
|
|
13
|
+
/**
|
|
14
|
+
* Parse comma-separated locale values
|
|
15
|
+
*/
|
|
16
|
+
function collectLocales(value, previous) {
|
|
17
|
+
const tokens = (Array.isArray(value) ? value : value.split(','))
|
|
18
|
+
.map((entry) => entry.trim())
|
|
19
|
+
.filter(Boolean);
|
|
20
|
+
return [...previous, ...tokens];
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Resolve provider settings from config and options
|
|
24
|
+
*/
|
|
25
|
+
function resolveProviderSettings(translationConfig, override) {
|
|
26
|
+
const providerName = (override ?? translationConfig?.provider ?? 'manual').trim();
|
|
27
|
+
const moduleSpecifier = translationConfig?.module;
|
|
28
|
+
let secret;
|
|
29
|
+
if (translationConfig?.secretEnvVar) {
|
|
30
|
+
secret = process.env[translationConfig.secretEnvVar];
|
|
31
|
+
}
|
|
32
|
+
const loaderOptions = {
|
|
33
|
+
provider: providerName,
|
|
34
|
+
module: moduleSpecifier,
|
|
35
|
+
apiKey: translationConfig?.apiKey,
|
|
36
|
+
secret,
|
|
37
|
+
concurrency: translationConfig?.concurrency,
|
|
38
|
+
batchSize: translationConfig?.batchSize,
|
|
39
|
+
config: translationConfig ? { ...translationConfig } : undefined,
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
name: providerName,
|
|
43
|
+
loaderOptions,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Prompt for translation confirmation
|
|
48
|
+
*/
|
|
49
|
+
async function confirmTranslate(plan, providerName) {
|
|
50
|
+
const { proceed } = await inquirer.prompt([
|
|
51
|
+
{
|
|
52
|
+
type: 'confirm',
|
|
53
|
+
name: 'proceed',
|
|
54
|
+
default: false,
|
|
55
|
+
message: `Translate ${plan.totalTasks} key${plan.totalTasks === 1 ? '' : 's'} (${plan.totalCharacters} chars) across ${plan.locales.length} locale${plan.locales.length === 1 ? '' : 's'} via ${providerName}?`,
|
|
56
|
+
},
|
|
57
|
+
]);
|
|
58
|
+
return proceed;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Register the translate command
|
|
62
|
+
*/
|
|
63
|
+
export function registerTranslate(program) {
|
|
64
|
+
program
|
|
65
|
+
.command('translate')
|
|
66
|
+
.description('Fill missing locale entries by invoking configured translation adapters')
|
|
67
|
+
.option('-c, --config <path>', 'Path to i18nsmith config file', 'i18n.config.json')
|
|
68
|
+
.option('--json', 'Print raw JSON results', false)
|
|
69
|
+
.option('--report <path>', 'Write JSON summary to a file')
|
|
70
|
+
.option('--write', 'Write translated values to locale files (defaults to dry-run)', false)
|
|
71
|
+
.option('--locales <codes...>', 'Comma-separated list of locale codes to translate', collectLocales, [])
|
|
72
|
+
.option('--provider <name>', 'Override the translation provider configured in i18n.config.json')
|
|
73
|
+
.option('--force', 'Retranslate keys even if a locale already has a value', false)
|
|
74
|
+
.option('--estimate', 'Attempt to estimate cost when running in dry-run mode', false)
|
|
75
|
+
.option('--no-skip-empty', 'Allow writing empty translator results (default skips them)')
|
|
76
|
+
.option('-y, --yes', 'Skip interactive confirmation when applying translations', false)
|
|
77
|
+
.option('--strict-placeholders', 'Fail if translated output has placeholder mismatches (for CI)', false)
|
|
78
|
+
.option('--export <path>', 'Export missing translations to a CSV file for external translation')
|
|
79
|
+
.option('--import <path>', 'Import translations from a CSV file and merge into locale files')
|
|
80
|
+
.action(async (options) => {
|
|
81
|
+
// Handle CSV export mode
|
|
82
|
+
if (options.export) {
|
|
83
|
+
await handleCsvExport(options);
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Handle CSV import mode
|
|
87
|
+
if (options.import) {
|
|
88
|
+
await handleCsvImport(options);
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
console.log(chalk.blue(options.write ? 'Translating locale files...' : 'Planning translations (dry-run)...'));
|
|
92
|
+
try {
|
|
93
|
+
const config = await loadConfig(options.config);
|
|
94
|
+
const translationService = new TranslationService(config);
|
|
95
|
+
const plan = await translationService.buildPlan({
|
|
96
|
+
locales: options.locales,
|
|
97
|
+
force: options.force,
|
|
98
|
+
});
|
|
99
|
+
const placeholderValidator = new PlaceholderValidator(config.sync?.placeholderFormats?.length ? config.sync.placeholderFormats : DEFAULT_PLACEHOLDER_FORMATS);
|
|
100
|
+
if (!plan.totalTasks) {
|
|
101
|
+
console.log(chalk.green('✓ No missing translations detected.'));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const providerSettings = resolveProviderSettings(config.translation, options.provider);
|
|
105
|
+
const summary = {
|
|
106
|
+
provider: providerSettings.name,
|
|
107
|
+
dryRun: !options.write,
|
|
108
|
+
plan,
|
|
109
|
+
locales: [],
|
|
110
|
+
localeStats: [],
|
|
111
|
+
totalCharacters: plan.totalCharacters,
|
|
112
|
+
};
|
|
113
|
+
if (!options.write) {
|
|
114
|
+
if (options.estimate && providerSettings.name !== 'manual') {
|
|
115
|
+
await maybePrintEstimate(plan, providerSettings);
|
|
116
|
+
}
|
|
117
|
+
await emitTranslateOutput(summary, options);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (providerSettings.name === 'manual') {
|
|
121
|
+
throw new Error('No translation provider configured. Update "translation.provider" in i18n.config.json or pass --provider.');
|
|
122
|
+
}
|
|
123
|
+
if (options.write && !options.yes) {
|
|
124
|
+
if (!process.stdout.isTTY) {
|
|
125
|
+
throw new Error('Interactive confirmation required in non-TTY environment. Re-run with --yes to proceed.');
|
|
126
|
+
}
|
|
127
|
+
const confirmed = await confirmTranslate(plan, providerSettings.name);
|
|
128
|
+
if (!confirmed) {
|
|
129
|
+
console.log(chalk.yellow('Translation aborted by user.'));
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
const skipEmpty = options.skipEmpty !== false;
|
|
134
|
+
const strictPlaceholders = options.strictPlaceholders ?? false;
|
|
135
|
+
const localeResults = await executeTranslations({
|
|
136
|
+
plan,
|
|
137
|
+
translationService,
|
|
138
|
+
provider: providerSettings,
|
|
139
|
+
overwrite: options.force ?? false,
|
|
140
|
+
skipEmpty,
|
|
141
|
+
placeholderValidator,
|
|
142
|
+
strictPlaceholders,
|
|
143
|
+
});
|
|
144
|
+
summary.locales = localeResults.results;
|
|
145
|
+
summary.localeStats = localeResults.stats;
|
|
146
|
+
// Check for placeholder issues in strict mode
|
|
147
|
+
const allPlaceholderIssues = localeResults.results.flatMap((r) => r.placeholderIssues);
|
|
148
|
+
if (strictPlaceholders && allPlaceholderIssues.length > 0) {
|
|
149
|
+
console.error(chalk.red(`\n✗ ${allPlaceholderIssues.length} placeholder issue(s) detected in translated output:`));
|
|
150
|
+
allPlaceholderIssues.slice(0, 10).forEach((issue) => {
|
|
151
|
+
console.error(chalk.red(` • ${issue.key} (${issue.locale}): ${issue.type} placeholder${issue.placeholders.length === 1 ? '' : 's'} ${issue.placeholders.join(', ')}`));
|
|
152
|
+
});
|
|
153
|
+
if (allPlaceholderIssues.length > 10) {
|
|
154
|
+
console.error(chalk.red(` ... and ${allPlaceholderIssues.length - 10} more issues`));
|
|
155
|
+
}
|
|
156
|
+
process.exitCode = 1;
|
|
157
|
+
}
|
|
158
|
+
await emitTranslateOutput(summary, options);
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
const translatorError = error instanceof TranslatorLoadError ? error : undefined;
|
|
162
|
+
const normalizedError = error instanceof Error
|
|
163
|
+
? error
|
|
164
|
+
: new Error(typeof error === 'string' ? error : JSON.stringify(error));
|
|
165
|
+
console.error(chalk.red('Translate failed:'), translatorError?.message ?? normalizedError.message);
|
|
166
|
+
process.exitCode = 1;
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/commands/translate/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting and reporting utilities for the translate command
|
|
3
|
+
*/
|
|
4
|
+
import type { TranslationPlan } from '@i18nsmith/core';
|
|
5
|
+
import { type TranslatorLoadOptions } from '@i18nsmith/translation';
|
|
6
|
+
import type { TranslateSummary, TranslateLocaleResult, TranslateCommandOptions, ProviderSettings } from './types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Emit the translation output (report file, JSON, or console)
|
|
9
|
+
*/
|
|
10
|
+
export declare function emitTranslateOutput(summary: TranslateSummary, options: TranslateCommandOptions): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Print a summary of the translation plan
|
|
13
|
+
*/
|
|
14
|
+
export declare function printPlanSummary(plan: TranslationPlan): void;
|
|
15
|
+
/**
|
|
16
|
+
* Print the execution summary after translations are applied
|
|
17
|
+
*/
|
|
18
|
+
export declare function printExecutionSummary(results: TranslateLocaleResult[]): void;
|
|
19
|
+
/**
|
|
20
|
+
* Print cost estimation if available
|
|
21
|
+
*/
|
|
22
|
+
export declare function maybePrintEstimate(plan: TranslationPlan, provider: ProviderSettings & {
|
|
23
|
+
loaderOptions: TranslatorLoadOptions;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Print a generic cost estimate based on common cloud provider rates
|
|
27
|
+
*/
|
|
28
|
+
export declare function printGenericEstimate(plan: TranslationPlan): void;
|
|
29
|
+
//# sourceMappingURL=reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../../src/commands/translate/reporter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACpF,OAAO,KAAK,EACV,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAqB5D;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAY5E;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,eAAe,EACrB,QAAQ,EAAE,gBAAgB,GAAG;IAAE,aAAa,EAAE,qBAAqB,CAAA;CAAE,GACpE,OAAO,CAAC,IAAI,CAAC,CAuBf;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,eAAe,GAAG,IAAI,CAShE"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output formatting and reporting utilities for the translate command
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'fs/promises';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import chalk from 'chalk';
|
|
7
|
+
import { loadTranslator } from '@i18nsmith/translation';
|
|
8
|
+
/**
|
|
9
|
+
* Emit the translation output (report file, JSON, or console)
|
|
10
|
+
*/
|
|
11
|
+
export async function emitTranslateOutput(summary, options) {
|
|
12
|
+
if (options.report) {
|
|
13
|
+
const outputPath = path.resolve(process.cwd(), options.report);
|
|
14
|
+
await fs.mkdir(path.dirname(outputPath), { recursive: true });
|
|
15
|
+
await fs.writeFile(outputPath, JSON.stringify(summary, null, 2));
|
|
16
|
+
console.log(chalk.green(`Translate report written to ${outputPath}`));
|
|
17
|
+
}
|
|
18
|
+
if (options.json) {
|
|
19
|
+
console.log(JSON.stringify(summary, null, 2));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
printPlanSummary(summary.plan);
|
|
23
|
+
if (!summary.dryRun) {
|
|
24
|
+
printExecutionSummary(summary.locales);
|
|
25
|
+
const mutations = summary.localeStats.reduce((total, stat) => total + stat.added.length + stat.updated.length, 0);
|
|
26
|
+
if (mutations === 0) {
|
|
27
|
+
console.log(chalk.yellow('No locale files were updated. Translator may have skipped all entries.'));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.log(chalk.yellow('Run again with --write to apply translations.'));
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Print a summary of the translation plan
|
|
36
|
+
*/
|
|
37
|
+
export function printPlanSummary(plan) {
|
|
38
|
+
console.log(chalk.green(`Source locale ${plan.sourceLocale}; ${plan.totalTasks} missing entr${plan.totalTasks === 1 ? 'y' : 'ies'} across ${plan.locales.length} locale${plan.locales.length === 1 ? '' : 's'}.`));
|
|
39
|
+
if (!plan.locales.length) {
|
|
40
|
+
console.log(chalk.green('All configured locales are up to date.'));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
plan.locales.forEach((localePlan) => {
|
|
44
|
+
const reuseCount = localePlan.tasks.filter((task) => task.reusedValue).length;
|
|
45
|
+
const reuseMessage = reuseCount > 0 ? chalk.gray(` (${reuseCount} reusable)`) : '';
|
|
46
|
+
console.log(` • ${localePlan.locale}: ${localePlan.tasks.length} key${localePlan.tasks.length === 1 ? '' : 's'} (${localePlan.totalCharacters} chars)${reuseMessage}`);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Print the execution summary after translations are applied
|
|
51
|
+
*/
|
|
52
|
+
export function printExecutionSummary(results) {
|
|
53
|
+
if (!results.length) {
|
|
54
|
+
console.log(chalk.yellow('No translations were written.'));
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
console.log(chalk.blue('\nTranslation results:'));
|
|
58
|
+
results.forEach((result) => {
|
|
59
|
+
console.log(` • ${result.locale}: ${result.written} written, ${result.skipped} skipped, ${result.emptySkipped} empty (${result.characters} chars)`);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Print cost estimation if available
|
|
64
|
+
*/
|
|
65
|
+
export async function maybePrintEstimate(plan, provider) {
|
|
66
|
+
console.log(chalk.blue('\n📊 Cost Estimation:'));
|
|
67
|
+
console.log(chalk.gray(` Provider: ${provider.name}`));
|
|
68
|
+
console.log(chalk.gray(` Total characters: ${plan.totalCharacters.toLocaleString()}`));
|
|
69
|
+
console.log(chalk.gray(` Locales: ${plan.locales.length}`));
|
|
70
|
+
try {
|
|
71
|
+
const translator = await loadTranslator(provider.loaderOptions);
|
|
72
|
+
if (typeof translator.estimateCost === 'function') {
|
|
73
|
+
const estimate = await translator.estimateCost(plan.totalCharacters, { localeCount: plan.locales.length });
|
|
74
|
+
const formattedCost = typeof estimate === 'number'
|
|
75
|
+
? `$${estimate.toFixed(4)}`
|
|
76
|
+
: String(estimate);
|
|
77
|
+
console.log(chalk.green(` Estimated cost: ${formattedCost}`));
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
console.log(chalk.yellow(' Provider does not expose cost estimation.'));
|
|
81
|
+
printGenericEstimate(plan);
|
|
82
|
+
}
|
|
83
|
+
await translator.dispose?.();
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
console.log(chalk.yellow(` Unable to estimate via provider: ${error.message}`));
|
|
87
|
+
printGenericEstimate(plan);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Print a generic cost estimate based on common cloud provider rates
|
|
92
|
+
*/
|
|
93
|
+
export function printGenericEstimate(plan) {
|
|
94
|
+
// Generic estimation based on common cloud provider rates (rough average)
|
|
95
|
+
// Google/AWS/Azure typically charge ~$20 per million characters
|
|
96
|
+
const ratePerMillion = 20;
|
|
97
|
+
const charsByLocale = plan.totalCharacters;
|
|
98
|
+
const totalChars = charsByLocale * plan.locales.length;
|
|
99
|
+
const estimated = (totalChars / 1000000) * ratePerMillion;
|
|
100
|
+
console.log(chalk.gray(` Generic estimate (at ~$20/M chars): $${estimated.toFixed(4)}`));
|
|
101
|
+
console.log(chalk.gray(' (Actual costs vary by provider and tier)'));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../../src/commands/translate/reporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for the translate command
|
|
3
|
+
*/
|
|
4
|
+
import type { TranslationWriteSummary, TranslationPlan } from '@i18nsmith/core';
|
|
5
|
+
import type { TranslationService } from '@i18nsmith/core';
|
|
6
|
+
export interface TranslateCommandOptions {
|
|
7
|
+
config?: string;
|
|
8
|
+
json?: boolean;
|
|
9
|
+
report?: string;
|
|
10
|
+
write?: boolean;
|
|
11
|
+
locales?: string[];
|
|
12
|
+
provider?: string;
|
|
13
|
+
force?: boolean;
|
|
14
|
+
estimate?: boolean;
|
|
15
|
+
skipEmpty?: boolean;
|
|
16
|
+
yes?: boolean;
|
|
17
|
+
strictPlaceholders?: boolean;
|
|
18
|
+
export?: string;
|
|
19
|
+
import?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface TranslateLocaleResult extends TranslationWriteSummary {
|
|
22
|
+
characters: number;
|
|
23
|
+
placeholderIssues: PlaceholderIssue[];
|
|
24
|
+
}
|
|
25
|
+
export interface PlaceholderIssue {
|
|
26
|
+
key: string;
|
|
27
|
+
locale: string;
|
|
28
|
+
type: 'missing' | 'extra';
|
|
29
|
+
placeholders: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface TranslateSummary {
|
|
32
|
+
provider: string;
|
|
33
|
+
dryRun: boolean;
|
|
34
|
+
plan: TranslationPlan;
|
|
35
|
+
locales: TranslateLocaleResult[];
|
|
36
|
+
localeStats: Awaited<ReturnType<TranslationService['flush']>>;
|
|
37
|
+
totalCharacters: number;
|
|
38
|
+
}
|
|
39
|
+
export interface ProviderSettings {
|
|
40
|
+
name: string;
|
|
41
|
+
options?: Record<string, unknown>;
|
|
42
|
+
}
|
|
43
|
+
export interface CsvRow {
|
|
44
|
+
key: string;
|
|
45
|
+
sourceLocale: string;
|
|
46
|
+
sourceValue: string;
|
|
47
|
+
targetLocale: string;
|
|
48
|
+
targetValue: string;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/commands/translate/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAE1D,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,EAAE,gBAAgB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,EAAE,eAAe,CAAC;IACtB,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC,UAAU,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9D,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/commands/translate/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.d.ts","sourceRoot":"","sources":["../../src/commands/translate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.js","sourceRoot":"","sources":["../../src/commands/translate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,cAAc,sBAAsB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.test.d.ts","sourceRoot":"","sources":["../../src/commands/translate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import os from 'os';
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
describe('translate command', () => {
|
|
7
|
+
let tempDir;
|
|
8
|
+
beforeEach(async () => {
|
|
9
|
+
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'i18nsmith-translate-test-'));
|
|
10
|
+
// Create basic project structure
|
|
11
|
+
await fs.mkdir(path.join(tempDir, 'src'), { recursive: true });
|
|
12
|
+
await fs.mkdir(path.join(tempDir, 'locales'), { recursive: true });
|
|
13
|
+
// Create source file with translation calls
|
|
14
|
+
await fs.writeFile(path.join(tempDir, 'src', 'App.tsx'), `import { useTranslation } from 'react-i18next';
|
|
15
|
+
export function App() {
|
|
16
|
+
const { t } = useTranslation();
|
|
17
|
+
return <div>{t('greeting')}{t('farewell')}</div>;
|
|
18
|
+
}
|
|
19
|
+
`);
|
|
20
|
+
// Create source locale
|
|
21
|
+
await fs.writeFile(path.join(tempDir, 'locales', 'en.json'), JSON.stringify({ greeting: 'Hello', farewell: 'Goodbye' }, null, 2));
|
|
22
|
+
// Create target locale with one missing key
|
|
23
|
+
await fs.writeFile(path.join(tempDir, 'locales', 'fr.json'), JSON.stringify({ greeting: 'Bonjour' }, null, 2));
|
|
24
|
+
// Create config
|
|
25
|
+
await fs.writeFile(path.join(tempDir, 'i18n.config.json'), JSON.stringify({
|
|
26
|
+
version: 1,
|
|
27
|
+
sourceLanguage: 'en',
|
|
28
|
+
targetLanguages: ['fr'],
|
|
29
|
+
localesDir: 'locales',
|
|
30
|
+
include: ['src/**/*.{ts,tsx}'],
|
|
31
|
+
}, null, 2));
|
|
32
|
+
});
|
|
33
|
+
afterEach(async () => {
|
|
34
|
+
await fs.rm(tempDir, { recursive: true, force: true });
|
|
35
|
+
});
|
|
36
|
+
const runCli = (args) => {
|
|
37
|
+
const cliPath = path.resolve(__dirname, '..', '..', 'dist', 'index.js');
|
|
38
|
+
try {
|
|
39
|
+
return execSync(`node ${cliPath} ${args}`, {
|
|
40
|
+
cwd: tempDir,
|
|
41
|
+
encoding: 'utf8',
|
|
42
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const err = error;
|
|
47
|
+
return (err.stdout ?? '') + (err.stderr ?? '');
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
describe('--export', () => {
|
|
51
|
+
it('exports missing translations to CSV', async () => {
|
|
52
|
+
const csvPath = path.join(tempDir, 'missing.csv');
|
|
53
|
+
const output = runCli(`translate --export ${csvPath}`);
|
|
54
|
+
expect(output).toContain('Exported');
|
|
55
|
+
const csvContent = await fs.readFile(csvPath, 'utf8');
|
|
56
|
+
expect(csvContent).toContain('key,sourceLocale,sourceValue,targetLocale,translatedValue');
|
|
57
|
+
expect(csvContent).toContain('farewell');
|
|
58
|
+
expect(csvContent).toContain('Goodbye');
|
|
59
|
+
expect(csvContent).toContain('fr');
|
|
60
|
+
});
|
|
61
|
+
it('handles empty values correctly', async () => {
|
|
62
|
+
// All translations are present
|
|
63
|
+
await fs.writeFile(path.join(tempDir, 'locales', 'fr.json'), JSON.stringify({ greeting: 'Bonjour', farewell: 'Au revoir' }, null, 2));
|
|
64
|
+
const output = runCli('translate --export output.csv');
|
|
65
|
+
expect(output).toContain('No missing translations');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
describe('--import', () => {
|
|
69
|
+
it('imports translations from CSV', async () => {
|
|
70
|
+
const csvPath = path.join(tempDir, 'translations.csv');
|
|
71
|
+
await fs.writeFile(csvPath, `key,sourceLocale,sourceValue,targetLocale,translatedValue
|
|
72
|
+
farewell,en,Goodbye,fr,Au revoir
|
|
73
|
+
`);
|
|
74
|
+
const output = runCli(`translate --import ${csvPath} --write`);
|
|
75
|
+
expect(output).toContain('1 row');
|
|
76
|
+
const frContent = await fs.readFile(path.join(tempDir, 'locales', 'fr.json'), 'utf8');
|
|
77
|
+
const frData = JSON.parse(frContent);
|
|
78
|
+
expect(frData.farewell).toBe('Au revoir');
|
|
79
|
+
});
|
|
80
|
+
it('skips rows with empty translatedValue', async () => {
|
|
81
|
+
const csvPath = path.join(tempDir, 'translations.csv');
|
|
82
|
+
await fs.writeFile(csvPath, `key,sourceLocale,sourceValue,targetLocale,translatedValue
|
|
83
|
+
farewell,en,Goodbye,fr,
|
|
84
|
+
`);
|
|
85
|
+
const output = runCli(`translate --import ${csvPath}`);
|
|
86
|
+
expect(output).toContain('skipped');
|
|
87
|
+
});
|
|
88
|
+
it('handles quoted CSV fields with commas', async () => {
|
|
89
|
+
// Add a source key with comma
|
|
90
|
+
await fs.writeFile(path.join(tempDir, 'locales', 'en.json'), JSON.stringify({
|
|
91
|
+
greeting: 'Hello',
|
|
92
|
+
farewell: 'Goodbye',
|
|
93
|
+
message: 'Hello, world!'
|
|
94
|
+
}, null, 2));
|
|
95
|
+
const csvPath = path.join(tempDir, 'translations.csv');
|
|
96
|
+
await fs.writeFile(csvPath, `key,sourceLocale,sourceValue,targetLocale,translatedValue
|
|
97
|
+
message,en,"Hello, world!",fr,"Bonjour, le monde!"
|
|
98
|
+
`);
|
|
99
|
+
const output = runCli(`translate --import ${csvPath} --write`);
|
|
100
|
+
expect(output).toContain('1 row');
|
|
101
|
+
const frContent = await fs.readFile(path.join(tempDir, 'locales', 'fr.json'), 'utf8');
|
|
102
|
+
const frData = JSON.parse(frContent);
|
|
103
|
+
expect(frData.message).toBe('Bonjour, le monde!');
|
|
104
|
+
});
|
|
105
|
+
it('dry-run mode does not write files', async () => {
|
|
106
|
+
const csvPath = path.join(tempDir, 'translations.csv');
|
|
107
|
+
await fs.writeFile(csvPath, `key,sourceLocale,sourceValue,targetLocale,translatedValue
|
|
108
|
+
farewell,en,Goodbye,fr,Au revoir
|
|
109
|
+
`);
|
|
110
|
+
const originalContent = await fs.readFile(path.join(tempDir, 'locales', 'fr.json'), 'utf8');
|
|
111
|
+
const output = runCli(`translate --import ${csvPath}`);
|
|
112
|
+
expect(output).toContain('DRY RUN');
|
|
113
|
+
const newContent = await fs.readFile(path.join(tempDir, 'locales', 'fr.json'), 'utf8');
|
|
114
|
+
expect(newContent).toBe(originalContent);
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
//# sourceMappingURL=translate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"translate.test.js","sourceRoot":"","sources":["../../src/commands/translate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e2e.test.d.ts","sourceRoot":"","sources":["../src/e2e.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|