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: Paketübersicht
2
+
3
+ Dieses Dokument beschreibt die interne Architektur von `ai-i18n-tools`, wie jede Komponente zusammenpasst und wie die beiden Kernarbeitsabläufe implementiert sind.
4
+
5
+ Für praktische Nutzungshinweise siehe [GETTING_STARTED.md](GETTING_STARTED.de.md).
6
+
7
+ <small>**In anderen Sprachen lesen:** </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
+ **Inhaltsverzeichnis**
16
+
17
+ - [Architekturübersicht](#architecture-overview)
18
+ - [Quellbaum](#source-tree)
19
+ - [Workflow 1 - UI-Übersetzungsinternas](#workflow-1---ui-translation-internals)
20
+ - [`UIStringExtractor`](#uistringextractor)
21
+ - [`strings.json`](#stringsjson)
22
+ - [Flache Lokalisierungsdateien](#flat-locale-files)
23
+ - [UI-Übersetzungsaufforderungen](#ui-translation-prompts)
24
+ - [Workflow 2 - Dokumentenübersetzungsinternas](#workflow-2---document-translation-internals)
25
+ - [Extraktoren](#extractors)
26
+ - [Platzhalter-Schutz](#placeholder-protection)
27
+ - [Cache (`TranslationCache`)](#cache-translationcache)
28
+ - [Ausgabepfadauflösung](#output-path-resolution)
29
+ - [Flaches Link-Rewriting](#flat-link-rewriting)
30
+ - [Gemeinsame Infrastruktur](#shared-infrastructure)
31
+ - [`OpenRouterClient`](#openrouterclient)
32
+ - [Konfigurationsladen](#config-loading)
33
+ - [Logger](#logger)
34
+ - [Laufzeit-Hilfs-API](#runtime-helpers-api)
35
+ - [RTL-Hilfen](#rtl-helpers)
36
+ - [i18next-Setup-Fabriken](#i18next-setup-factories)
37
+ - [Anzeigehilfen](#display-helpers)
38
+ - [String-Hilfen](#string-helpers)
39
+ - [Programmierbare API](#programmatic-api)
40
+ - [Erweiterungspunkte](#extension-points)
41
+ - [Benutzerdefinierte Funktionsnamen (UI-Extraktion)](#custom-function-names-ui-extraction)
42
+ - [Benutzerdefinierte Extraktoren](#custom-extractors)
43
+ - [Benutzerdefinierte Ausgabepfade](#custom-output-paths)
44
+
45
+ <!-- END doctoc generated TOC please keep comment here to allow auto update -->
46
+
47
+ ---
48
+
49
+ ## Architekturübersicht
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
+ Alles, was Verbraucher programmgesteuert benötigen könnten, wird von `src/index.ts` erneut exportiert.
65
+
66
+ ---
67
+
68
+ ## Quellbaum
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
+ ## Workflow 1 - UI-Übersetzungsinternas
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
+ Verwendet `i18next-scanner`'s `Parser.parseFuncFromString`, um `t("literal")` und `i18n.t("literal")` Aufrufe in jeder JS/TS-Datei zu finden. Funktionsnamen und Dateiendungen sind konfigurierbar, und die Extraktion kann auch die `description` des Projekt-`package.json` einbeziehen, wenn `reactExtractor.includePackageDescription` aktiviert ist. Segment-Hashes sind **MD5 erste 8 hex Zeichen** des getrimmten Quellstrings - diese werden zu den Schlüsseln in `strings.json`.
152
+
153
+ ### `strings.json`
154
+
155
+ Der Master-Katalog hat die Form:
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
+ `models` (optional) – je Sprachvariante, welches Modell die Übersetzung nach dem letzten erfolgreichen `translate-ui`-Lauf für diese Sprachvariante erstellt hat (oder `user-edited`, wenn der Text über die `editor`-Webbenutzeroberfläche gespeichert wurde). `locations` (optional) – wo `extract` die Zeichenkette gefunden hat.
175
+
176
+ `extract` fügt neue Schlüssel hinzu und behält vorhandene `translated`-/`models`-Daten für Schlüssel bei, die weiterhin im Scan vorhanden sind. `translate-ui` füllt fehlende `translated`-Einträge aus, aktualisiert `models` für die Sprachvarianten, die es übersetzt, und schreibt flache Sprachdateien.
177
+
178
+ ### Flache Lokalisierungsdateien
179
+
180
+ Jede Zielsprache erhält eine flache JSON-Datei (`de.json`), die die Quellzeichenkette der Übersetzung zuordnet (ohne `models`-Feld):
181
+
182
+ ```json
183
+ {
184
+ "The English string": "Der deutsche Text",
185
+ "Save": "Speichern"
186
+ }
187
+ ```
188
+
189
+ i18next lädt diese als Ressourcenbündel und sucht Übersetzungen anhand des Quellstrings (key-as-default Modell).
190
+
191
+ ### UI-Übersetzungsaufforderungen
192
+
193
+ `buildUIPromptMessages` erstellt System- + Benutzermeldungen, die:
194
+ - Die Quell- und Zielsprache identifizieren (nach Anzeigename aus `localeDisplayNames` oder `ui-languages.json`).
195
+ - Ein JSON-Array von Strings senden und ein JSON-Array von Übersetzungen anfordern.
196
+ - Glossarhinweise enthalten, wenn verfügbar.
197
+
198
+ `OpenRouterClient.translateUIBatch` versucht nacheinander jedes Modell, mit Fallback bei Parse- oder Netzwerkfehlern. Die CLI erstellt diese Liste aus `openrouter.translationModels` (oder veraltetem Standard-/Fallback); für `translate-ui` wird das optionale `ui.preferredModel` vorangestellt, falls gesetzt (Duplikate gegenüber dem Rest werden entfernt).
199
+
200
+ ---
201
+
202
+ ## Workflow 2 - Dokumentenübersetzungsinternas
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
+ ### Extraktoren
227
+
228
+ Alle Extraktoren erweitern `BaseExtractor` und implementieren `extract(content, filepath): Segment[]`.
229
+
230
+ - `MarkdownExtractor` – teilt Markdown in typisierte Segmente auf: `frontmatter`, `heading`, `paragraph`, `code`, `admonition`. Nicht zu übersetzende Segmente (Codeblöcke, rohes HTML) werden wortwörtlich beibehalten.
231
+ - `JsonExtractor` – extrahiert Zeichenkettenwerte aus Docusaurus-JSON-Bezeichnungsdateien.
232
+ - `SvgExtractor` – extrahiert Inhalte aus `<text>`, `<title>` und `<desc>` aus SVG (verwendet von `translate-svg` für Assets unter `config.svg`, nicht von `translate-docs`).
233
+
234
+ ### Platzhalter-Schutz
235
+
236
+ Vor der Übersetzung wird sensible Syntax durch undurchsichtige Tokens ersetzt, um eine Korruption durch LLM zu verhindern:
237
+
238
+ 1. **Admonition-Markierungen** (`:::note`, `:::`) - werden mit dem genauen Originaltext wiederhergestellt.
239
+ 2. **Dok-Links** (HTML `<a id="…">`, Docusaurus-Überschrift `{#…}`) - werden unverändert beibehalten.
240
+ 3. **Markdown-URLs** (`](url)`, `src="../…"`) - werden nach der Übersetzung aus einer Zuordnung wiederhergestellt.
241
+
242
+ ### Cache (`TranslationCache`)
243
+
244
+ Die SQLite-Datenbank (über `node:sqlite`) speichert Zeilen, die durch `(source_hash, locale)` indiziert sind, mit `translated_text`, `model`, `filepath`, `last_hit_at` und verwandten Feldern. Der Hash ist SHA-256 der ersten 16 hexadezimalen Zeichen des normalisierten Inhalts (Whitespace zusammengefasst).
245
+
246
+ Bei jedem Durchlauf werden Segmente nach Hash × Locale gesucht. Nur Cache-Fehlermeldungen gehen an das LLM. Nach der Übersetzung wird `last_hit_at` für Segmentzeilen im aktuellen Übersetzungsbereich zurückgesetzt, die nicht aufgerufen wurden. `cleanup` führt zuerst `sync --force-update` aus, entfernt dann veraltete Segmentzeilen (null `last_hit_at` / leeres filepath), kürzt `file_tracking`-Schlüssel, wenn der aufgelöste Quellpfad auf der Festplatte fehlt (`doc-block:…`, `svg-assets:…` usw.) und entfernt Übersetzungszeilen, deren Metadaten-Filepath auf eine fehlende Datei zeigt; es sichert zuerst `cache.db`, es sei denn, `--no-backup` wird übergeben.
247
+
248
+ Der Befehl `translate-docs` verwendet auch **Dateitracking**, sodass unveränderte Quellen mit vorhandenen Ausgaben die Arbeit vollständig überspringen können. `--force-update` führt die Dateiverarbeitung erneut aus, während der Segmentcache weiterhin verwendet wird; `--force` löscht das Dateitracking und umgeht die Lesevorgänge des Segmentcaches für die API-Übersetzung. Siehe [Getting Started](GETTING_STARTED.de.md#cache-behaviour-and-translate-docs-flags) für die vollständige Flaggenübersicht.
249
+
250
+ **Batch-Aufforderungsformat:** `translate-docs --prompt-format` wählt XML (`<seg>` / `<t>`) oder JSON-Array/-Objekt-Formen ausschließlich für `OpenRouterClient.translateDocumentBatch`; Extraktion, Platzhalter und Validierung bleiben unverändert. Siehe [Batch-Aufforderungsformat](GETTING_STARTED.de.md#batch-prompt-format).
251
+
252
+ ### Auflösung des Ausgabepfads
253
+
254
+ `resolveDocumentationOutputPath(config, cwd, locale, relPath, kind)` ordnet einen quellenrelativen Pfad dem Ausgabepfad zu:
255
+
256
+ - `nested`-Stil (Standard): `{outputDir}/{locale}/{relPath}` für Markdown.
257
+ - `docusaurus`-Stil: unter `docsRoot` verwenden die Ausgaben `{outputDir}/{locale}/docusaurus-plugin-content-docs/current/{relativeToDocsRoot}`; Pfade außerhalb von `docsRoot` fallen auf das verschachtelte Layout zurück.
258
+ - `flat`-Stil: `{outputDir}/{stem}.{locale}{extension}`. Wenn `flatPreserveRelativeDir` auf `true` gesetzt ist, werden Quellunterverzeichnisse unter `outputDir` beibehalten.
259
+ - **Benutzerdefiniert** `pathTemplate`: beliebiges Markdown-Layout unter Verwendung von `{outputDir}`, `{locale}`, `{LOCALE}`, `{relPath}`, `{stem}`, `{basename}`, `{extension}`, `{docsRoot}`, `{relativeToDocsRoot}`.
260
+ - **Benutzerdefiniert** `jsonPathTemplate`: separates benutzerdefiniertes Layout für JSON-Bezeichnungsdateien, mit denselben Platzhaltern.
261
+ - `linkRewriteDocsRoot` hilft dem flachen Link-Umschreiber, korrekte Präfixe zu berechnen, wenn die übersetzte Ausgabe an einer anderen Stelle als der standardmäßigen Projektwurzel verankert ist.
262
+
263
+ ### Flaches Link-Umschreiben
264
+
265
+ Wenn `markdownOutput.style === "flat"`, werden übersetzte Markdown-Dateien neben der Quelle mit Lokalisierungssuffixen platziert. Relative Links zwischen Seiten werden umgeschrieben, sodass `[Guide](../guide.md)` in `readme.de.md` auf `guide.de.md` verweist. Gesteuert durch `rewriteRelativeLinks` (automatisch aktiviert für den flachen Stil ohne benutzerdefiniertes `pathTemplate`).
266
+
267
+ ---
268
+
269
+ ## Gemeinsame Infrastruktur
270
+
271
+ ### `OpenRouterClient`
272
+
273
+ Umhüllt die OpenRouter-Chat-Vervollständigungs-API. Wichtige Verhaltensweisen:
274
+
275
+ - **Modell-Fallback**: versucht jedes Modell in der aufgelösten Liste der Reihe nach; fällt bei HTTP-Fehlern oder Parsing-Fehlern zurück. Die UI-Übersetzung löst zuerst `ui.preferredModel` auf, wenn vorhanden, dann die `openrouter`-Modelle.
276
+ - **Ratenbegrenzung**: erkennt 429-Antworten, wartet `retry-after` (oder 2s), und versucht es einmal erneut.
277
+ - **Prompt-Caching**: Die Systemnachricht wird mit `cache_control: { type: "ephemeral" }` gesendet, um das Prompt-Caching bei unterstützten Modellen zu aktivieren.
278
+ - **Debug-Verkehrsprotokoll**: Wenn `debugTrafficFilePath` gesetzt ist, werden Anforderungs- und Antwort-JSON in eine Datei angehängt.
279
+
280
+ ### Konfigurationsladen
281
+
282
+ `loadI18nConfigFromFile(configPath, cwd)` Pipeline:
283
+
284
+ 1. Lesen und Parsen von `ai-i18n-tools.config.json` (JSON).
285
+ 2. `mergeWithDefaults` - tiefes Mergen mit `defaultI18nConfigPartial` und Mergen von Einträgen in `documentations[].sourceFiles` in `contentPaths`.
286
+ 3. `expandTargetLocalesFileReferenceInRawInput` - wenn `targetLocales` ein Dateipfad ist, das Manifest laden und in Locale-Codes erweitern; `uiLanguagesPath` setzen.
287
+ 4. `expandDocumentationTargetLocalesInRawInput` - dasselbe für jeden Eintrag in `documentations[].targetLocales`.
288
+ 5. `parseI18nConfig` - Zod-Validierung + `validateI18nBusinessRules`.
289
+ 6. `applyEnvOverrides` - `OPENROUTER_API_KEY`, `I18N_SOURCE_LOCALE` usw. anwenden.
290
+ 7. `augmentConfigWithUiLanguagesFile` - Manifest-Anzeigenamen anhängen.
291
+
292
+ ### Protokollierer
293
+
294
+ `Logger` unterstützt die Ebenen `debug`, `info`, `warn`, `error` mit ANSI-Farbausgabe. Der ausführliche Modus (`-v`) aktiviert `debug`. Wenn `logFilePath` gesetzt ist, werden Protokollzeilen auch in diese Datei geschrieben.
295
+
296
+ ---
297
+
298
+ ## Laufzeit-Hilfs-API
299
+
300
+ Diese werden aus `'ai-i18n-tools/runtime'` exportiert und funktionieren in jeder JavaScript-Umgebung (Browser, Node.js, Deno, Edge). Sie importieren **nicht** von `i18next` oder `react-i18next`.
301
+
302
+ ### RTL-Hilfen
303
+
304
+ ```ts
305
+ RTL_LANGS: ReadonlySet<string>
306
+ getTextDirection(lng: string): 'ltr' | 'rtl'
307
+ applyDirection(lng: string, element?: Element): void
308
+ ```
309
+
310
+ ### i18next Setup-Fabriken
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
+ ### Anzeigehilfen
323
+
324
+ ```ts
325
+ getUILanguageLabel(lang: UiLanguageEntry, t: TranslateFn): string
326
+ getUILanguageLabelNative(lang: UiLanguageEntry): string
327
+ ```
328
+
329
+ ### String-Hilfen
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
+ ## Programmatic API
339
+
340
+ Alle öffentlichen Typen und Klassen werden aus dem Paketstamm exportiert. Beispiel: Ausführen des translate-UI-Schritts aus Node.js ohne die CLI:
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
+ Wichtige Exporte:
361
+
362
+ | Export | Beschreibung |
363
+ |---|---|
364
+ | `loadI18nConfigFromFile` | Laden, Mergen, Validieren der Konfiguration aus einer JSON-Datei. |
365
+ | `parseI18nConfig` | Validieren eines rohen Konfigurationsobjekts. |
366
+ | `TranslationCache` | SQLite-Cache - mit einem `cacheDir`-Pfad instanziieren. |
367
+ | `UIStringExtractor` | Extrahieren von `t("…")`-Strings aus JS/TS-Quellcode. |
368
+ | `MarkdownExtractor` | Extrahieren von übersetzbaren Segmenten aus Markdown. |
369
+ | `JsonExtractor` | Extrahieren aus Docusaurus JSON-Label-Dateien. |
370
+ | `SvgExtractor` | Extrahieren aus SVG-Dateien. |
371
+ | `OpenRouterClient` | Übersetzungsanfragen an OpenRouter stellen. |
372
+ | `PlaceholderHandler` | Markdown-Syntax um die Übersetzung schützen/wiederherstellen. |
373
+ | `splitTranslatableIntoBatches` | Segmente in LLM-große Batches gruppieren. |
374
+ | `validateTranslation` | Strukturelle Überprüfungen nach der Übersetzung. |
375
+ | `resolveDocumentationOutputPath` | Ausgabedateipfad für ein übersetztes Dokument auflösen. |
376
+ | `Glossar` / `GlossarMatcher` | Übersetzungs-Glossare laden und anwenden. |
377
+ | `runTranslateUI` | Programmgesteuerter Einstiegspunkt für die Übersetzung der UI. |
378
+
379
+ ---
380
+
381
+ ## Erweiterungspunkte
382
+
383
+ ### Benutzerdefinierte Funktionsnamen (UI-Extraktion)
384
+
385
+ Fügen Sie über die Konfiguration nicht-standardmäßige Übersetzungsfunktionsnamen hinzu:
386
+
387
+ ```json
388
+ {
389
+ "ui": {
390
+ "reactExtractor": {
391
+ "funcNames": ["t", "i18n.t", "translate", "i18n.translate"]
392
+ }
393
+ }
394
+ }
395
+ ```
396
+
397
+ ### Benutzerdefinierte Extraktoren
398
+
399
+ Implementiere `ContentExtractor` aus dem Paket:
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
+ Übergebe es an die doc-translate-Pipeline, indem du die `doc-translate.ts`-Hilfsprogramme programmgesteuert importierst.
413
+
414
+ ### Benutzerdefinierte Ausgabepfade
415
+
416
+ Verwende `markdownOutput.pathTemplate` für jedes Dateilayout:
417
+
418
+ ```json
419
+ {
420
+ "documentations": [
421
+ {
422
+ "markdownOutput": {
423
+ "pathTemplate": "{outputDir}/{locale}/{relativeToDocsRoot}"
424
+ }
425
+ }
426
+ ]
427
+ }
428
+ ```