https://github.com/mariokreitz/i18n-excel-manager
CLI tool for converting and validating i18n JSON and Excel files with placeholder validation
https://github.com/mariokreitz/i18n-excel-manager
cli converter excel i18n internationalization json l10n language localization-tool translations
Last synced: 6 months ago
JSON representation
CLI tool for converting and validating i18n JSON and Excel files with placeholder validation
- Host: GitHub
- URL: https://github.com/mariokreitz/i18n-excel-manager
- Owner: mariokreitz
- License: mit
- Created: 2025-06-16T11:24:12.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2025-12-15T21:31:26.000Z (7 months ago)
- Last Synced: 2025-12-19T05:40:09.306Z (7 months ago)
- Topics: cli, converter, excel, i18n, internationalization, json, l10n, language, localization-tool, translations
- Language: JavaScript
- Homepage: https://www.npmjs.com/package/i18n-excel-manager
- Size: 1.47 MB
- Stars: 5
- Watchers: 0
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# i18n-excel-manager
[](https://github.com/mariokreitz/i18n-excel-manager/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/i18n-excel-manager)
[](https://www.npmjs.com/package/i18n-excel-manager)
[](https://codecov.io/gh/mariokreitz/i18n-excel-manager)
[](https://opensource.org/licenses/MIT)
i18n-excel-manager
Effortless conversion between i18n JSON files and Excel for Angular and modern web projects.
---
## β¨ Features
### Core Conversion
- **Bidirectional Conversion**: Convert i18n JSON files to Excel and vice versa.
- **Nested Key Support**: Handles deeply nested translation structures with dot-notation flattening.
- **Language Mapping**: Use full language names in Excel headers (e.g., "German" instead of "de").
- **Placeholder Validation**: Detect inconsistent placeholders (e.g., `{{value}}`) across languages.
- **Duplicate Detection**: Identify and handle duplicate translation keys.
### Codebase Analysis
- **Missing Key Detection**: Find translation keys used in code but missing from JSON files.
- **Unused Key Detection**: Identify translation keys defined in JSON but never used in code.
- **Flexible Patterns**: Scan any file types using customizable glob patterns.
- **Multi-file Reports**: Get analysis reports for each language file separately.
### AI-Powered Translation
- **Gemini Integration**: Auto-translate missing values using Google's Gemini AI.
- **Placeholder Preservation**: AI preserves `{{placeholders}}`, HTML tags, and formatting.
- **Multiple Models**: Choose from `gemini-2.5-flash`, `gemini-1.5-flash`, or `gemini-1.5-pro`.
- **Batch Processing**: Efficiently translates multiple strings in a single API call.
### Developer Experience
- **Interactive CLI**: User-friendly menu-driven interface for all operations.
- **Dry-Run Mode**: Preview changes without writing files.
- **Initialization**: Quickly scaffold i18n folders and starter JSON files.
- **Path Safety**: Prevent directory traversal attacks with path validation.
- **Node.js API**: Programmatic access for CI/CD integrations.
---
## π Table of Contents
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Usage](#-usage)
- [Interactive Mode](#interactive-mode)
- [Initialize i18n Files](#initialize-i18n-files)
- [Convert JSON to Excel](#convert-json-to-excel)
- [Convert Excel to JSON](#convert-excel-to-json)
- [Analyze Codebase](#analyze-codebase)
- [AI Auto-Translation](#ai-auto-translation)
- [API](#-api)
- [Angular Integration](#-angular-integration)
- [Configuration](#-configuration)
- [CLI Options Reference](#-cli-options-reference)
- [Migration Guide](#-migration-guide)
- [Error Handling](#-error-handling)
- [Architecture](#-architecture)
- [Known Issues](#-known-issues)
- [Development](#-development)
- [Contributing](#-contributing)
- [License](#-license)
---
## π¦ Installation
### Requirements
- Node.js >= 20
- Tested on Node.js 20.x, 22.x, and 24.x
### Global Installation (Recommended)
```bash
npm install -g i18n-excel-manager
```
### Local Installation (as dev dependency)
```bash
npm install --save-dev i18n-excel-manager
```
---
## π Quick Start
1. **Install globally:**
```bash
npm install -g i18n-excel-manager
```
2. **Initialize a new project** (creates `public/assets/i18n` with starter files):
```bash
i18n-excel-manager init --output ./public/assets/i18n --languages en,de,fr
```
3. **Convert JSON to Excel:**
```bash
i18n-excel-manager i18n-to-excel --input ./public/assets/i18n --output translations.xlsx
```
4. **Edit the Excel file** with your translations.
5. **Convert back to JSON:**
```bash
i18n-excel-manager excel-to-i18n --input translations.xlsx --output ./public/assets/i18n
```
6. **Analyze your codebase** for missing/unused keys:
```bash
i18n-excel-manager analyze --input ./public/assets/i18n --pattern "src/**/*.{ts,html}"
```
7. **Auto-translate missing values** with AI:
```bash
i18n-excel-manager analyze --translate --input translations.xlsx --api-key YOUR_GEMINI_KEY
```
> **Tip:** Running `i18n-excel-manager` without arguments opens an interactive menu with all options.
---
## π οΈ Usage
### Interactive Mode
Run without arguments for a guided experience:
```bash
i18n-excel-manager
```
The interactive menu provides access to all features:
- Convert i18n files to Excel
- Convert Excel to i18n files
- Analyze Codebase (Missing/Unused keys)
- AI Auto-Translate (Fill missing translations)
- Initialize i18n files
If the default i18n folder is missing or empty, the CLI will offer to initialize it.
### Initialize i18n Files
Create the i18n directory and language files with minimal starter content. Existing files are never overwritten.
```bash
i18n-excel-manager init \
--output ./public/assets/i18n \
--languages en,de,fr
```
**Options:**
- Use `--dry-run` to preview which files would be created.
- Omit `--languages` to choose interactively from configured languages.
**Example output:**
```
β Created: public/assets/i18n/en.json
β Created: public/assets/i18n/de.json
β Created: public/assets/i18n/fr.json
```
### Convert JSON to Excel
Convert your i18n JSON files into an Excel workbook for easy editing and collaboration:
```bash
i18n-excel-manager i18n-to-excel \
--input ./public/assets/i18n \
--output translations.xlsx \
--sheet-name "Translations"
```
The Excel file will have:
- Column A: Translation keys (dot-notation)
- Subsequent columns: One per language (en, de, fr, etc.)
### Convert Excel to JSON
Convert an Excel workbook back to individual JSON files per language:
```bash
i18n-excel-manager excel-to-i18n \
--input translations.xlsx \
--output ./public/assets/i18n \
--fail-on-duplicates
```
**Options:**
- `--fail-on-duplicates`: Exit with error if duplicate keys are detected.
- `--dry-run`: Preview changes without writing files.
### Analyze Codebase
Scan your source code to find translation keys that are missing from your JSON files or defined but never used:
```bash
i18n-excel-manager analyze \
--input ./public/assets/i18n \
--pattern "src/**/*.{ts,html}"
```
**What it detects:**
- **Missing keys**: Keys used in code (e.g., `{{ 'app.title' | translate }}`) but not defined in JSON.
- **Unused keys**: Keys defined in JSON but never referenced in your codebase.
**Supported patterns in code:**
```typescript
// Angular pipe syntax
{
{
'KEY.NAME' | translate
}
}
// TranslateService methods
this.translate.get('KEY.NAME');
this.translate.instant('KEY.NAME');
this.translate.stream('KEY.NAME');
// Directive syntax
< div [translate] = "'KEY.NAME'" >
```
**Example output:**
```
Analysis Report:
Total Code Keys Found: 42
en.json
Missing in JSON:
- app.newFeature
- errors.timeout
Unused in Code:
- legacy.oldButton
de.json
All good!
```
### AI Auto-Translation
Automatically translate missing values in your Excel file using Google's Gemini AI:
```bash
i18n-excel-manager analyze \
--translate \
--input translations.xlsx \
--api-key YOUR_GEMINI_API_KEY \
--source-lang en \
--model gemini-2.5-flash
```
**API Key Configuration:**
The API key can be provided in three ways (in order of precedence):
1. CLI flag: `--api-key YOUR_KEY`
2. Environment variable: `GEMINI_API_KEY`
3. Fallback environment variable: `I18N_MANAGER_API_KEY`
**Available Models:**
| Model | Description |
| ------------------ | ---------------------------- |
| `gemini-2.5-flash` | Fast and efficient (default) |
| `gemini-1.5-flash` | Balanced speed and quality |
| `gemini-1.5-pro` | Highest quality, slower |
**Features:**
- Preserves placeholders like `{{value}}`, `{0}`, etc.
- Maintains HTML tags and formatting
- Processes translations in efficient batches
- Uses low temperature (0.2) for consistent results
**Interactive Mode:**
When using interactive mode, you'll be prompted for:
- Path to Excel file
- Source language code
- API key (can be masked input)
- Model selection
---
## π API
Use the library programmatically in your Node.js applications:
```javascript
import {
convertToExcel,
convertToJson,
analyze,
translate,
} from 'i18n-excel-manager';
```
### convertToExcel(sourcePath, targetFile, options?)
Convert JSON localization files to an Excel workbook.
```javascript
await convertToExcel('./public/assets/i18n', 'translations.xlsx', {
sheetName: 'Translations',
dryRun: false,
languageMap: { en: 'English', de: 'Deutsch' },
});
```
### convertToJson(sourceFile, targetPath, options?)
Convert an Excel workbook to JSON localization files.
```javascript
await convertToJson('translations.xlsx', './public/assets/i18n', {
sheetName: 'Translations',
failOnDuplicates: true,
});
```
### analyze(options)
Analyze the codebase for missing and unused translation keys.
```javascript
const report = await analyze({
sourcePath: './public/assets/i18n',
codePattern: 'src/**/*.{ts,html}',
});
console.log(`Total keys in code: ${report.totalCodeKeys}`);
for (const [file, result] of Object.entries(report.fileReports)) {
console.log(`${file}:`);
console.log(` Missing: ${result.missing.join(', ')}`);
console.log(` Unused: ${result.unused.join(', ')}`);
}
```
**Return type:**
```typescript
{
totalCodeKeys: number;
fileReports: {
[ filename
:
string
]:
{
missing: string[]; // Keys in code but not in JSON
unused: string[]; // Keys in JSON but not in code
}
}
}
```
### translate(options)
Auto-translate missing values in an Excel workbook using Gemini AI.
```javascript
await translate({
input: './translations.xlsx',
apiKey: process.env.GEMINI_API_KEY,
sourceLang: 'en',
model: 'gemini-2.5-flash',
languageMap: { en: 'English', de: 'German', fr: 'French' },
});
```
**Options:**
| Option | Type | Required | Default | Description |
| ------------- | ------ | -------- | -------------------- | ------------------------------------- |
| `input` | string | Yes | - | Path to the Excel file |
| `apiKey` | string | Yes | - | Gemini API key |
| `sourceLang` | string | No | `'en'` | Source language code |
| `model` | string | No | `'gemini-2.5-flash'` | Gemini model to use |
| `languageMap` | object | No | `{}` | Language code to display name mapping |
---
## π§ Angular Integration
This tool is designed to work seamlessly with Angular's i18n workflow. It's compatible with **Angular 17+** and \*
\*ngx-translate v17+\*\*.
### Project Structure
A typical Angular project structure for i18n:
```
my-angular-app/
βββ public/
β βββ assets/
β βββ i18n/
β βββ en.json
β βββ de.json
β βββ fr.json
βββ src/
β βββ app/
β βββ app.component.ts
β βββ app.config.ts
βββ angular.json
```
### Installation
Install ngx-translate packages:
```bash
npm install @ngx-translate/core @ngx-translate/http-loader
```
### App Configuration (Angular 20+ / ngx-translate v17+)
Configure the translation service in `src/app/app.config.ts`:
```typescript
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withFetch } from '@angular/common/http';
import { provideTranslateService } from '@ngx-translate/core';
import { provideTranslateHttpLoader } from '@ngx-translate/http-loader';
export const appConfig: ApplicationConfig = {
providers: [
provideHttpClient(withFetch()),
provideTranslateService({
loader: provideTranslateHttpLoader({
prefix: './assets/i18n/',
suffix: '.json',
}),
fallbackLang: 'en',
lang: 'en',
}),
],
};
```
### Using Translations in Components
Use the `TranslatePipe` and `TranslateService` in your standalone components:
```typescript
import { Component, inject, signal } from '@angular/core';
import { TranslateService, TranslatePipe } from '@ngx-translate/core';
@Component({
selector: 'app-root',
imports: [TranslatePipe],
template: `
{{ 'app.title' | translate }}
{{ 'app.welcome' | translate: { name: userName() } }}
English
Deutsch
`,
})
export class AppComponent {
private translate = inject(TranslateService);
userName = signal('User');
switchLanguage(lang: string) {
this.translate.use(lang);
}
}
```
### Using the Translate Directive
For translating element content directly:
```typescript
import { Component, inject } from '@angular/core';
import { TranslateService, TranslateDirective } from '@ngx-translate/core';
@Component({
selector: 'app-header',
imports: [TranslateDirective],
template: `
`,
})
export class HeaderComponent {
private translate = inject(TranslateService);
}
```
### Translation File Format
Your JSON translation files should use nested or flat structures:
**Nested format (`en.json`):**
```json
{
"app": {
"title": "My Application",
"welcome": "Welcome, {{name}}!"
},
"header": {
"title": "Dashboard",
"subtitle": "Version {{version}}"
},
"buttons": {
"save": "Save",
"cancel": "Cancel"
}
}
```
### Generating Translation Files
Use the CLI to convert Excel files to Angular-compatible JSON:
```bash
# Convert Excel to Angular i18n files
i18n-excel-manager excel-to-i18n \
--input ./translations.xlsx \
--output ./public/assets/i18n \
--fail-on-duplicates
```
### Angular Configuration
Ensure `public/` is included in your `angular.json` assets:
```json
{
"projects": {
"my-app": {
"architect": {
"build": {
"options": {
"assets": ["public"]
}
}
}
}
}
}
```
### Best Practices
- **Version Control**: Commit translation files to git for version history.
- **CI/CD Integration**: Run `analyze` in your pipeline to catch missing translations.
- **Language Detection**: Use browser language or user preferences for initial language.
- **Lazy Loading**: Consider splitting translations per feature for large applications.
- **Validation**: Use `--dry-run` to validate translations before deployment.
- **Placeholder Consistency**: Use consistent placeholder names across all languages.
---
## βοΈ Configuration
Create a `config.json` file for custom settings. The CLI automatically loads `./config.json` from your current working
directory when present.
```json
{
"languages": {
"en": "English",
"de": "Deutsch",
"fr": "FranΓ§ais",
"es": "Spanish"
},
"defaults": {
"sourcePath": "./public/assets/i18n",
"targetFile": "translations.xlsx",
"targetPath": "./public/assets/i18n",
"sheetName": "Translations"
}
}
```
### Configuration Precedence
CLI options take precedence over config file settings:
```
CLI flags > config.defaults > built-in defaults
```
Language map precedence:
```
CLI > config.languages > runtime config
```
### Usage Examples
```bash
# Autoload from CWD
i18n-excel-manager i18n-to-excel --dry-run
# Custom config path
i18n-excel-manager i18n-to-excel --config ./my-config.json --dry-run
# CLI flags override config
i18n-excel-manager i18n-to-excel -i ./custom -o out.xlsx --dry-run
```
> **Note:** For safety, `--config` must point within the current working directory.
---
## π CLI Options Reference
### `init` Command
| Option | Short | Description | Default |
| -------------------- | ----- | -------------------------------------------- | --------------------- |
| `--output ` | `-o` | Target directory for i18n JSON files | `public/assets/i18n` |
| `--languages ` | `-l` | Comma-separated language codes to initialize | prompts interactively |
| `--dry-run` | `-d` | Simulate only, do not write files | `false` |
| `--config ` | | Path to config file | `./config.json` |
### `i18n-to-excel` Command
| Option | Short | Description | Default |
| --------------------- | ----- | -------------------------------------------- | ------------------------ |
| `--input ` | `-i` | Path to directory containing i18n JSON files | `public/assets/i18n` |
| `--output ` | `-o` | Path for the output Excel file | `dist/translations.xlsx` |
| `--sheet-name ` | `-s` | Excel worksheet name | `Translations` |
| `--dry-run` | `-d` | Simulate only, do not write files | `false` |
| `--no-report` | | Skip generating translation report | `false` |
| `--config ` | | Path to config file | `./config.json` |
### `excel-to-i18n` Command
| Option | Short | Description | Default |
| ---------------------- | ----- | ------------------------------------ | ------------------------ |
| `--input ` | `-i` | Path to Excel file | `dist/translations.xlsx` |
| `--output ` | `-o` | Target directory for i18n JSON files | `locales` |
| `--sheet-name ` | `-s` | Excel worksheet name | `Translations` |
| `--dry-run` | `-d` | Simulate only, do not write files | `false` |
| `--fail-on-duplicates` | | Exit with error on duplicate keys | `false` |
| `--config ` | | Path to config file | `./config.json` |
### `analyze` Command
| Option | Short | Description | Default |
| ---------------------- | ----- | -------------------------------------------- | ------------------- |
| `--input ` | `-i` | Path to directory containing i18n JSON files | - |
| `--pattern ` | `-p` | Glob pattern for source code files | `**/*.{html,ts,js}` |
| `--translate` | | Enable AI auto-translation mode | `false` |
| `--api-key ` | | Gemini API key (or use env vars) | - |
| `--source-lang ` | | Source language code for translation | `en` |
| `--model ` | | Gemini model to use | `gemini-2.5-flash` |
| `--config ` | | Path to config file | `./config.json` |
---
## π Migration Guide
### From v1.x to v2.x
In v2.x, we removed legacy CLI command aliases to enforce explicit command names for better clarity and consistency.
#### Breaking Changes
- Removed `to-excel` alias for `i18n-to-excel` command.
- Removed `to-json` alias for `excel-to-i18n` command.
#### Migration Steps
1. Update your scripts to use the full command names:
- Change `i18n-excel-manager to-excel ...` to `i18n-excel-manager i18n-to-excel ...`
- Change `i18n-excel-manager to-json ...` to `i18n-excel-manager excel-to-i18n ...`
2. If you were using the aliases in CI/CD pipelines or automation scripts, update them accordingly.
3. No other changes are required; all other options and functionality remain the same.
If you encounter issues, use `i18n-excel-manager --help` to see available commands.
---
## π¨ Error Handling
The tool provides clear error messages for common issues:
| Error Type | Message Example |
| ---------------------- | ---------------------------------------------------------- |
| Missing files | `File does not exist: path` |
| Invalid JSON | `Invalid JSON in file: error message` |
| Duplicate keys | `Duplicate keys detected in Excel: key1, key2` |
| Invalid language codes | `Invalid language code: xyz` |
| Unsafe paths | `Unsafe output path: path` |
| Missing API key | `API Key is missing. Pass --api-key or set GEMINI_API_KEY` |
Use `--dry-run` to validate before actual conversion.
### Troubleshooting
| Issue | Solution |
| ---------------------- | -------------------------------------------------------- |
| Permission errors | Ensure you have write access to the output directory |
| Invalid language codes | Use standard ISO language codes (e.g., `en`, `de`, `fr`) |
| Missing placeholders | Check for consistent placeholder usage across languages |
| Large files | Consider splitting into multiple sheets |
| API rate limits | Use batch processing or add delays between requests |
---
## ποΈ Architecture
The project follows a modular architecture with clear separation of concerns:
```
src/
βββ app/ # Application orchestration layer
β βββ analyze.js # Codebase analysis orchestrator
β βββ convert.js # Conversion orchestrator
β βββ translate.js # AI translation orchestrator
βββ core/ # Business logic (pure functions)
β βββ analyzer.js # Key extraction and comparison
β βββ translator.js # Gemini API integration
β βββ excel/ # Excel data processing
β βββ json/ # JSON structure handling
β βββ languages/ # Language mapping utilities
βββ io/ # I/O operations
β βββ excel.js # Excel file read/write
β βββ fs.js # File system operations
β βββ config.js # Configuration loading
βββ cli/ # CLI interface
β βββ commands.js # Command handlers
β βββ interactive.js # Interactive menu
β βββ init.js # Initialization logic
βββ reporters/ # Output formatting
βββ console.js # Console reporter
βββ json.js # JSON reporter
```
### Design Principles
- **Modular Design**: Separate concerns for I/O, core logic, and reporting.
- **Pure Functions**: Core business logic is testable and side-effect free.
- **Dependency Injection**: I/O adapters are injectable for testing.
- **Validation**: Input validation at all boundaries.
- **Extensibility**: Pluggable reporters and configurable I/O layers.
---
## β οΈ Known Issues
### Language Mapping After AI Auto-Translation
There is a known issue when exporting back from Excel to JSON after using the AI auto-translator where the language
mapping may not work properly.
**Workaround:** Restart `i18n-excel-manager` and try the export again.
This issue is being tracked and will be fixed in a future release.
---
## π§βπ» Development
### Prerequisites
- Node.js >= 20
- npm or yarn
### Setup
```bash
git clone https://github.com/mariokreitz/i18n-excel-manager.git
cd i18n-excel-manager
npm install
```
### Running Tests
```bash
# Run all tests
npm test
# Run tests with coverage
npm run test:coverage
```
### Linting
```bash
# Check for lint errors
npm run lint
# Fix lint errors
npm run lint:fix
```
### Formatting
```bash
# Check formatting
npm run format:check
# Fix formatting
npm run format
```
---
## π€ Contributing
Contributions are welcome! Please read the [Contributing Guide](CONTRIBUTING.md)
and [Code of Conduct](CODE_OF_CONDUCT.md) before submitting a pull request.
### Quick Contribution Steps
1. Fork the repository
2. Create a feature branch: `git checkout -b feature/amazing-feature`
3. Make your changes
4. Run tests: `npm test`
5. Commit your changes: `git commit -m 'Add amazing feature'`
6. Push to the branch: `git push origin feature/amazing-feature`
7. Open a Pull Request
---
## π License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
---
Made with β€οΈ by Mario Kreitz