ai-i18n-tools 1.0.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/LICENSE +21 -0
- package/README.md +157 -0
- package/dist/api/openrouter.d.ts +115 -0
- package/dist/api/openrouter.d.ts.map +1 -0
- package/dist/api/openrouter.js +399 -0
- package/dist/api/openrouter.js.map +1 -0
- package/dist/cli/doc-translate.d.ts +90 -0
- package/dist/cli/doc-translate.d.ts.map +1 -0
- package/dist/cli/doc-translate.js +1153 -0
- package/dist/cli/doc-translate.js.map +1 -0
- package/dist/cli/export-ui-xliff.d.ts +32 -0
- package/dist/cli/export-ui-xliff.d.ts.map +1 -0
- package/dist/cli/export-ui-xliff.js +153 -0
- package/dist/cli/export-ui-xliff.js.map +1 -0
- package/dist/cli/extract-strings.d.ts +12 -0
- package/dist/cli/extract-strings.d.ts.map +1 -0
- package/dist/cli/extract-strings.js +80 -0
- package/dist/cli/extract-strings.js.map +1 -0
- package/dist/cli/file-utils.d.ts +10 -0
- package/dist/cli/file-utils.d.ts.map +1 -0
- package/dist/cli/file-utils.js +77 -0
- package/dist/cli/file-utils.js.map +1 -0
- package/dist/cli/format.d.ts +21 -0
- package/dist/cli/format.d.ts.map +1 -0
- package/dist/cli/format.js +75 -0
- package/dist/cli/format.js.map +1 -0
- package/dist/cli/helpers.d.ts +27 -0
- package/dist/cli/helpers.d.ts.map +1 -0
- package/dist/cli/helpers.js +84 -0
- package/dist/cli/helpers.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +772 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/log-output.d.ts +13 -0
- package/dist/cli/log-output.d.ts.map +1 -0
- package/dist/cli/log-output.js +75 -0
- package/dist/cli/log-output.js.map +1 -0
- package/dist/cli/translate-svg.d.ts +7 -0
- package/dist/cli/translate-svg.d.ts.map +1 -0
- package/dist/cli/translate-svg.js +167 -0
- package/dist/cli/translate-svg.js.map +1 -0
- package/dist/cli/translate-ui-strings.d.ts +27 -0
- package/dist/cli/translate-ui-strings.d.ts.map +1 -0
- package/dist/cli/translate-ui-strings.js +357 -0
- package/dist/cli/translate-ui-strings.js.map +1 -0
- package/dist/core/cache-tracking-keys.d.ts +12 -0
- package/dist/core/cache-tracking-keys.d.ts.map +1 -0
- package/dist/core/cache-tracking-keys.js +20 -0
- package/dist/core/cache-tracking-keys.js.map +1 -0
- package/dist/core/cache.d.ts +153 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +546 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/config.d.ts +58 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +392 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/doc-file-tracking.d.ts +8 -0
- package/dist/core/doc-file-tracking.d.ts.map +1 -0
- package/dist/core/doc-file-tracking.js +27 -0
- package/dist/core/doc-file-tracking.js.map +1 -0
- package/dist/core/errors.d.ts +19 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +23 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/locale-utils.d.ts +20 -0
- package/dist/core/locale-utils.d.ts.map +1 -0
- package/dist/core/locale-utils.js +75 -0
- package/dist/core/locale-utils.js.map +1 -0
- package/dist/core/output-paths.d.ts +22 -0
- package/dist/core/output-paths.d.ts.map +1 -0
- package/dist/core/output-paths.js +130 -0
- package/dist/core/output-paths.js.map +1 -0
- package/dist/core/prompt-builder.d.ts +62 -0
- package/dist/core/prompt-builder.d.ts.map +1 -0
- package/dist/core/prompt-builder.js +232 -0
- package/dist/core/prompt-builder.js.map +1 -0
- package/dist/core/prompts.d.ts +27 -0
- package/dist/core/prompts.d.ts.map +1 -0
- package/dist/core/prompts.js +57 -0
- package/dist/core/prompts.js.map +1 -0
- package/dist/core/svg-asset-paths.d.ts +40 -0
- package/dist/core/svg-asset-paths.d.ts.map +1 -0
- package/dist/core/svg-asset-paths.js +107 -0
- package/dist/core/svg-asset-paths.js.map +1 -0
- package/dist/core/types.d.ts +388 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +265 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/ui-languages.d.ts +66 -0
- package/dist/core/ui-languages.d.ts.map +1 -0
- package/dist/core/ui-languages.js +277 -0
- package/dist/core/ui-languages.js.map +1 -0
- package/dist/core/user-edited-model.d.ts +3 -0
- package/dist/core/user-edited-model.d.ts.map +1 -0
- package/dist/core/user-edited-model.js +3 -0
- package/dist/core/user-edited-model.js.map +1 -0
- package/dist/edit-cache-app/app.js +1326 -0
- package/dist/edit-cache-app/index.html +287 -0
- package/dist/edit-cache-app/styles.css +664 -0
- package/dist/extractors/base-extractor.d.ts +15 -0
- package/dist/extractors/base-extractor.d.ts.map +1 -0
- package/dist/extractors/base-extractor.js +23 -0
- package/dist/extractors/base-extractor.js.map +1 -0
- package/dist/extractors/classify-segment.d.ts +6 -0
- package/dist/extractors/classify-segment.d.ts.map +1 -0
- package/dist/extractors/classify-segment.js +20 -0
- package/dist/extractors/classify-segment.js.map +1 -0
- package/dist/extractors/json-extractor.d.ts +16 -0
- package/dist/extractors/json-extractor.d.ts.map +1 -0
- package/dist/extractors/json-extractor.js +128 -0
- package/dist/extractors/json-extractor.js.map +1 -0
- package/dist/extractors/markdown-extractor.d.ts +15 -0
- package/dist/extractors/markdown-extractor.d.ts.map +1 -0
- package/dist/extractors/markdown-extractor.js +205 -0
- package/dist/extractors/markdown-extractor.js.map +1 -0
- package/dist/extractors/svg-extractor.d.ts +19 -0
- package/dist/extractors/svg-extractor.d.ts.map +1 -0
- package/dist/extractors/svg-extractor.js +132 -0
- package/dist/extractors/svg-extractor.js.map +1 -0
- package/dist/extractors/ui-string-extractor.d.ts +40 -0
- package/dist/extractors/ui-string-extractor.d.ts.map +1 -0
- package/dist/extractors/ui-string-extractor.js +146 -0
- package/dist/extractors/ui-string-extractor.js.map +1 -0
- package/dist/extractors/ui-string-locations.d.ts +23 -0
- package/dist/extractors/ui-string-locations.d.ts.map +1 -0
- package/dist/extractors/ui-string-locations.js +138 -0
- package/dist/extractors/ui-string-locations.js.map +1 -0
- package/dist/glossary/glossary.d.ts +34 -0
- package/dist/glossary/glossary.d.ts.map +1 -0
- package/dist/glossary/glossary.js +260 -0
- package/dist/glossary/glossary.js.map +1 -0
- package/dist/glossary/matcher.d.ts +10 -0
- package/dist/glossary/matcher.d.ts.map +1 -0
- package/dist/glossary/matcher.js +12 -0
- package/dist/glossary/matcher.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +44 -0
- package/dist/index.js.map +1 -0
- package/dist/processors/admonition-placeholders.d.ts +8 -0
- package/dist/processors/admonition-placeholders.d.ts.map +1 -0
- package/dist/processors/admonition-placeholders.js +59 -0
- package/dist/processors/admonition-placeholders.js.map +1 -0
- package/dist/processors/anchor-placeholders.d.ts +8 -0
- package/dist/processors/anchor-placeholders.d.ts.map +1 -0
- package/dist/processors/anchor-placeholders.js +37 -0
- package/dist/processors/anchor-placeholders.js.map +1 -0
- package/dist/processors/batch-processor.d.ts +10 -0
- package/dist/processors/batch-processor.d.ts.map +1 -0
- package/dist/processors/batch-processor.js +33 -0
- package/dist/processors/batch-processor.js.map +1 -0
- package/dist/processors/bold-code-placeholders.d.ts +14 -0
- package/dist/processors/bold-code-placeholders.d.ts.map +1 -0
- package/dist/processors/bold-code-placeholders.js +116 -0
- package/dist/processors/bold-code-placeholders.js.map +1 -0
- package/dist/processors/doc-postprocess.d.ts +51 -0
- package/dist/processors/doc-postprocess.d.ts.map +1 -0
- package/dist/processors/doc-postprocess.js +215 -0
- package/dist/processors/doc-postprocess.js.map +1 -0
- package/dist/processors/emphasis-placeholders.d.ts +6 -0
- package/dist/processors/emphasis-placeholders.d.ts.map +1 -0
- package/dist/processors/emphasis-placeholders.js +262 -0
- package/dist/processors/emphasis-placeholders.js.map +1 -0
- package/dist/processors/flat-link-rewrite.d.ts +32 -0
- package/dist/processors/flat-link-rewrite.d.ts.map +1 -0
- package/dist/processors/flat-link-rewrite.js +90 -0
- package/dist/processors/flat-link-rewrite.js.map +1 -0
- package/dist/processors/glossary-force-placeholders.d.ts +12 -0
- package/dist/processors/glossary-force-placeholders.d.ts.map +1 -0
- package/dist/processors/glossary-force-placeholders.js +58 -0
- package/dist/processors/glossary-force-placeholders.js.map +1 -0
- package/dist/processors/inline-code-placeholders.d.ts +11 -0
- package/dist/processors/inline-code-placeholders.d.ts.map +1 -0
- package/dist/processors/inline-code-placeholders.js +87 -0
- package/dist/processors/inline-code-placeholders.js.map +1 -0
- package/dist/processors/placeholder-handler.d.ts +38 -0
- package/dist/processors/placeholder-handler.d.ts.map +1 -0
- package/dist/processors/placeholder-handler.js +55 -0
- package/dist/processors/placeholder-handler.js.map +1 -0
- package/dist/processors/translation-placeholder-leaks.d.ts +2 -0
- package/dist/processors/translation-placeholder-leaks.d.ts.map +1 -0
- package/dist/processors/translation-placeholder-leaks.js +9 -0
- package/dist/processors/translation-placeholder-leaks.js.map +1 -0
- package/dist/processors/url-placeholders.d.ts +10 -0
- package/dist/processors/url-placeholders.d.ts.map +1 -0
- package/dist/processors/url-placeholders.js +29 -0
- package/dist/processors/url-placeholders.js.map +1 -0
- package/dist/processors/validator.d.ts +23 -0
- package/dist/processors/validator.d.ts.map +1 -0
- package/dist/processors/validator.js +186 -0
- package/dist/processors/validator.js.map +1 -0
- package/dist/runtime/i18next-helpers.d.ts +146 -0
- package/dist/runtime/i18next-helpers.d.ts.map +1 -0
- package/dist/runtime/i18next-helpers.js +192 -0
- package/dist/runtime/i18next-helpers.js.map +1 -0
- package/dist/runtime/index.d.ts +4 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +4 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/template.d.ts +21 -0
- package/dist/runtime/template.d.ts.map +1 -0
- package/dist/runtime/template.js +28 -0
- package/dist/runtime/template.js.map +1 -0
- package/dist/runtime/ui-language-display.d.ts +16 -0
- package/dist/runtime/ui-language-display.d.ts.map +1 -0
- package/dist/runtime/ui-language-display.js +26 -0
- package/dist/runtime/ui-language-display.js.map +1 -0
- package/dist/server/translation-editor.d.ts +25 -0
- package/dist/server/translation-editor.d.ts.map +1 -0
- package/dist/server/translation-editor.js +583 -0
- package/dist/server/translation-editor.js.map +1 -0
- package/dist/utils/concurrency.d.ts +31 -0
- package/dist/utils/concurrency.d.ts.map +1 -0
- package/dist/utils/concurrency.js +103 -0
- package/dist/utils/concurrency.js.map +1 -0
- package/dist/utils/hash.d.ts +5 -0
- package/dist/utils/hash.d.ts.map +1 -0
- package/dist/utils/hash.js +9 -0
- package/dist/utils/hash.js.map +1 -0
- package/dist/utils/ignore-parser.d.ts +7 -0
- package/dist/utils/ignore-parser.d.ts.map +1 -0
- package/dist/utils/ignore-parser.js +26 -0
- package/dist/utils/ignore-parser.js.map +1 -0
- package/dist/utils/logger.d.ts +45 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +158 -0
- package/dist/utils/logger.js.map +1 -0
- package/docs/GETTING_STARTED.md +697 -0
- package/docs/PACKAGE_OVERVIEW.md +427 -0
- package/docs/ai-i18n-tools-context.md +481 -0
- package/package.json +117 -0
- package/translated-docs/README.de.md +157 -0
- package/translated-docs/README.es.md +157 -0
- package/translated-docs/README.fr.md +157 -0
- package/translated-docs/README.hi.md +157 -0
- package/translated-docs/README.ja.md +157 -0
- package/translated-docs/README.ko.md +157 -0
- package/translated-docs/README.pt-BR.md +157 -0
- package/translated-docs/README.zh-CN.md +157 -0
- package/translated-docs/README.zh-TW.md +157 -0
- package/translated-docs/docs/GETTING_STARTED.de.md +682 -0
- package/translated-docs/docs/GETTING_STARTED.es.md +682 -0
- package/translated-docs/docs/GETTING_STARTED.fr.md +682 -0
- package/translated-docs/docs/GETTING_STARTED.hi.md +682 -0
- package/translated-docs/docs/GETTING_STARTED.ja.md +682 -0
- package/translated-docs/docs/GETTING_STARTED.ko.md +682 -0
- package/translated-docs/docs/GETTING_STARTED.pt-BR.md +682 -0
- package/translated-docs/docs/GETTING_STARTED.zh-CN.md +682 -0
- package/translated-docs/docs/GETTING_STARTED.zh-TW.md +682 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.de.md +428 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.es.md +428 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.fr.md +428 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.hi.md +428 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.ja.md +428 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.ko.md +428 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.pt-BR.md +428 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.zh-CN.md +428 -0
- package/translated-docs/docs/PACKAGE_OVERVIEW.zh-TW.md +428 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
# ai-i18n-tools: AI Agent Context
|
|
2
|
+
|
|
3
|
+
This document gives an AI agent the mental model, key decisions, and patterns needed to work effectively with `ai-i18n-tools` without consulting every other doc first. Read this before making code or config changes.
|
|
4
|
+
|
|
5
|
+
<!-- DOCTOC SKIP -->
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What this package does
|
|
10
|
+
|
|
11
|
+
`ai-i18n-tools` is a CLI + library that automates internationalization for JavaScript/TypeScript projects. It:
|
|
12
|
+
|
|
13
|
+
1. **Extracts** UI strings from source code (`t("…")` calls) into a master catalog.
|
|
14
|
+
2. **Translates** that catalog and documentation files via LLMs (through OpenRouter).
|
|
15
|
+
3. **Writes** locale-ready JSON files for i18next, plus translated markdown, Docusaurus JSON labels, and standalone SVG assets.
|
|
16
|
+
4. **Exports runtime helpers** for wiring i18next, RTL support, and language selection in any JS environment.
|
|
17
|
+
|
|
18
|
+
Everything is driven by a single config file: `ai-i18n-tools.config.json`.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Two independent workflows
|
|
23
|
+
|
|
24
|
+
| | Workflow 1 - UI Strings | Workflow 2 - Documents |
|
|
25
|
+
|---|---|---|
|
|
26
|
+
| **Input** | JS/TS source files with `t("…")` calls | `.md`, `.mdx`, Docusaurus JSON label files |
|
|
27
|
+
| **Output** | `strings.json` (catalog) + per-locale flat JSON files (`de.json`, etc.) | Translated copies of those files at configured output paths |
|
|
28
|
+
| **Cache** | `strings.json` itself (existing translations are preserved) | SQLite database (`cacheDir`) - only new/changed segments go to LLM |
|
|
29
|
+
| **Key command** | `translate-ui` | `translate-docs` |
|
|
30
|
+
| **Sync command** | `sync` | `sync` |
|
|
31
|
+
| **Feature flags** | `extractUIStrings`, `translateUIStrings` | `translateMarkdown`, `translateJSON`, `translateSVG` |
|
|
32
|
+
|
|
33
|
+
They can be used independently or together in the same config. `sync` runs, in order: `extract` (if enabled), `translate-ui` (if enabled, unless `--no-ui`), `translate-svg` when `features.translateSVG` is true and `config.svg` is set (unless `--no-svg`), then `translate-docs` (unless `--no-docs`). Standalone SVG translation requires the **`translateSVG`** feature plus the top-level **`svg`** block (paths and layout). See the [CLI cheat sheet](#cli-commands-cheat-sheet) for flags.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Config file quick reference
|
|
38
|
+
|
|
39
|
+
File: `ai-i18n-tools.config.json` (default location - override with `-c <path>`)
|
|
40
|
+
|
|
41
|
+
```json
|
|
42
|
+
{
|
|
43
|
+
"sourceLocale": "en-GB",
|
|
44
|
+
"targetLocales": "src/locales/ui-languages.json",
|
|
45
|
+
|
|
46
|
+
"openrouter": {
|
|
47
|
+
"translationModels": [
|
|
48
|
+
"qwen/qwen3-235b-a22b-2507",
|
|
49
|
+
"openai/gpt-4o-mini",
|
|
50
|
+
"deepseek/deepseek-v3.2",
|
|
51
|
+
"anthropic/claude-3-haiku",
|
|
52
|
+
"qwen/qwen3.6-plus",
|
|
53
|
+
"anthropic/claude-3.5-haiku",
|
|
54
|
+
"openai/gpt-5.3-codex",
|
|
55
|
+
"anthropic/claude-sonnet-4.6",
|
|
56
|
+
"google/gemini-3-flash-preview"
|
|
57
|
+
],
|
|
58
|
+
"maxTokens": 8192,
|
|
59
|
+
"temperature": 0.2
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
"features": {
|
|
63
|
+
"extractUIStrings": true,
|
|
64
|
+
"translateUIStrings": true,
|
|
65
|
+
"translateMarkdown": true,
|
|
66
|
+
"translateJSON": false,
|
|
67
|
+
"translateSVG": true
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
"ui": {
|
|
71
|
+
"sourceRoots": ["src/"],
|
|
72
|
+
"stringsJson": "src/locales/strings.json",
|
|
73
|
+
"flatOutputDir": "src/locales/",
|
|
74
|
+
"preferredModel": "anthropic/claude-3.5-haiku",
|
|
75
|
+
"reactExtractor": {
|
|
76
|
+
"funcNames": ["t", "i18n.t"],
|
|
77
|
+
"extensions": [".js", ".jsx", ".ts", ".tsx"]
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
"cacheDir": ".translation-cache",
|
|
82
|
+
"documentations": [
|
|
83
|
+
{
|
|
84
|
+
"contentPaths": ["docs/"],
|
|
85
|
+
"outputDir": "i18n/",
|
|
86
|
+
"targetLocales": ["de", "fr"],
|
|
87
|
+
"jsonSource": "i18n/en",
|
|
88
|
+
"markdownOutput": {
|
|
89
|
+
"style": "docusaurus",
|
|
90
|
+
"docsRoot": "docs"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
],
|
|
94
|
+
|
|
95
|
+
"svg": {
|
|
96
|
+
"sourcePath": "images",
|
|
97
|
+
"outputDir": "public/assets",
|
|
98
|
+
"style": "flat"
|
|
99
|
+
},
|
|
100
|
+
|
|
101
|
+
"glossary": {
|
|
102
|
+
"uiGlossary": "src/locales/strings.json",
|
|
103
|
+
"userGlossary": "glossary-user.csv"
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Key constraints
|
|
109
|
+
|
|
110
|
+
- `sourceLocale` **must exactly match** the `SOURCE_LOCALE` constant exported from the runtime i18n setup file (`src/i18n.ts` / `src/i18n.js`).
|
|
111
|
+
- `targetLocales` can be a string path to a `ui-languages.json` manifest OR an array of BCP-47 codes.
|
|
112
|
+
- `uiLanguagesPath` is optional, but useful when `targetLocales` is an explicit array and you still want manifest-driven labels and locale filtering.
|
|
113
|
+
- `documentations[].description` is optional text for maintainers (what the block is for); it does not affect translation. When set, it is included in the `translate-docs` headline and `status` headers.
|
|
114
|
+
- `documentations[].targetLocales` limits that block to a subset; effective documentation locales are the **union** across blocks (useful when different trees need different locale sets).
|
|
115
|
+
- `documentations[].markdownOutput.postProcessing` can adjust translated markdown after reassembly, for example by rewriting screenshot paths or rebuilding a language list block.
|
|
116
|
+
- All paths are relative to cwd (where the CLI is invoked).
|
|
117
|
+
- `OPENROUTER_API_KEY` must be set in the environment or a `.env` file.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## The `ui-languages.json` manifest
|
|
122
|
+
|
|
123
|
+
When `targetLocales` is a file path, that file must be a JSON array of this shape:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
[
|
|
127
|
+
{ "code": "en-GB", "label": "English (UK)", "englishName": "English (UK)" },
|
|
128
|
+
{ "code": "de", "label": "Deutsch", "englishName": "German" },
|
|
129
|
+
{ "code": "ar", "label": "العربية", "englishName": "Arabic" }
|
|
130
|
+
]
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
- `code` - BCP-47 locale code used in file names and by i18next.
|
|
134
|
+
- `label` - native name shown in language pickers.
|
|
135
|
+
- `englishName` - English name used for display helpers and translation prompts.
|
|
136
|
+
|
|
137
|
+
This file drives both the translation pipeline and the runtime language-switcher UI. Keep it as the single source of truth for supported locales.
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## CLI commands cheat sheet
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
npx ai-i18n-tools init [-t ui-markdown|ui-docusaurus]
|
|
145
|
+
Write a starter config file. ui-markdown = React/UI-only template.
|
|
146
|
+
ui-docusaurus = combined UI + docs template.
|
|
147
|
+
|
|
148
|
+
npx ai-i18n-tools extract
|
|
149
|
+
Scan source for t("…") calls, write/merge strings.json.
|
|
150
|
+
Safe to re-run - preserves existing translations.
|
|
151
|
+
|
|
152
|
+
npx ai-i18n-tools translate-ui [--locale <code>] [--force] [--dry-run] [-j <n>]
|
|
153
|
+
Translate UI strings only. Reads strings.json, writes flatOutputDir/de.json etc.
|
|
154
|
+
--force: re-translate all entries per locale. --dry-run: no writes, no API calls. -j: max parallel locales.
|
|
155
|
+
|
|
156
|
+
npx ai-i18n-tools translate-docs [--locale <code>] [--force | --force-update] …
|
|
157
|
+
Translate markdown and JSON under documentation paths. Default: skip unchanged files + use segment SQLite cache.
|
|
158
|
+
--force-update: re-run every file output; segment cache still used (no API for unchanged text).
|
|
159
|
+
--force: clear file tracking and ignore segment cache reads (full re-translation); new results still write to cache.
|
|
160
|
+
--stats: print cache stats and exit. --clear-cache [locale]: wipe cache (all or one locale) and exit.
|
|
161
|
+
--prompt-format xml|json-array|json-object: batch wire format to the model (default xml); does not change validation or cache.
|
|
162
|
+
Do not combine --force with --force-update (when the docs step runs).
|
|
163
|
+
|
|
164
|
+
npx ai-i18n-tools translate-svg [--locale <code>] [--force | --force-update] [--no-cache] …
|
|
165
|
+
Standalone SVG assets from config.svg. Requires features.translateSVG. --no-cache: skip SQLite reads/writes for this run only.
|
|
166
|
+
|
|
167
|
+
npx ai-i18n-tools sync [--locale <code>] [--force | --force-update] [--no-ui] [--no-svg] [--no-docs] …
|
|
168
|
+
extract (if enabled), translate-ui (unless --no-ui), translate-svg when features.translateSVG and config.svg (unless --no-svg),
|
|
169
|
+
translate-docs (unless --no-docs). --force / --force-update apply to the docs step only; if --no-docs, both can be passed without conflict.
|
|
170
|
+
|
|
171
|
+
npx ai-i18n-tools status
|
|
172
|
+
Show markdown translation coverage per file × locale.
|
|
173
|
+
|
|
174
|
+
npx ai-i18n-tools editor
|
|
175
|
+
Launch a local web editor for the SQLite cache, strings.json, and glossary.
|
|
176
|
+
|
|
177
|
+
npx ai-i18n-tools cleanup [--dry-run] [--no-backup] [--backup <path>]
|
|
178
|
+
Runs sync --force-update first, then maintains the SQLite cache: stale segment rows; orphaned file_tracking keys (doc-block:, svg-assets:, …);
|
|
179
|
+
orphaned translation rows whose filepath metadata points at a missing file.
|
|
180
|
+
Backs up cache.db under the cache dir before modifications unless --no-backup.
|
|
181
|
+
|
|
182
|
+
npx ai-i18n-tools glossary-generate
|
|
183
|
+
Write an empty glossary-user.csv template.
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Global flags: `-c <config>` (config path), `-v` (verbose/debug output), `-w` / `--write-logs [path]` (tee console output to a log file; default path: under `cacheDir`).
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## Workflow 1 - UI strings: how data flows
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
source files (JS/TS)
|
|
194
|
+
│ i18next-scanner Parser finds t("literal") and i18n.t("literal")
|
|
195
|
+
▼
|
|
196
|
+
strings.json - master catalog
|
|
197
|
+
{
|
|
198
|
+
"<md5-8-hex>": {
|
|
199
|
+
"source": "The English string",
|
|
200
|
+
"translated": { "de": "Der deutsche Text", "pt-BR": "O texto em português" },
|
|
201
|
+
"models": { "de": "…", "pt-BR": "…" }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
│ translate-ui reads this, sends batches to OpenRouter, fills missing locales and records model ids per locale
|
|
205
|
+
▼
|
|
206
|
+
src/locales/de.json - flat map: source string → translation
|
|
207
|
+
{ "The English string": "Der deutsche Text", "Save": "Speichern" }
|
|
208
|
+
src/locales/pt-BR.json
|
|
209
|
+
...
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
**Only literal strings are extractable.** Variables, expressions, or template literals as the key are not found:
|
|
213
|
+
|
|
214
|
+
```js
|
|
215
|
+
t('Save') // ✓ extracted
|
|
216
|
+
t('Hello {{name}}', {name}) // ✓ extracted as "Hello {{name}}"
|
|
217
|
+
t(labelVar) // ✗ not extracted - variable key
|
|
218
|
+
t(`Hello ${name}`) // ✗ not extracted - template literal
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
i18next uses the key-as-default model: missing translations fall back to the key itself (the English source string). The `parseMissingKeyHandler` in `defaultI18nInitOptions` handles this.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Workflow 2 - Document translation: how data flows
|
|
226
|
+
|
|
227
|
+
```
|
|
228
|
+
source files (md/mdx/json)
|
|
229
|
+
│ Extractor produces typed segments with SHA-256 hash
|
|
230
|
+
▼
|
|
231
|
+
PlaceholderHandler - replaces URLs, admonitions, anchors with opaque tokens
|
|
232
|
+
▼
|
|
233
|
+
TranslationCache lookup (SQLite)
|
|
234
|
+
│ cache hit → use stored translation
|
|
235
|
+
│ cache miss → send batch to OpenRouter
|
|
236
|
+
▼
|
|
237
|
+
PlaceholderHandler.restore - tokens replaced back with original syntax
|
|
238
|
+
▼
|
|
239
|
+
resolveDocumentationOutputPath → write to output file
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
**Cache key**: SHA-256 first 16 hex chars of whitespace-normalized segment content × locale. The cache lives under root `cacheDir` (a `cache.db` SQLite file), shared by all `documentations` blocks. Each row stores the `model` that last translated the segment; saving an edit in the `editor` sets `model` to `user-edited` (same sentinel as UI `strings.json` `models`).
|
|
243
|
+
|
|
244
|
+
**CLI**: `--force-update` bypasses only the *file-level* skip (rebuild outputs) while still using segment cache. `--force` clears per-file tracking and skips segment cache reads for API calls. See the getting started guide for the full flag table.
|
|
245
|
+
|
|
246
|
+
**Standalone SVGs**: handled by `translate-svg` when `features.translateSVG` is true and the top-level `svg` config block is set. They use the same OpenRouter/cache ideas, but not the `documentations` pipeline.
|
|
247
|
+
|
|
248
|
+
**Output styles** (`markdownOutput.style`):
|
|
249
|
+
|
|
250
|
+
| Style | Example |
|
|
251
|
+
|---|---|
|
|
252
|
+
| `"nested"` (default) | `docs/guide.md` → `i18n/de/docs/guide.md` |
|
|
253
|
+
| `"docusaurus"` | `docs/guide.md` → `i18n/de/docusaurus-plugin-content-docs/current/guide.md` |
|
|
254
|
+
| `"flat"` | `docs/guide.md` → `i18n/guide.de.md` |
|
|
255
|
+
| custom `pathTemplate` | any layout using `{outputDir}`, `{locale}`, `{LOCALE}`, `{relPath}`, `{stem}`, `{basename}`, `{extension}`, `{docsRoot}`, `{relativeToDocsRoot}` |
|
|
256
|
+
|
|
257
|
+
Flat-style output auto-rewrites relative links between pages (e.g. `[Guide](./guide.md)` → `guide.de.md`).
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## Runtime integration - wiring i18next
|
|
262
|
+
|
|
263
|
+
The package exports helpers from `'ai-i18n-tools/runtime'` that remove boilerplate. The minimal setup:
|
|
264
|
+
|
|
265
|
+
```ts
|
|
266
|
+
// src/i18n.ts - import this at the top of your entry point
|
|
267
|
+
import i18n from 'i18next';
|
|
268
|
+
import { initReactI18next } from 'react-i18next';
|
|
269
|
+
import uiLanguages from './locales/ui-languages.json';
|
|
270
|
+
import {
|
|
271
|
+
defaultI18nInitOptions,
|
|
272
|
+
wrapI18nWithKeyTrim,
|
|
273
|
+
makeLoadLocale,
|
|
274
|
+
applyDirection,
|
|
275
|
+
} from 'ai-i18n-tools/runtime';
|
|
276
|
+
|
|
277
|
+
// Must match sourceLocale in ai-i18n-tools.config.json exactly
|
|
278
|
+
export const SOURCE_LOCALE = 'en-GB';
|
|
279
|
+
|
|
280
|
+
void i18n.use(initReactI18next).init(defaultI18nInitOptions(SOURCE_LOCALE));
|
|
281
|
+
wrapI18nWithKeyTrim(i18n);
|
|
282
|
+
i18n.on('languageChanged', applyDirection);
|
|
283
|
+
applyDirection(i18n.language);
|
|
284
|
+
|
|
285
|
+
// Dynamic imports for non-source locales
|
|
286
|
+
const localeLoaders = Object.fromEntries(
|
|
287
|
+
uiLanguages
|
|
288
|
+
.filter(({ code }) => code !== SOURCE_LOCALE)
|
|
289
|
+
.map(({ code }) => [code, () => import(`./locales/${code}.json`)])
|
|
290
|
+
);
|
|
291
|
+
|
|
292
|
+
export const loadLocale = makeLoadLocale(i18n, localeLoaders, SOURCE_LOCALE);
|
|
293
|
+
export default i18n;
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
**Loading a locale on demand** (e.g. when user switches language):
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
await loadLocale(code);
|
|
300
|
+
i18n.changeLanguage(code);
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
`loadLocale` is a no-op for the source locale - it only fetches non-source locales.
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## Runtime helpers reference
|
|
308
|
+
|
|
309
|
+
All exported from `'ai-i18n-tools/runtime'`. Work in any JS environment (browser, Node.js, Edge, Deno). No i18next peer dependency required.
|
|
310
|
+
|
|
311
|
+
| Export | Signature | Purpose |
|
|
312
|
+
|---|---|---|
|
|
313
|
+
| `defaultI18nInitOptions` | `(sourceLocale?: string) => i18nextInitOptions` | Standard i18next init for key-as-default setup |
|
|
314
|
+
| `wrapI18nWithKeyTrim` | `(i18n: I18nLike) => void` | Trim keys before lookup and apply `{{var}}` interpolation for the source locale (where `parseMissingKeyHandler` returns the raw key) |
|
|
315
|
+
| `makeLoadLocale` | `(i18n, loaders, sourceLocale?) => (lang: string) => Promise<void>` | Factory for async locale loading |
|
|
316
|
+
| `getTextDirection` | `(lng: string) => 'ltr' \| 'rtl'` | RTL detection by BCP-47 code |
|
|
317
|
+
| `applyDirection` | `(lng: string, element?: Element) => void` | Set `dir` on `document.documentElement` (no-op in Node.js) |
|
|
318
|
+
| `getUILanguageLabel` | `(lang: UiLanguageEntry, t: TranslateFn) => string` | Translated label for settings-page dropdowns |
|
|
319
|
+
| `getUILanguageLabelNative` | `(lang: UiLanguageEntry) => string` | Native label for header menus (no `t()` call) |
|
|
320
|
+
| `interpolateTemplate` | `(str: string, vars: Record<string, string \| number \| boolean>) => string` | Low-level `{{var}}` substitution on a plain string (used internally by `wrapI18nWithKeyTrim`; rarely needed in app code) |
|
|
321
|
+
| `flipUiArrowsForRtl` | `(text, isRtl: boolean) => string` | Flip `→` to `←` for RTL layouts |
|
|
322
|
+
| `RTL_LANGS` | `ReadonlySet<string>` | Set of BCP-47 codes treated as RTL |
|
|
323
|
+
|
|
324
|
+
---
|
|
325
|
+
|
|
326
|
+
## Programmatic API
|
|
327
|
+
|
|
328
|
+
Import from `'ai-i18n-tools'`. Useful when you need to call translation steps from a build script or CI pipeline.
|
|
329
|
+
|
|
330
|
+
```ts
|
|
331
|
+
import {
|
|
332
|
+
loadI18nConfigFromFile,
|
|
333
|
+
runTranslateUI,
|
|
334
|
+
} from 'ai-i18n-tools';
|
|
335
|
+
|
|
336
|
+
const config = loadI18nConfigFromFile('ai-i18n-tools.config.json');
|
|
337
|
+
const summary = await runTranslateUI(config, {
|
|
338
|
+
cwd: process.cwd(),
|
|
339
|
+
locales: config.targetLocales,
|
|
340
|
+
force: false,
|
|
341
|
+
dryRun: false,
|
|
342
|
+
verbose: false,
|
|
343
|
+
});
|
|
344
|
+
// summary.stringsUpdated - number of newly translated strings
|
|
345
|
+
// summary.localesTouched - locale codes processed
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
Other useful exports for custom pipelines:
|
|
349
|
+
|
|
350
|
+
| Export | Use when |
|
|
351
|
+
|---|---|
|
|
352
|
+
| `loadI18nConfigFromFile(path, cwd?)` | Load and validate the config |
|
|
353
|
+
| `parseI18nConfig(rawObject)` | Validate a config object you built in code |
|
|
354
|
+
| `TranslationCache` | Direct SQLite cache access |
|
|
355
|
+
| `UIStringExtractor` | Extract `t("…")` calls from JS/TS files |
|
|
356
|
+
| `MarkdownExtractor` | Parse markdown into translatable segments |
|
|
357
|
+
| `JsonExtractor` | Parse Docusaurus JSON label files |
|
|
358
|
+
| `SvgExtractor` | Parse SVG text elements |
|
|
359
|
+
| `OpenRouterClient` | Make translation requests directly |
|
|
360
|
+
| `PlaceholderHandler` | Protect/restore markdown syntax around translation |
|
|
361
|
+
| `splitTranslatableIntoBatches` | Group segments into LLM-sized batches |
|
|
362
|
+
| `validateTranslation` | Structural checks after a translation call |
|
|
363
|
+
| `resolveDocumentationOutputPath` | Compute the output file path for a translated document |
|
|
364
|
+
| `Glossary` / `GlossaryMatcher` | Load and apply a translation glossary |
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## Glossary
|
|
369
|
+
|
|
370
|
+
The glossary ensures consistent terminology across translations.
|
|
371
|
+
|
|
372
|
+
- **Auto-built glossary** (`glossary.uiGlossary`): reads `strings.json` and uses existing translations as a hint source. No CSV needed.
|
|
373
|
+
- **User glossary** (`glossary.userGlossary`): a CSV file with columns `Original language string`, `locale`, `Translation` (or `en`, `locale`, `Translation`). Generate an empty template with `npx ai-i18n-tools glossary-generate`.
|
|
374
|
+
|
|
375
|
+
Glossary hints are injected into the LLM system prompt - they are suggestions, not hard replacements.
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## Extension points
|
|
380
|
+
|
|
381
|
+
### Custom function names
|
|
382
|
+
|
|
383
|
+
```json
|
|
384
|
+
{ "ui": { "reactExtractor": { "funcNames": ["t", "i18n.t", "translate"] } } }
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
### Custom extractor
|
|
388
|
+
|
|
389
|
+
```ts
|
|
390
|
+
import { BaseExtractor, type Segment } from 'ai-i18n-tools';
|
|
391
|
+
|
|
392
|
+
class MyExtractor extends BaseExtractor {
|
|
393
|
+
readonly name = 'my-format';
|
|
394
|
+
canHandle(filepath: string) { return filepath.endsWith('.myext'); }
|
|
395
|
+
extract(content: string): Segment[] { /* return typed segments */ }
|
|
396
|
+
reassemble(segments: Segment[], translations: Map<string, string>): string { /* rebuild file */ }
|
|
397
|
+
}
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
### Custom output path
|
|
401
|
+
|
|
402
|
+
```json
|
|
403
|
+
{
|
|
404
|
+
"documentations": [
|
|
405
|
+
{
|
|
406
|
+
"markdownOutput": {
|
|
407
|
+
"pathTemplate": "{outputDir}/{locale}/{relativeToDocsRoot}"
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
]
|
|
411
|
+
}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
Available placeholders: `{outputDir}`, `{locale}`, `{LOCALE}`, `{relPath}`, `{stem}`, `{basename}`, `{extension}`, `{docsRoot}`, `{relativeToDocsRoot}`.
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## Common tasks and what to do
|
|
419
|
+
|
|
420
|
+
| Task | What to run / change |
|
|
421
|
+
|---|---|
|
|
422
|
+
| Add a new locale | Add it to `ui-languages.json` (or `targetLocales` array), then run `translate-docs` / `translate-ui` / `sync` |
|
|
423
|
+
| Translate only one locale | `npx ai-i18n-tools translate-docs --locale de` (or `translate-ui`, `sync`) |
|
|
424
|
+
| Add a new UI string | Write `t('My new string')` in source, then run `extract` then `translate-ui` |
|
|
425
|
+
| Update a translation manually | Edit `strings.json` directly (`translated`), or use `editor` (sets `models[locale]` to `user-edited`). `translate-ui` skips locales that already have text unless you use `--force` |
|
|
426
|
+
| Translate new/updated docs only | Run `translate-docs` - file + segment cache skips unchanged work automatically |
|
|
427
|
+
| Rebuild doc outputs without re-calling the API for unchanged segments | `npx ai-i18n-tools sync --force-update` |
|
|
428
|
+
| Full doc re-translation (ignore segment cache) | `npx ai-i18n-tools translate-docs --force` |
|
|
429
|
+
| Free up cache space | `npx ai-i18n-tools cleanup` or `translate-docs --clear-cache` |
|
|
430
|
+
| Inspect what is untranslated | `npx ai-i18n-tools status` |
|
|
431
|
+
| Change the translation model | Edit `openrouter.translationModels` (first is primary, rest are fallbacks). For **UI only**, optional `ui.preferredModel` is tried before that list. |
|
|
432
|
+
| Wire i18next in a new project | See [Runtime integration](#runtime-integration---wiring-i18next) above |
|
|
433
|
+
| Translate docs to fewer locales than UI | Set `documentations[].targetLocales` on the relevant block(s), or use a smaller union |
|
|
434
|
+
| Run extract + UI + SVG + docs in one command | `npx ai-i18n-tools sync` (SVG runs when `features.translateSVG` and `svg` are set) - use `--no-ui`, `--no-svg`, or `--no-docs` to skip a stage (e.g. UI + SVG only: `--no-docs`) |
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
## Environment variables
|
|
439
|
+
|
|
440
|
+
| Variable | Effect |
|
|
441
|
+
|---|---|
|
|
442
|
+
| `OPENROUTER_API_KEY` | **Required.** Your OpenRouter API key. |
|
|
443
|
+
| `OPENROUTER_BASE_URL` | Override the API base URL. |
|
|
444
|
+
| `I18N_SOURCE_LOCALE` | Override `sourceLocale` at runtime. |
|
|
445
|
+
| `I18N_TARGET_LOCALES` | Comma-separated locale codes to override `targetLocales`. |
|
|
446
|
+
| `I18N_LOG_LEVEL` | Logger level (`debug`, `info`, `warn`, `error`, `silent`). |
|
|
447
|
+
| `NO_COLOR` | When `1`, disable ANSI colours in log output. |
|
|
448
|
+
| `I18N_LOG_SESSION_MAX` | Max lines kept per log session (default `5000`). |
|
|
449
|
+
|
|
450
|
+
---
|
|
451
|
+
|
|
452
|
+
## Files generated / maintained by the tool
|
|
453
|
+
|
|
454
|
+
| File | Owned by | Notes |
|
|
455
|
+
|---|---|---|
|
|
456
|
+
| `ai-i18n-tools.config.json` | You | Main config. Edit manually. |
|
|
457
|
+
| `ui-languages.json` (wherever configured) | You | Locale manifest. Edit manually to add/remove locales. |
|
|
458
|
+
| `strings.json` (wherever configured) | Tool (`extract` / `translate-ui` / `editor`) | Master UI catalog: `source`, `translated`, optional `models` (per locale: OpenRouter model id or `user-edited`), optional `locations`. Safe to edit `translated`; do not rename keys. |
|
|
459
|
+
| `{flatOutputDir}/de.json`, etc. | Tool (`translate-ui`) | Per-locale flat maps (source → translation only, no `models`). Do not edit — regenerated on each `translate-ui`. |
|
|
460
|
+
| `{cacheDir}/*.db` | Tool | SQLite translation cache (per-segment `model` metadata; `user-edited` after manual saves in `editor`). Do not edit directly; use `editor` or `cleanup`. |
|
|
461
|
+
| `glossary-user.csv` | You | Term overrides. Generate template with `glossary-generate`. |
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
465
|
+
## Source layout summary
|
|
466
|
+
|
|
467
|
+
```
|
|
468
|
+
src/
|
|
469
|
+
├── index.ts Public API (all programmatic exports)
|
|
470
|
+
├── cli/ CLI command implementations
|
|
471
|
+
├── core/ Config loading, types (Zod), SQLite cache, prompt builder, output paths
|
|
472
|
+
├── extractors/ Segment extractors: JS/TS, Markdown, JSON, SVG
|
|
473
|
+
├── processors/ Placeholder protection, batch splitting, post-translation validation, link rewriting
|
|
474
|
+
├── api/openrouter.ts HTTP client for OpenRouter with model fallback and rate-limit handling
|
|
475
|
+
├── glossary/ Glossary loading (CSV + auto from strings.json) and term matching
|
|
476
|
+
├── runtime/ i18next helpers, RTL helpers, display helpers (no i18next import)
|
|
477
|
+
├── server/ Local Express web editor for cache/glossary
|
|
478
|
+
└── utils/ Logger, SHA-256 hash, .translate-ignore parser
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
The entry point for all public types and functions is `src/index.ts`.
|
package/package.json
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ai-i18n-tools",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Unified internationalization toolkit for Node.js apps and documentation with AI translation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./runtime": {
|
|
15
|
+
"types": "./dist/runtime/index.d.ts",
|
|
16
|
+
"import": "./dist/runtime/index.js",
|
|
17
|
+
"default": "./dist/runtime/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"ai-i18n-tools": "dist/cli/index.js"
|
|
22
|
+
},
|
|
23
|
+
"files": [
|
|
24
|
+
"dist/",
|
|
25
|
+
"README.md",
|
|
26
|
+
"docs/",
|
|
27
|
+
"translated-docs/",
|
|
28
|
+
"LICENSE"
|
|
29
|
+
],
|
|
30
|
+
"keywords": [
|
|
31
|
+
"i18n",
|
|
32
|
+
"internationalization",
|
|
33
|
+
"translation",
|
|
34
|
+
"react",
|
|
35
|
+
"docusaurus",
|
|
36
|
+
"openrouter",
|
|
37
|
+
"localization",
|
|
38
|
+
"multilingual",
|
|
39
|
+
"cache",
|
|
40
|
+
"cli"
|
|
41
|
+
],
|
|
42
|
+
"author": "Waldemar Scudeller Jr.",
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"repository": {
|
|
45
|
+
"type": "git",
|
|
46
|
+
"url": "git+https://github.com/wsj-br/ai-i18n-tools.git"
|
|
47
|
+
},
|
|
48
|
+
"bugs": {
|
|
49
|
+
"url": "https://github.com/wsj-br/ai-i18n-tools/issues"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/wsj-br/ai-i18n-tools#readme",
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"chalk": "^5.6.2",
|
|
54
|
+
"commander": "^14.0.3",
|
|
55
|
+
"csv-parse": "^6.2.1",
|
|
56
|
+
"express": "^5.2.1",
|
|
57
|
+
"gray-matter-es": "^0.2.1",
|
|
58
|
+
"i18next-scanner": "^4.6.0",
|
|
59
|
+
"ignore": "^7.0.5",
|
|
60
|
+
"mdast-util-from-markdown": "^2.0.3",
|
|
61
|
+
"mdast-util-gfm": "^3.1.0",
|
|
62
|
+
"micromark-extension-gfm": "^3.0.0",
|
|
63
|
+
"unist-util-visit": "^5.1.0",
|
|
64
|
+
"zod": "^4.3.6"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@eslint/js": "^10.0.1",
|
|
68
|
+
"@types/express": "^5.0.6",
|
|
69
|
+
"@types/mdast": "^4.0.4",
|
|
70
|
+
"@types/node": "^25.6.0",
|
|
71
|
+
"@types/unist": "^3.0.3",
|
|
72
|
+
"@vitest/coverage-v8": "^4.1.4",
|
|
73
|
+
"eslint": "^10.2.0",
|
|
74
|
+
"github-slugger": "^2.0.0",
|
|
75
|
+
"globals": "^17.4.0",
|
|
76
|
+
"prettier": "^3.8.2",
|
|
77
|
+
"typescript": "^6.0.2",
|
|
78
|
+
"typescript-eslint": "^8.58.1",
|
|
79
|
+
"vitest": "^4.1.4"
|
|
80
|
+
},
|
|
81
|
+
"peerDependencies": {
|
|
82
|
+
"react": ">=16.8.0"
|
|
83
|
+
},
|
|
84
|
+
"peerDependenciesMeta": {
|
|
85
|
+
"react": {
|
|
86
|
+
"optional": true
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"engines": {
|
|
90
|
+
"node": ">=22.16.0",
|
|
91
|
+
"pnpm": ">=10.33.0"
|
|
92
|
+
},
|
|
93
|
+
"publishConfig": {
|
|
94
|
+
"access": "public"
|
|
95
|
+
},
|
|
96
|
+
"overrides": {
|
|
97
|
+
"glob": "^13.0.6",
|
|
98
|
+
"test-exclude": "^8.0.0"
|
|
99
|
+
},
|
|
100
|
+
"scripts": {
|
|
101
|
+
"build": "tsc && node scripts/copy-edit-cache-app.mjs",
|
|
102
|
+
"dev": "node scripts/copy-edit-cache-app.mjs && tsc --watch",
|
|
103
|
+
"test": "vitest run --coverage",
|
|
104
|
+
"test:watch": "vitest",
|
|
105
|
+
"lint": "eslint .",
|
|
106
|
+
"lint:fix": "eslint . --fix",
|
|
107
|
+
"format": "prettier --write \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
108
|
+
"format:check": "prettier --check \"src/**/*.ts\" \"tests/**/*.ts\"",
|
|
109
|
+
"clean": "rm -rf dist/",
|
|
110
|
+
"i18n:extract": "ai-i18n-tools extract",
|
|
111
|
+
"i18n:sync": "ai-i18n-tools sync",
|
|
112
|
+
"i18n:translate": "ai-i18n-tools translate-docs",
|
|
113
|
+
"i18n:cleanup": "ai-i18n-tools cleanup",
|
|
114
|
+
"update-all": "pnpm build && ai-i18n-tools cleanup && cd examples/console-app && ai-i18n-tools cleanup && cd ../nextjs-app && ai-i18n-tools cleanup",
|
|
115
|
+
"clean-temp": "find . \\( -name '*.log' -o -name 'cache.db.backup*.sqlite' \\) -print && read -p '\nDelete these files? (y/n) ' ans && [ \"$ans\" = \"y\" ] && find . \\( -name '*.log' -o -name 'cache.db.backup*.sqlite' \\) -delete"
|
|
116
|
+
}
|
|
117
|
+
}
|