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.
Files changed (260) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +157 -0
  3. package/dist/api/openrouter.d.ts +115 -0
  4. package/dist/api/openrouter.d.ts.map +1 -0
  5. package/dist/api/openrouter.js +399 -0
  6. package/dist/api/openrouter.js.map +1 -0
  7. package/dist/cli/doc-translate.d.ts +90 -0
  8. package/dist/cli/doc-translate.d.ts.map +1 -0
  9. package/dist/cli/doc-translate.js +1153 -0
  10. package/dist/cli/doc-translate.js.map +1 -0
  11. package/dist/cli/export-ui-xliff.d.ts +32 -0
  12. package/dist/cli/export-ui-xliff.d.ts.map +1 -0
  13. package/dist/cli/export-ui-xliff.js +153 -0
  14. package/dist/cli/export-ui-xliff.js.map +1 -0
  15. package/dist/cli/extract-strings.d.ts +12 -0
  16. package/dist/cli/extract-strings.d.ts.map +1 -0
  17. package/dist/cli/extract-strings.js +80 -0
  18. package/dist/cli/extract-strings.js.map +1 -0
  19. package/dist/cli/file-utils.d.ts +10 -0
  20. package/dist/cli/file-utils.d.ts.map +1 -0
  21. package/dist/cli/file-utils.js +77 -0
  22. package/dist/cli/file-utils.js.map +1 -0
  23. package/dist/cli/format.d.ts +21 -0
  24. package/dist/cli/format.d.ts.map +1 -0
  25. package/dist/cli/format.js +75 -0
  26. package/dist/cli/format.js.map +1 -0
  27. package/dist/cli/helpers.d.ts +27 -0
  28. package/dist/cli/helpers.d.ts.map +1 -0
  29. package/dist/cli/helpers.js +84 -0
  30. package/dist/cli/helpers.js.map +1 -0
  31. package/dist/cli/index.d.ts +3 -0
  32. package/dist/cli/index.d.ts.map +1 -0
  33. package/dist/cli/index.js +772 -0
  34. package/dist/cli/index.js.map +1 -0
  35. package/dist/cli/log-output.d.ts +13 -0
  36. package/dist/cli/log-output.d.ts.map +1 -0
  37. package/dist/cli/log-output.js +75 -0
  38. package/dist/cli/log-output.js.map +1 -0
  39. package/dist/cli/translate-svg.d.ts +7 -0
  40. package/dist/cli/translate-svg.d.ts.map +1 -0
  41. package/dist/cli/translate-svg.js +167 -0
  42. package/dist/cli/translate-svg.js.map +1 -0
  43. package/dist/cli/translate-ui-strings.d.ts +27 -0
  44. package/dist/cli/translate-ui-strings.d.ts.map +1 -0
  45. package/dist/cli/translate-ui-strings.js +357 -0
  46. package/dist/cli/translate-ui-strings.js.map +1 -0
  47. package/dist/core/cache-tracking-keys.d.ts +12 -0
  48. package/dist/core/cache-tracking-keys.d.ts.map +1 -0
  49. package/dist/core/cache-tracking-keys.js +20 -0
  50. package/dist/core/cache-tracking-keys.js.map +1 -0
  51. package/dist/core/cache.d.ts +153 -0
  52. package/dist/core/cache.d.ts.map +1 -0
  53. package/dist/core/cache.js +546 -0
  54. package/dist/core/cache.js.map +1 -0
  55. package/dist/core/config.d.ts +58 -0
  56. package/dist/core/config.d.ts.map +1 -0
  57. package/dist/core/config.js +392 -0
  58. package/dist/core/config.js.map +1 -0
  59. package/dist/core/doc-file-tracking.d.ts +8 -0
  60. package/dist/core/doc-file-tracking.d.ts.map +1 -0
  61. package/dist/core/doc-file-tracking.js +27 -0
  62. package/dist/core/doc-file-tracking.js.map +1 -0
  63. package/dist/core/errors.d.ts +19 -0
  64. package/dist/core/errors.d.ts.map +1 -0
  65. package/dist/core/errors.js +23 -0
  66. package/dist/core/errors.js.map +1 -0
  67. package/dist/core/locale-utils.d.ts +20 -0
  68. package/dist/core/locale-utils.d.ts.map +1 -0
  69. package/dist/core/locale-utils.js +75 -0
  70. package/dist/core/locale-utils.js.map +1 -0
  71. package/dist/core/output-paths.d.ts +22 -0
  72. package/dist/core/output-paths.d.ts.map +1 -0
  73. package/dist/core/output-paths.js +130 -0
  74. package/dist/core/output-paths.js.map +1 -0
  75. package/dist/core/prompt-builder.d.ts +62 -0
  76. package/dist/core/prompt-builder.d.ts.map +1 -0
  77. package/dist/core/prompt-builder.js +232 -0
  78. package/dist/core/prompt-builder.js.map +1 -0
  79. package/dist/core/prompts.d.ts +27 -0
  80. package/dist/core/prompts.d.ts.map +1 -0
  81. package/dist/core/prompts.js +57 -0
  82. package/dist/core/prompts.js.map +1 -0
  83. package/dist/core/svg-asset-paths.d.ts +40 -0
  84. package/dist/core/svg-asset-paths.d.ts.map +1 -0
  85. package/dist/core/svg-asset-paths.js +107 -0
  86. package/dist/core/svg-asset-paths.js.map +1 -0
  87. package/dist/core/types.d.ts +388 -0
  88. package/dist/core/types.d.ts.map +1 -0
  89. package/dist/core/types.js +265 -0
  90. package/dist/core/types.js.map +1 -0
  91. package/dist/core/ui-languages.d.ts +66 -0
  92. package/dist/core/ui-languages.d.ts.map +1 -0
  93. package/dist/core/ui-languages.js +277 -0
  94. package/dist/core/ui-languages.js.map +1 -0
  95. package/dist/core/user-edited-model.d.ts +3 -0
  96. package/dist/core/user-edited-model.d.ts.map +1 -0
  97. package/dist/core/user-edited-model.js +3 -0
  98. package/dist/core/user-edited-model.js.map +1 -0
  99. package/dist/edit-cache-app/app.js +1326 -0
  100. package/dist/edit-cache-app/index.html +287 -0
  101. package/dist/edit-cache-app/styles.css +664 -0
  102. package/dist/extractors/base-extractor.d.ts +15 -0
  103. package/dist/extractors/base-extractor.d.ts.map +1 -0
  104. package/dist/extractors/base-extractor.js +23 -0
  105. package/dist/extractors/base-extractor.js.map +1 -0
  106. package/dist/extractors/classify-segment.d.ts +6 -0
  107. package/dist/extractors/classify-segment.d.ts.map +1 -0
  108. package/dist/extractors/classify-segment.js +20 -0
  109. package/dist/extractors/classify-segment.js.map +1 -0
  110. package/dist/extractors/json-extractor.d.ts +16 -0
  111. package/dist/extractors/json-extractor.d.ts.map +1 -0
  112. package/dist/extractors/json-extractor.js +128 -0
  113. package/dist/extractors/json-extractor.js.map +1 -0
  114. package/dist/extractors/markdown-extractor.d.ts +15 -0
  115. package/dist/extractors/markdown-extractor.d.ts.map +1 -0
  116. package/dist/extractors/markdown-extractor.js +205 -0
  117. package/dist/extractors/markdown-extractor.js.map +1 -0
  118. package/dist/extractors/svg-extractor.d.ts +19 -0
  119. package/dist/extractors/svg-extractor.d.ts.map +1 -0
  120. package/dist/extractors/svg-extractor.js +132 -0
  121. package/dist/extractors/svg-extractor.js.map +1 -0
  122. package/dist/extractors/ui-string-extractor.d.ts +40 -0
  123. package/dist/extractors/ui-string-extractor.d.ts.map +1 -0
  124. package/dist/extractors/ui-string-extractor.js +146 -0
  125. package/dist/extractors/ui-string-extractor.js.map +1 -0
  126. package/dist/extractors/ui-string-locations.d.ts +23 -0
  127. package/dist/extractors/ui-string-locations.d.ts.map +1 -0
  128. package/dist/extractors/ui-string-locations.js +138 -0
  129. package/dist/extractors/ui-string-locations.js.map +1 -0
  130. package/dist/glossary/glossary.d.ts +34 -0
  131. package/dist/glossary/glossary.d.ts.map +1 -0
  132. package/dist/glossary/glossary.js +260 -0
  133. package/dist/glossary/glossary.js.map +1 -0
  134. package/dist/glossary/matcher.d.ts +10 -0
  135. package/dist/glossary/matcher.d.ts.map +1 -0
  136. package/dist/glossary/matcher.js +12 -0
  137. package/dist/glossary/matcher.js.map +1 -0
  138. package/dist/index.d.ts +44 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +44 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/processors/admonition-placeholders.d.ts +8 -0
  143. package/dist/processors/admonition-placeholders.d.ts.map +1 -0
  144. package/dist/processors/admonition-placeholders.js +59 -0
  145. package/dist/processors/admonition-placeholders.js.map +1 -0
  146. package/dist/processors/anchor-placeholders.d.ts +8 -0
  147. package/dist/processors/anchor-placeholders.d.ts.map +1 -0
  148. package/dist/processors/anchor-placeholders.js +37 -0
  149. package/dist/processors/anchor-placeholders.js.map +1 -0
  150. package/dist/processors/batch-processor.d.ts +10 -0
  151. package/dist/processors/batch-processor.d.ts.map +1 -0
  152. package/dist/processors/batch-processor.js +33 -0
  153. package/dist/processors/batch-processor.js.map +1 -0
  154. package/dist/processors/bold-code-placeholders.d.ts +14 -0
  155. package/dist/processors/bold-code-placeholders.d.ts.map +1 -0
  156. package/dist/processors/bold-code-placeholders.js +116 -0
  157. package/dist/processors/bold-code-placeholders.js.map +1 -0
  158. package/dist/processors/doc-postprocess.d.ts +51 -0
  159. package/dist/processors/doc-postprocess.d.ts.map +1 -0
  160. package/dist/processors/doc-postprocess.js +215 -0
  161. package/dist/processors/doc-postprocess.js.map +1 -0
  162. package/dist/processors/emphasis-placeholders.d.ts +6 -0
  163. package/dist/processors/emphasis-placeholders.d.ts.map +1 -0
  164. package/dist/processors/emphasis-placeholders.js +262 -0
  165. package/dist/processors/emphasis-placeholders.js.map +1 -0
  166. package/dist/processors/flat-link-rewrite.d.ts +32 -0
  167. package/dist/processors/flat-link-rewrite.d.ts.map +1 -0
  168. package/dist/processors/flat-link-rewrite.js +90 -0
  169. package/dist/processors/flat-link-rewrite.js.map +1 -0
  170. package/dist/processors/glossary-force-placeholders.d.ts +12 -0
  171. package/dist/processors/glossary-force-placeholders.d.ts.map +1 -0
  172. package/dist/processors/glossary-force-placeholders.js +58 -0
  173. package/dist/processors/glossary-force-placeholders.js.map +1 -0
  174. package/dist/processors/inline-code-placeholders.d.ts +11 -0
  175. package/dist/processors/inline-code-placeholders.d.ts.map +1 -0
  176. package/dist/processors/inline-code-placeholders.js +87 -0
  177. package/dist/processors/inline-code-placeholders.js.map +1 -0
  178. package/dist/processors/placeholder-handler.d.ts +38 -0
  179. package/dist/processors/placeholder-handler.d.ts.map +1 -0
  180. package/dist/processors/placeholder-handler.js +55 -0
  181. package/dist/processors/placeholder-handler.js.map +1 -0
  182. package/dist/processors/translation-placeholder-leaks.d.ts +2 -0
  183. package/dist/processors/translation-placeholder-leaks.d.ts.map +1 -0
  184. package/dist/processors/translation-placeholder-leaks.js +9 -0
  185. package/dist/processors/translation-placeholder-leaks.js.map +1 -0
  186. package/dist/processors/url-placeholders.d.ts +10 -0
  187. package/dist/processors/url-placeholders.d.ts.map +1 -0
  188. package/dist/processors/url-placeholders.js +29 -0
  189. package/dist/processors/url-placeholders.js.map +1 -0
  190. package/dist/processors/validator.d.ts +23 -0
  191. package/dist/processors/validator.d.ts.map +1 -0
  192. package/dist/processors/validator.js +186 -0
  193. package/dist/processors/validator.js.map +1 -0
  194. package/dist/runtime/i18next-helpers.d.ts +146 -0
  195. package/dist/runtime/i18next-helpers.d.ts.map +1 -0
  196. package/dist/runtime/i18next-helpers.js +192 -0
  197. package/dist/runtime/i18next-helpers.js.map +1 -0
  198. package/dist/runtime/index.d.ts +4 -0
  199. package/dist/runtime/index.d.ts.map +1 -0
  200. package/dist/runtime/index.js +4 -0
  201. package/dist/runtime/index.js.map +1 -0
  202. package/dist/runtime/template.d.ts +21 -0
  203. package/dist/runtime/template.d.ts.map +1 -0
  204. package/dist/runtime/template.js +28 -0
  205. package/dist/runtime/template.js.map +1 -0
  206. package/dist/runtime/ui-language-display.d.ts +16 -0
  207. package/dist/runtime/ui-language-display.d.ts.map +1 -0
  208. package/dist/runtime/ui-language-display.js +26 -0
  209. package/dist/runtime/ui-language-display.js.map +1 -0
  210. package/dist/server/translation-editor.d.ts +25 -0
  211. package/dist/server/translation-editor.d.ts.map +1 -0
  212. package/dist/server/translation-editor.js +583 -0
  213. package/dist/server/translation-editor.js.map +1 -0
  214. package/dist/utils/concurrency.d.ts +31 -0
  215. package/dist/utils/concurrency.d.ts.map +1 -0
  216. package/dist/utils/concurrency.js +103 -0
  217. package/dist/utils/concurrency.js.map +1 -0
  218. package/dist/utils/hash.d.ts +5 -0
  219. package/dist/utils/hash.d.ts.map +1 -0
  220. package/dist/utils/hash.js +9 -0
  221. package/dist/utils/hash.js.map +1 -0
  222. package/dist/utils/ignore-parser.d.ts +7 -0
  223. package/dist/utils/ignore-parser.d.ts.map +1 -0
  224. package/dist/utils/ignore-parser.js +26 -0
  225. package/dist/utils/ignore-parser.js.map +1 -0
  226. package/dist/utils/logger.d.ts +45 -0
  227. package/dist/utils/logger.d.ts.map +1 -0
  228. package/dist/utils/logger.js +158 -0
  229. package/dist/utils/logger.js.map +1 -0
  230. package/docs/GETTING_STARTED.md +697 -0
  231. package/docs/PACKAGE_OVERVIEW.md +427 -0
  232. package/docs/ai-i18n-tools-context.md +481 -0
  233. package/package.json +117 -0
  234. package/translated-docs/README.de.md +157 -0
  235. package/translated-docs/README.es.md +157 -0
  236. package/translated-docs/README.fr.md +157 -0
  237. package/translated-docs/README.hi.md +157 -0
  238. package/translated-docs/README.ja.md +157 -0
  239. package/translated-docs/README.ko.md +157 -0
  240. package/translated-docs/README.pt-BR.md +157 -0
  241. package/translated-docs/README.zh-CN.md +157 -0
  242. package/translated-docs/README.zh-TW.md +157 -0
  243. package/translated-docs/docs/GETTING_STARTED.de.md +682 -0
  244. package/translated-docs/docs/GETTING_STARTED.es.md +682 -0
  245. package/translated-docs/docs/GETTING_STARTED.fr.md +682 -0
  246. package/translated-docs/docs/GETTING_STARTED.hi.md +682 -0
  247. package/translated-docs/docs/GETTING_STARTED.ja.md +682 -0
  248. package/translated-docs/docs/GETTING_STARTED.ko.md +682 -0
  249. package/translated-docs/docs/GETTING_STARTED.pt-BR.md +682 -0
  250. package/translated-docs/docs/GETTING_STARTED.zh-CN.md +682 -0
  251. package/translated-docs/docs/GETTING_STARTED.zh-TW.md +682 -0
  252. package/translated-docs/docs/PACKAGE_OVERVIEW.de.md +428 -0
  253. package/translated-docs/docs/PACKAGE_OVERVIEW.es.md +428 -0
  254. package/translated-docs/docs/PACKAGE_OVERVIEW.fr.md +428 -0
  255. package/translated-docs/docs/PACKAGE_OVERVIEW.hi.md +428 -0
  256. package/translated-docs/docs/PACKAGE_OVERVIEW.ja.md +428 -0
  257. package/translated-docs/docs/PACKAGE_OVERVIEW.ko.md +428 -0
  258. package/translated-docs/docs/PACKAGE_OVERVIEW.pt-BR.md +428 -0
  259. package/translated-docs/docs/PACKAGE_OVERVIEW.zh-CN.md +428 -0
  260. package/translated-docs/docs/PACKAGE_OVERVIEW.zh-TW.md +428 -0
@@ -0,0 +1,428 @@
1
+ # ai-i18n-tools : Vue d'ensemble du package
2
+
3
+ Ce document décrit l'architecture interne de `ai-i18n-tools`, comment chaque composant s'assemble et comment les deux flux de travail principaux sont implémentés.
4
+
5
+ Pour des instructions d'utilisation pratiques, voir [GETTING_STARTED.md](GETTING_STARTED.fr.md).
6
+
7
+ <small>**Lire dans d'autres langues :** </small>
8
+
9
+ <small id="lang-list">[en-GB](../../docs/PACKAGE_OVERVIEW.md) · [de](./PACKAGE_OVERVIEW.de.md) · [es](./PACKAGE_OVERVIEW.es.md) · [fr](./PACKAGE_OVERVIEW.fr.md) · [hi](./PACKAGE_OVERVIEW.hi.md) · [ja](./PACKAGE_OVERVIEW.ja.md) · [ko](./PACKAGE_OVERVIEW.ko.md) · [pt-BR](./PACKAGE_OVERVIEW.pt-BR.md) · [zh-CN](./PACKAGE_OVERVIEW.zh-CN.md) · [zh-TW](./PACKAGE_OVERVIEW.zh-TW.md)</small>
10
+
11
+ ---
12
+
13
+ <!-- START doctoc generated TOC please keep comment here to allow auto update -->
14
+ <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
15
+ **Table des matières**
16
+
17
+ - [Vue d'ensemble de l'architecture](#architecture-overview)
18
+ - [Arbre source](#source-tree)
19
+ - [Flux de travail 1 - Internes de la traduction UI](#workflow-1---ui-translation-internals)
20
+ - [`UIStringExtractor`](#uistringextractor)
21
+ - [`strings.json`](#stringsjson)
22
+ - [Fichiers de locale plats](#flat-locale-files)
23
+ - [Invites de traduction UI](#ui-translation-prompts)
24
+ - [Flux de travail 2 - Internes de la traduction de documents](#workflow-2---document-translation-internals)
25
+ - [Extracteurs](#extractors)
26
+ - [Protection des espaces réservés](#placeholder-protection)
27
+ - [Cache (`TranslationCache`)](#cache-translationcache)
28
+ - [Résolution du chemin de sortie](#output-path-resolution)
29
+ - [Réécriture de liens plats](#flat-link-rewriting)
30
+ - [Infrastructure partagée](#shared-infrastructure)
31
+ - [`OpenRouterClient`](#openrouterclient)
32
+ - [Chargement de la configuration](#config-loading)
33
+ - [Journaliseur](#logger)
34
+ - [API des helpers d'exécution](#runtime-helpers-api)
35
+ - [Helpers RTL](#rtl-helpers)
36
+ - [Usines de configuration i18next](#i18next-setup-factories)
37
+ - [Helpers d'affichage](#display-helpers)
38
+ - [Helpers de chaîne](#string-helpers)
39
+ - [API programmatique](#programmatic-api)
40
+ - [Points d'extension](#extension-points)
41
+ - [Noms de fonctions personnalisées (extraction UI)](#custom-function-names-ui-extraction)
42
+ - [Extracteurs personnalisés](#custom-extractors)
43
+ - [Chemins de sortie personnalisés](#custom-output-paths)
44
+
45
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
46
+
47
+ ---
48
+
49
+ ## Vue d'ensemble de l'architecture
50
+
51
+ ```
52
+ ai-i18n-tools
53
+ ├── CLI (src/cli/) - commands: init, extract, translate-docs, translate-svg, translate-ui, sync, status, …
54
+ ├── Core (src/core/) - config, types, cache, prompts, output paths, UI languages
55
+ ├── Extractors (src/extractors/) - segment extraction from JS/TS, markdown, JSON, SVG
56
+ ├── Processors (src/processors/) - placeholders, batching, validation, link rewriting
57
+ ├── API (src/api/) - OpenRouter HTTP client
58
+ ├── Glossary (src/glossary/) - glossary loading and term matching
59
+ ├── Runtime (src/runtime/) - i18next helpers, display helpers (no i18next import)
60
+ ├── Server (src/server/) - local Express web editor for cache / glossary
61
+ └── Utils (src/utils/) - logger, hash, ignore parser
62
+ ```
63
+
64
+ Tout ce dont les consommateurs peuvent avoir besoin de manière programmatique est réexporté depuis `src/index.ts`.
65
+
66
+ ---
67
+
68
+ ## Arbre source
69
+
70
+ ```
71
+ src/
72
+ ├── index.ts Public API re-exports
73
+ │
74
+ ├── cli/
75
+ │ ├── index.ts CLI entry point (commander)
76
+ │ ├── extract-strings.ts `extract` command implementation
77
+ │ ├── translate-ui-strings.ts `translate-ui` command implementation
78
+ │ ├── doc-translate.ts `translate-docs` command (documentation files only)
79
+ │ ├── translate-svg.ts `translate-svg` command (standalone assets from `config.svg`)
80
+ │ ├── helpers.ts Shared CLI utilities
81
+ │ └── file-utils.ts File collection helpers
82
+ │
83
+ ├── core/
84
+ │ ├── types.ts Zod schemas + TypeScript types for all config shapes
85
+ │ ├── config.ts Config loading, merging, validation, init templates
86
+ │ ├── cache.ts SQLite translation cache (node:sqlite)
87
+ │ ├── prompt-builder.ts LLM prompt construction for docs and UI strings
88
+ │ ├── output-paths.ts Docusaurus / flat output path resolution
89
+ │ ├── ui-languages.ts ui-languages.json loading and locale resolution
90
+ │ ├── locale-utils.ts BCP-47 normalization and locale list parsing
91
+ │ └── errors.ts Typed error classes
92
+ │
93
+ ├── extractors/
94
+ │ ├── base-extractor.ts Abstract base class for all extractors
95
+ │ ├── ui-string-extractor.ts JS/TS source scanner (i18next-scanner)
96
+ │ ├── classify-segment.ts Heuristic segment type classification
97
+ │ ├── markdown-extractor.ts Markdown / MDX segment extraction
98
+ │ ├── json-extractor.ts JSON label file extraction
99
+ │ └── svg-extractor.ts SVG text extraction
100
+ │
101
+ ├── processors/
102
+ │ ├── placeholder-handler.ts Chain: admonitions → anchors → URLs
103
+ │ ├── url-placeholders.ts Markdown URL protection/restore
104
+ │ ├── admonition-placeholders.ts Docusaurus admonition protection/restore
105
+ │ ├── anchor-placeholders.ts HTML anchor / heading ID protection/restore
106
+ │ ├── batch-processor.ts Segment → batch grouping (count + char limits)
107
+ │ ├── validator.ts Post-translation structural checks
108
+ │ └── flat-link-rewrite.ts Relative link rewriting for flat output
109
+ │
110
+ ├── api/
111
+ │ └── openrouter.ts OpenRouter HTTP client with model fallback chain
112
+ │
113
+ ├── glossary/
114
+ │ ├── glossary.ts Glossary loading (CSV + auto-build from strings.json)
115
+ │ └── matcher.ts Term hint extraction for prompts
116
+ │
117
+ ├── runtime/
118
+ │ ├── index.ts Runtime re-exports
119
+ │ ├── template.ts interpolateTemplate, flipUiArrowsForRtl
120
+ │ ├── ui-language-display.ts getUILanguageLabel, getUILanguageLabelNative
121
+ │ └── i18next-helpers.ts RTL detection, i18next setup factories
122
+ │
123
+ ├── server/
124
+ │ └── translation-editor.ts Express app for cache / strings.json / glossary editor
125
+ │
126
+ └── utils/
127
+ ├── logger.ts Leveled logger with ANSI support
128
+ ├── hash.ts Segment hash (SHA-256 first 16 hex)
129
+ └── ignore-parser.ts .translate-ignore file parser
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Flux de travail 1 - Internes de la traduction UI
135
+
136
+ ```
137
+ source files (JS/TS)
138
+ │
139
+ ▼ UIStringExtractor (i18next-scanner Parser)
140
+ strings.json ─────────────────── master catalog
141
+ │ { hash: { source, translated, models?, locations? } }
142
+ ▼
143
+ OpenRouterClient.translateUIBatch()
144
+ │ sends JSON array of source strings, receives JSON array of translations (+ model id per batch)
145
+ ▼
146
+ de.json, pt-BR.json … ─────────── per-locale flat maps: source → translation (no model metadata)
147
+ ```
148
+
149
+ ### `UIStringExtractor`
150
+
151
+ Utilise `i18next-scanner`'s `Parser.parseFuncFromString` pour trouver les appels `t("literal")` et `i18n.t("literal")` dans n'importe quel fichier JS/TS. Les noms de fonctions et les extensions de fichiers sont configurables, et l'extraction peut également inclure la `description` du projet `package.json` lorsque `reactExtractor.includePackageDescription` est activé. Les hachages de segment sont les **8 premiers caractères hexadécimaux MD5** de la chaîne source tronquée - ceux-ci deviennent les clés dans `strings.json`.
152
+
153
+ ### `strings.json`
154
+
155
+ Le catalogue maître a la forme :
156
+
157
+ ```json
158
+ {
159
+ "<md5-8>": {
160
+ "source": "The English string",
161
+ "translated": {
162
+ "de": "Der deutsche Text",
163
+ "pt-BR": "O texto em português"
164
+ },
165
+ "models": {
166
+ "de": "anthropic/claude-3.5-haiku",
167
+ "pt-BR": "openai/gpt-4o"
168
+ },
169
+ "locations": [{ "file": "src/app/page.tsx", "line": 51 }]
170
+ }
171
+ }
172
+ ```
173
+
174
+ `modèles` (optionnel) — par locale, quel modèle a produit cette traduction après la dernière exécution réussie de `translate-ui` pour cette locale (ou `édité par l'utilisateur` si le texte a été enregistré depuis l'interface web de `l'éditeur`). `emplacements` (optionnel) — où `extract` a trouvé la chaîne.
175
+
176
+ `extract` ajoute de nouvelles clés et préserve les données `traduites` / `modèles` existantes pour les clés encore présentes dans le scan. `translate-ui` remplit les entrées `traduites` manquantes, met à jour les `modèles` pour les locales qu'il traduit, et écrit des fichiers de locale plats.
177
+
178
+ ### Fichiers de locale plats
179
+
180
+ Chaque locale cible obtient un fichier JSON plat (`de.json`) mappant la chaîne source → traduction (sans champ `modèles`) :
181
+
182
+ ```json
183
+ {
184
+ "The English string": "Der deutsche Text",
185
+ "Save": "Speichern"
186
+ }
187
+ ```
188
+
189
+ i18next charge ces fichiers en tant que bundles de ressources et recherche des traductions par la chaîne source (modèle clé-par-défaut).
190
+
191
+ ### Invites de traduction UI
192
+
193
+ `buildUIPromptMessages` construit des messages système + utilisateur qui :
194
+ - Identifient les langues source et cible (par nom d'affichage à partir de `localeDisplayNames` ou `ui-languages.json`).
195
+ - Envoient un tableau JSON de chaînes et demandent un tableau JSON de traductions en retour.
196
+ - Incluent des indices de glossaire lorsque disponibles.
197
+
198
+ `OpenRouterClient.translateUIBatch` essaie chaque modèle dans l'ordre, en revenant sur les erreurs de parsing ou de réseau. La CLI construit cette liste à partir de `openrouter.translationModels` (ou par défaut/retour hérité) ; pour `translate-ui`, le `ui.preferredModel` optionnel est préfixé lorsqu'il est défini (dédupliqué par rapport au reste).
199
+
200
+ ---
201
+
202
+ ## Flux de travail 2 - Internes de la traduction de documents
203
+
204
+ ```
205
+ markdown/MDX/JSON files (`translate-docs`)
206
+ │
207
+ ▼ MarkdownExtractor / JsonExtractor
208
+ segments[] ─────────────────── typed segments with hash + content
209
+ │
210
+ ▼ PlaceholderHandler
211
+ protected text ──────────────── URLs, admonitions, anchors replaced with tokens
212
+ │
213
+ ▼ splitTranslatableIntoBatches
214
+ batches[] ───────────────────── grouped by count + char limit
215
+ │
216
+ ▼ TranslationCache lookup
217
+ cache hit → skip, miss → OpenRouterClient.translateDocumentBatch
218
+ │
219
+ ▼ PlaceholderHandler.restoreAfterTranslation
220
+ final text ──────────────────── placeholders restored
221
+ │
222
+ ▼ resolveDocumentationOutputPath
223
+ output file ─────────────────── Docusaurus layout or flat layout
224
+ ```
225
+
226
+ ### Extracteurs
227
+
228
+ Tous les extracteurs étendent `BaseExtractor` et implémentent `extract(content, filepath): Segment[]`.
229
+
230
+ - `MarkdownExtractor` - divise le markdown en segments typés : `frontmatter`, `heading`, `paragraph`, `code`, `admonition`. Les segments non traduisibles (blocs de code, HTML brut) sont préservés tels quels.
231
+ - `JsonExtractor` - extrait les valeurs de chaîne des fichiers de labels JSON de Docusaurus.
232
+ - `SvgExtractor` - extrait le contenu `<text>`, `<title>`, et `<desc>` des SVG (utilisé par `translate-svg` pour les actifs sous `config.svg`, pas par `translate-docs`).
233
+
234
+ ### Protection des espaces réservés
235
+
236
+ Avant la traduction, la syntaxe sensible est remplacée par des jetons opaques pour éviter toute corruption par le LLM :
237
+
238
+ 1. **Marqueurs d'admonition** (`:::note`, `:::`) - restaurés avec le texte original exact.
239
+ 2. **Ancres de document** (HTML `<a id="…">`, titre Docusaurus `{#…}`) - conservés tels quels.
240
+ 3. **URLs Markdown** (`](url)`, `src="../…"`) - restaurées à partir d'une table de correspondance après la traduction.
241
+
242
+ ### Cache (`TranslationCache`)
243
+
244
+ Une base de données SQLite (via `node:sqlite`) stocke des lignes indexées par `(source_hash, locale)` contenant `translated_text`, `model`, `filepath`, `last_hit_at` et des champs associés. Le hash correspond aux 16 premiers caractères hexadécimaux du SHA-256 du contenu normalisé (espaces réduits).
245
+
246
+ À chaque exécution, les segments sont recherchés par hash × locale. Seuls les échecs de cache sont envoyés au LLM. Après la traduction, `last_hit_at` est réinitialisé pour les lignes de segment dans la portée de traduction actuelle qui n'ont pas été atteintes. `cleanup` exécute d'abord `sync --force-update`, puis supprime les lignes de segment obsolètes (`last_hit_at` nul / filepath vide), élague les clés `file_tracking` lorsque le chemin source résolu est absent du disque (`doc-block:…`, `svg-assets:…`, etc.), et supprime les lignes de traduction dont le filepath de métadonnées pointe vers un fichier manquant ; il sauvegarde `cache.db` au préalable, sauf si `--no-backup` est passé.
247
+
248
+ La commande `translate-docs` utilise également le **suivi de fichiers** afin que les sources inchangées avec des sorties existantes puissent ignorer tout travail. `--force-update` relance le traitement des fichiers tout en utilisant le cache de segments ; `--force` efface le suivi de fichiers et contourne les lectures du cache de segments pour la traduction via API. Voir [Démarrage](GETTING_STARTED.fr.md#cache-behaviour-and-translate-docs-flags) pour le tableau complet des options.
249
+
250
+ **Format de prompt Batch :** `translate-docs --prompt-format` sélectionne les formes XML (`<seg>` / `<t>`) ou tableau/objet JSON uniquement pour `OpenRouterClient.translateDocumentBatch` ; l'extraction, les espaces réservés et la validation restent inchangés. Voir [Format de prompt Batch](GETTING_STARTED.fr.md#batch-prompt-format).
251
+
252
+ ### Résolution du chemin de sortie
253
+
254
+ `resolveDocumentationOutputPath(config, cwd, locale, relPath, kind)` mappe un chemin relatif à la source vers le chemin de sortie :
255
+
256
+ - style `imbriqué` (par défaut) : `{outputDir}/{locale}/{relPath}` pour le markdown.
257
+ - style `docusaurus` : sous `docsRoot`, les sorties utilisent `{outputDir}/{locale}/docusaurus-plugin-content-docs/current/{relativeToDocsRoot}` ; les chemins en dehors de `docsRoot` reviennent au format imbriqué.
258
+ - style `plat` : `{outputDir}/{stem}.{locale}{extension}`. Lorsque `flatPreserveRelativeDir` est `true`, les sous-répertoires source sont conservés sous `outputDir`.
259
+ - **Personnalisé** `pathTemplate` : tout format de markdown utilisant `{outputDir}`, `{locale}`, `{LOCALE}`, `{relPath}`, `{stem}`, `{basename}`, `{extension}`, `{docsRoot}`, `{relativeToDocsRoot}`.
260
+ - **Personnalisé** `jsonPathTemplate` : mise en page personnalisée séparée pour les fichiers de labels JSON, utilisant les mêmes espaces réservés.
261
+ - `linkRewriteDocsRoot` aide le réécrivain de liens plats à calculer les préfixes corrects lorsque la sortie traduite est ancrée quelque part d'autre que la racine du projet par défaut.
262
+
263
+ ### Réécriture de liens plats
264
+
265
+ Lorsque `markdownOutput.style === "flat"`, les fichiers Markdown traduits sont placés aux côtés de la source avec des suffixes de locale. Les liens relatifs entre les pages sont réécrits de sorte que `[Guide](../guide.md)` dans `readme.de.md` pointe vers `guide.de.md`. Contrôlé par `rewriteRelativeLinks` (activé automatiquement pour le style plat sans `pathTemplate` personnalisé).
266
+
267
+ ---
268
+
269
+ ## Infrastructure partagée
270
+
271
+ ### `OpenRouterClient`
272
+
273
+ Enveloppe l'API de complétion de chat OpenRouter. Comportements clés :
274
+
275
+ - **Fallback du modèle** : essaie chaque modèle dans la liste résolue dans l'ordre ; revient en arrière en cas d'erreurs HTTP ou d'échecs d'analyse. La traduction de l'interface utilisateur résout d'abord `ui.preferredModel` lorsqu'il est présent, puis les modèles `openrouter`.
276
+ - **Limitation de débit** : détecte les réponses 429, attend `retry-after` (ou 2s), réessaie une fois.
277
+ - **Mise en cache des invites** : le message système est envoyé avec `cache_control: { type: "ephemeral" }` pour activer la mise en cache des invites sur les modèles pris en charge.
278
+ - **Journal de trafic de débogage** : si `debugTrafficFilePath` est défini, ajoute les requêtes et les réponses JSON à un fichier.
279
+
280
+ ### Chargement de la configuration
281
+
282
+ `loadI18nConfigFromFile(configPath, cwd)` pipeline :
283
+
284
+ 1. Lire et analyser `ai-i18n-tools.config.json` (JSON).
285
+ 2. `mergeWithDefaults` - fusion profonde avec `defaultI18nConfigPartial`, et fusionner toutes les entrées `documentations[].sourceFiles` dans `contentPaths`.
286
+ 3. `expandTargetLocalesFileReferenceInRawInput` - si `targetLocales` est un chemin de fichier, charger le manifeste et développer en codes de locale ; définir `uiLanguagesPath`.
287
+ 4. `expandDocumentationTargetLocalesInRawInput` - même pour chaque entrée `documentations[].targetLocales`.
288
+ 5. `parseI18nConfig` - validation Zod + `validateI18nBusinessRules`.
289
+ 6. `applyEnvOverrides` - appliquer `OPENROUTER_API_KEY`, `I18N_SOURCE_LOCALE`, etc.
290
+ 7. `augmentConfigWithUiLanguagesFile` - attacher les noms d'affichage du manifeste.
291
+
292
+ ### Journaliseur
293
+
294
+ `Logger` prend en charge les niveaux `debug`, `info`, `warn`, `error` avec sortie couleur ANSI. Le mode verbeux (`-v`) active `debug`. Lorsque `logFilePath` est défini, les lignes de journal sont également écrites dans ce fichier.
295
+
296
+ ---
297
+
298
+ ## API des helpers d'exécution
299
+
300
+ Ceux-ci sont exportés depuis `'ai-i18n-tools/runtime'` et fonctionnent dans n'importe quel environnement JavaScript (navigateur, Node.js, Deno, Edge). Ils **ne** s'importent pas depuis `i18next` ou `react-i18next`.
301
+
302
+ ### Helpers RTL
303
+
304
+ ```ts
305
+ RTL_LANGS: ReadonlySet<string>
306
+ getTextDirection(lng: string): 'ltr' | 'rtl'
307
+ applyDirection(lng: string, element?: Element): void
308
+ ```
309
+
310
+ ### Usines de configuration i18next
311
+
312
+ ```ts
313
+ defaultI18nInitOptions(sourceLocale?: string): i18nextInitOptions
314
+ wrapI18nWithKeyTrim(i18n: I18nLike): void
315
+ makeLoadLocale(
316
+ i18n: I18nWithResources,
317
+ localeLoaders: Record<string, () => Promise<unknown>>,
318
+ sourceLocale?: string
319
+ ): (lang: string) => Promise<void>
320
+ ```
321
+
322
+ ### Helpers d'affichage
323
+
324
+ ```ts
325
+ getUILanguageLabel(lang: UiLanguageEntry, t: TranslateFn): string
326
+ getUILanguageLabelNative(lang: UiLanguageEntry): string
327
+ ```
328
+
329
+ ### Helpers de chaîne
330
+
331
+ ```ts
332
+ interpolateTemplate(str: string, vars: Record<string, string | number | boolean>): string
333
+ flipUiArrowsForRtl(text: string | null | undefined, isRtl: boolean): string | null | undefined
334
+ ```
335
+
336
+ ---
337
+
338
+ ## API programmatique
339
+
340
+ Tous les types et classes publics sont exportés depuis la racine du package. Exemple : exécuter l'étape translate-UI depuis Node.js sans l'interface en ligne de commande :
341
+
342
+ ```ts
343
+ import { loadI18nConfigFromFile, runTranslateUI } from 'ai-i18n-tools';
344
+
345
+ // Config must have features.translateUIStrings: true (and valid targetLocales, etc.).
346
+ const config = loadI18nConfigFromFile('ai-i18n-tools.config.json');
347
+
348
+ const summary = await runTranslateUI(config, {
349
+ cwd: process.cwd(),
350
+ locales: config.targetLocales,
351
+ force: false,
352
+ dryRun: false,
353
+ verbose: false,
354
+ });
355
+ console.log(
356
+ `Updated ${summary.stringsUpdated} string(s); locales touched: ${summary.localesTouched.join(', ')}`
357
+ );
358
+ ```
359
+
360
+ Exports clés :
361
+
362
+ | Export | Description |
363
+ |---|---|
364
+ | `loadI18nConfigFromFile` | Charger, fusionner, valider la configuration à partir d'un fichier JSON. |
365
+ | `parseI18nConfig` | Valider un objet de configuration brut. |
366
+ | `TranslationCache` | Cache SQLite - instancier avec un chemin `cacheDir`. |
367
+ | `UIStringExtractor` | Extraire les chaînes `t("…")` des sources JS/TS. |
368
+ | `MarkdownExtractor` | Extraire les segments traduisibles du markdown. |
369
+ | `JsonExtractor` | Extraire des fichiers d'étiquettes JSON Docusaurus. |
370
+ | `SvgExtractor` | Extraire des fichiers SVG. |
371
+ | `OpenRouterClient` | Faire des demandes de traduction à OpenRouter. |
372
+ | `PlaceholderHandler` | Protéger/restaurer la syntaxe markdown autour de la traduction. |
373
+ | `splitTranslatableIntoBatches` | Regrouper les segments en lots de taille LLM. |
374
+ | `validateTranslation` | Vérifications structurelles après traduction. |
375
+ | `resolveDocumentationOutputPath` | Résoudre le chemin du fichier de sortie pour un document traduit. |
376
+ | `Glossary` / `GlossaryMatcher` | Charger et appliquer des glossaires de traduction. |
377
+ | `runTranslateUI` | Point d'entrée programmatique pour translate-UI. |
378
+
379
+ ---
380
+
381
+ ## Points d'extension
382
+
383
+ ### Noms de fonctions personnalisées (extraction UI)
384
+
385
+ Ajouter des noms de fonctions de traduction non standard via la configuration :
386
+
387
+ ```json
388
+ {
389
+ "ui": {
390
+ "reactExtractor": {
391
+ "funcNames": ["t", "i18n.t", "translate", "i18n.translate"]
392
+ }
393
+ }
394
+ }
395
+ ```
396
+
397
+ ### Extracteurs personnalisés
398
+
399
+ Implémentez `ContentExtractor` à partir du package :
400
+
401
+ ```ts
402
+ import { BaseExtractor, type Segment } from 'ai-i18n-tools';
403
+
404
+ class MyExtractor extends BaseExtractor {
405
+ readonly name = 'my-format';
406
+ canHandle(filepath: string) { return filepath.endsWith('.myext'); }
407
+ extract(content: string): Segment[] { /* … */ }
408
+ reassemble(segments: Segment[], translations: Map<string, string>): string { /* … */ }
409
+ }
410
+ ```
411
+
412
+ Passez-le au pipeline de traduction de documents en important les utilitaires `doc-translate.ts` de manière programmatique.
413
+
414
+ ### Chemins de sortie personnalisés
415
+
416
+ Utilisez `markdownOutput.pathTemplate` pour toute mise en page de fichier :
417
+
418
+ ```json
419
+ {
420
+ "documentations": [
421
+ {
422
+ "markdownOutput": {
423
+ "pathTemplate": "{outputDir}/{locale}/{relativeToDocsRoot}"
424
+ }
425
+ }
426
+ ]
427
+ }
428
+ ```