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,428 @@
|
|
|
1
|
+
# ai-i18n-tools:包概述
|
|
2
|
+
|
|
3
|
+
本文档描述了 `ai-i18n-tools` 的内部架构、各组件如何协同工作,以及两个核心工作流的实现方式。
|
|
4
|
+
|
|
5
|
+
关于实际使用说明,请参阅 [GETTING_STARTED.md](GETTING_STARTED.zh-CN.md)。
|
|
6
|
+
|
|
7
|
+
<small>**以其他语言阅读:**</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
|
+
**目录**
|
|
16
|
+
|
|
17
|
+
- [架构概述](#architecture-overview)
|
|
18
|
+
- [源码树](#source-tree)
|
|
19
|
+
- [工作流 1 - UI 翻译内部机制](#workflow-1---ui-translation-internals)
|
|
20
|
+
- [`UIStringExtractor`](#uistringextractor)
|
|
21
|
+
- [`strings.json`](#stringsjson)
|
|
22
|
+
- [扁平化区域设置文件](#flat-locale-files)
|
|
23
|
+
- [UI 翻译提示](#ui-translation-prompts)
|
|
24
|
+
- [工作流 2 - 文档翻译内部机制](#workflow-2---document-translation-internals)
|
|
25
|
+
- [提取器](#extractors)
|
|
26
|
+
- [占位符保护](#placeholder-protection)
|
|
27
|
+
- [缓存 (`TranslationCache`)](#cache-translationcache)
|
|
28
|
+
- [输出路径解析](#output-path-resolution)
|
|
29
|
+
- [扁平链接重写](#flat-link-rewriting)
|
|
30
|
+
- [共享基础设施](#shared-infrastructure)
|
|
31
|
+
- [`OpenRouterClient`](#openrouterclient)
|
|
32
|
+
- [配置加载](#config-loading)
|
|
33
|
+
- [日志记录器](#logger)
|
|
34
|
+
- [运行时辅助工具 API](#runtime-helpers-api)
|
|
35
|
+
- [RTL 辅助工具](#rtl-helpers)
|
|
36
|
+
- [i18next 设置工厂函数](#i18next-setup-factories)
|
|
37
|
+
- [显示辅助工具](#display-helpers)
|
|
38
|
+
- [字符串辅助工具](#string-helpers)
|
|
39
|
+
- [编程式 API](#programmatic-api)
|
|
40
|
+
- [扩展点](#extension-points)
|
|
41
|
+
- [自定义函数名称(UI 提取)](#custom-function-names-ui-extraction)
|
|
42
|
+
- [自定义提取器](#custom-extractors)
|
|
43
|
+
- [自定义输出路径](#custom-output-paths)
|
|
44
|
+
|
|
45
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 架构概述
|
|
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
|
+
使用者可能以编程方式需要的一切内容,都从 `src/index.ts` 重新导出。
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 源码树
|
|
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
|
+
## 工作流 1 - 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
|
+
使用 `i18next-scanner` 的 `Parser.parseFuncFromString` 在任何 JS/TS 文件中查找 `t("literal")` 和 `i18n.t("literal")` 调用。函数名称和文件扩展名是可配置的,当启用 `reactExtractor.includePackageDescription` 时,提取还可以包含项目 `package.json` 的 `description`。段哈希是**修剪后源字符串的 MD5 前 8 个十六进制字符**——这些将成为 `strings.json` 中的键。
|
|
152
|
+
|
|
153
|
+
### `strings.json`
|
|
154
|
+
|
|
155
|
+
主目录具有以下结构:
|
|
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`(可选)—— 按区域设置,表示在该区域设置上一次成功的 `translate-ui` 运行后,是由哪个模型生成了该翻译(如果文本是从 `editor` 网页界面保存的,则为 `user-edited`)。`locations`(可选)—— `extract` 发现该字符串的位置。
|
|
175
|
+
|
|
176
|
+
`extract` 会添加新键,并保留仍存在于扫描中的键的现有 `translated` / `models` 数据。`translate-ui` 填充缺失的 `translated` 条目,更新其所翻译区域设置的 `models`,并写入扁平化的区域设置文件。
|
|
177
|
+
|
|
178
|
+
### 扁平化区域设置文件
|
|
179
|
+
|
|
180
|
+
每个目标区域设置会生成一个扁平的 JSON 文件(如 `de.json`),将源字符串映射到翻译结果(不含 `models` 字段):
|
|
181
|
+
|
|
182
|
+
```json
|
|
183
|
+
{
|
|
184
|
+
"The English string": "Der deutsche Text",
|
|
185
|
+
"Save": "Speichern"
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
i18next 将这些文件作为资源包加载,并通过源字符串(键即默认模型)查找翻译。
|
|
190
|
+
|
|
191
|
+
### UI 翻译提示
|
|
192
|
+
|
|
193
|
+
`buildUIPromptMessages` 构建系统 + 用户消息,这些消息:
|
|
194
|
+
- 识别源语言和目标语言(通过 `localeDisplayNames` 或 `ui-languages.json` 中的显示名称)。
|
|
195
|
+
- 发送一个 JSON 字符串数组,并要求返回一个 JSON 翻译数组。
|
|
196
|
+
- 在可用时包含术语表提示。
|
|
197
|
+
|
|
198
|
+
`OpenRouterClient.translateUIBatch` 按顺序尝试每个模型,在解析或网络错误时进行降级。CLI 从 `openrouter.translationModels`(或旧版默认/备用模型)构建该列表;对于 `translate-ui`,当设置了可选的 `ui.preferredModel` 时会将其前置(与其余部分去重)。
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## 工作流 2 - 文档翻译内部机制
|
|
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
|
+
### 提取器
|
|
227
|
+
|
|
228
|
+
所有提取器都扩展 `BaseExtractor` 并实现 `extract(content, filepath): Segment[]`。
|
|
229
|
+
|
|
230
|
+
- `MarkdownExtractor` —— 将 Markdown 拆分为带类型片段:`frontmatter`、`heading`、`paragraph`、`code`、`admonition`。不可翻译的片段(代码块、原始 HTML)将原样保留。
|
|
231
|
+
- `JsonExtractor` —— 从 Docusaurus JSON 标签文件中提取字符串值。
|
|
232
|
+
- `SvgExtractor` —— 从 SVG 中提取 `<text>`、`<title>` 和 `<desc>` 内容(由 `translate-svg` 用于 `config.svg` 下的资源,不用于 `translate-docs`)。
|
|
233
|
+
|
|
234
|
+
### 占位符保护
|
|
235
|
+
|
|
236
|
+
在翻译之前,敏感语法被替换为不透明的令牌,以防止 LLM 损坏:
|
|
237
|
+
|
|
238
|
+
1. **警告标记** (`:::note`, `:::`) - 恢复为确切的原始文本。
|
|
239
|
+
2. **文档锚点** (HTML `<a id="…">`,Docusaurus 标题 `{#…}`) - 逐字保留。
|
|
240
|
+
3. **Markdown URLs** (`](url)`,`src="../…"`) - 在翻译后从映射中恢复。
|
|
241
|
+
|
|
242
|
+
### 缓存 (`TranslationCache`)
|
|
243
|
+
|
|
244
|
+
SQLite 数据库(通过 `node:sqlite`)存储以 `(source_hash, locale)` 为键的行,包含 `translated_text`、`model`、`filepath`、`last_hit_at` 和相关字段。哈希是标准化内容的 SHA-256 前 16 个十六进制字符(空格折叠)。
|
|
245
|
+
|
|
246
|
+
在每次运行中,通过哈希 × 语言环境查找段落。只有缓存未命中时才会调用 LLM。翻译后,当前翻译范围内未命中的段落的 `last_hit_at` 被重置。`cleanup` 首先运行 `sync --force-update`,然后删除过时的段落行(null `last_hit_at` / 空文件路径),在磁盘上缺少解析的源路径时修剪 `file_tracking` 键(`doc-block:…`、`svg-assets:…` 等),并删除其元数据文件路径指向缺失文件的翻译行;除非传递 `--no-backup`,否则会先备份 `cache.db`。
|
|
247
|
+
|
|
248
|
+
`translate-docs` 命令还使用 **文件跟踪**,因此未更改的源文件及其现有输出可以完全跳过工作。`--force-update` 在仍然使用段落缓存的同时重新运行文件处理;`--force` 清除文件跟踪并绕过段落缓存读取以进行 API 翻译。有关完整标志表,请参见 [入门](GETTING_STARTED.zh-CN.md#cache-behaviour-and-translate-docs-flags)。
|
|
249
|
+
|
|
250
|
+
**批量提示格式:** `translate-docs --prompt-format` 仅用于选择 `OpenRouterClient.translateDocumentBatch` 的 XML(`<seg>` / `<t>`)或 JSON 数组/对象格式;提取、占位符和验证保持不变。参见 [批量提示格式](GETTING_STARTED.zh-CN.md#batch-prompt-format)。
|
|
251
|
+
|
|
252
|
+
### 输出路径解析
|
|
253
|
+
|
|
254
|
+
`resolveDocumentationOutputPath(config, cwd, locale, relPath, kind)` 将源相对路径映射到输出路径:
|
|
255
|
+
|
|
256
|
+
- `nested` 风格(默认):Markdown 使用 `{outputDir}/{locale}/{relPath}`。
|
|
257
|
+
- `docusaurus` 风格:在 `docsRoot` 下,输出使用 `{outputDir}/{locale}/docusaurus-plugin-content-docs/current/{relativeToDocsRoot}`;在 `docsRoot` 外的路径回退到嵌套布局。
|
|
258
|
+
- `flat` 风格:`{outputDir}/{stem}.{locale}{extension}`。当 `flatPreserveRelativeDir` 为 `true` 时,源子目录将保留在 `outputDir` 下。
|
|
259
|
+
- **自定义** `pathTemplate`:使用 `{outputDir}`、`{locale}`、`{LOCALE}`、`{relPath}`、`{stem}`、`{basename}`、`{extension}`、`{docsRoot}`、`{relativeToDocsRoot}` 的任意 Markdown 布局。
|
|
260
|
+
- **自定义** `jsonPathTemplate`:为 JSON 标签文件设置的独立自定义布局,使用相同的占位符。
|
|
261
|
+
- `linkRewriteDocsRoot` 可帮助扁平链接重写器在翻译输出根目录不同于默认项目根目录时计算正确的前缀。
|
|
262
|
+
|
|
263
|
+
### 平面链接重写
|
|
264
|
+
|
|
265
|
+
当 `markdownOutput.style === "flat"` 时,翻译后的 markdown 文件与源文件并排放置,并带有语言后缀。页面之间的相对链接被重写,以便 `readme.de.md` 中的 `[Guide](../guide.md)` 指向 `guide.de.md`。由 `rewriteRelativeLinks` 控制(在没有自定义 `pathTemplate` 的平面风格下自动启用)。
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## 共享基础设施
|
|
270
|
+
|
|
271
|
+
### `OpenRouterClient`
|
|
272
|
+
|
|
273
|
+
封装 OpenRouter 聊天完成 API。关键行为:
|
|
274
|
+
|
|
275
|
+
- **模型回退**:按顺序尝试解析列表中的每个模型;在HTTP错误或解析失败时回退。UI翻译在存在时首先解析`ui.preferredModel`,然后是`openrouter`模型。
|
|
276
|
+
- **速率限制**:检测到429响应,等待`retry-after`(或2秒),重试一次。
|
|
277
|
+
- **提示缓存**:系统消息与`cache_control: { type: "ephemeral" }`一起发送,以启用对支持模型的提示缓存。
|
|
278
|
+
- **调试流量日志**:如果设置了`debugTrafficFilePath`,则将请求和响应JSON附加到文件中。
|
|
279
|
+
|
|
280
|
+
### 配置加载
|
|
281
|
+
|
|
282
|
+
`loadI18nConfigFromFile(configPath, cwd)`管道:
|
|
283
|
+
|
|
284
|
+
1. 读取并解析`ai-i18n-tools.config.json`(JSON)。
|
|
285
|
+
2. `mergeWithDefaults` - 与`defaultI18nConfigPartial`深度合并,并将任何`documentations[].sourceFiles`条目合并到`contentPaths`中。
|
|
286
|
+
3. `expandTargetLocalesFileReferenceInRawInput` - 如果`targetLocales`是文件路径,则加载清单并展开为区域代码;设置`uiLanguagesPath`。
|
|
287
|
+
4. `expandDocumentationTargetLocalesInRawInput` - 对每个`documentations[].targetLocales`条目执行相同操作。
|
|
288
|
+
5. `parseI18nConfig` - Zod验证 + `validateI18nBusinessRules`。
|
|
289
|
+
6. `applyEnvOverrides` - 应用`OPENROUTER_API_KEY`、`I18N_SOURCE_LOCALE`等。
|
|
290
|
+
7. `augmentConfigWithUiLanguagesFile` - 附加清单显示名称。
|
|
291
|
+
|
|
292
|
+
### 日志记录器
|
|
293
|
+
|
|
294
|
+
`Logger`支持`debug`、`info`、`warn`、`error`级别,并带有ANSI颜色输出。详细模式(`-v`)启用`debug`。当设置`logFilePath`时,日志行也会写入该文件。
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## 运行时助手API
|
|
299
|
+
|
|
300
|
+
这些从`'ai-i18n-tools/runtime'`导出,并在任何JavaScript环境中工作(浏览器、Node.js、Deno、Edge)。它们**不**从`i18next`或`react-i18next`导入。
|
|
301
|
+
|
|
302
|
+
### 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
|
+
### 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
|
+
### 显示助手
|
|
323
|
+
|
|
324
|
+
```ts
|
|
325
|
+
getUILanguageLabel(lang: UiLanguageEntry, t: TranslateFn): string
|
|
326
|
+
getUILanguageLabelNative(lang: UiLanguageEntry): string
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### 字符串助手
|
|
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
|
|
339
|
+
|
|
340
|
+
所有公共类型和类都从包根目录导出。示例:从Node.js运行translate-UI步骤而不使用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
|
+
关键导出:
|
|
361
|
+
|
|
362
|
+
| 导出 | 描述 |
|
|
363
|
+
|---|---|
|
|
364
|
+
| `loadI18nConfigFromFile` | 从JSON文件加载、合并、验证配置。 |
|
|
365
|
+
| `parseI18nConfig` | 验证原始配置对象。 |
|
|
366
|
+
| `TranslationCache` | SQLite缓存 - 使用`cacheDir`路径实例化。 |
|
|
367
|
+
| `UIStringExtractor` | 从JS/TS源提取`t("…")`字符串。 |
|
|
368
|
+
| `MarkdownExtractor` | 从markdown中提取可翻译的片段。 |
|
|
369
|
+
| `JsonExtractor` | 从Docusaurus JSON标签文件中提取。 |
|
|
370
|
+
| `SvgExtractor` | 从SVG文件中提取。 |
|
|
371
|
+
| `OpenRouterClient` | 向OpenRouter发送翻译请求。 |
|
|
372
|
+
| `PlaceholderHandler` | 保护/恢复翻译周围的markdown语法。 |
|
|
373
|
+
| `splitTranslatableIntoBatches` | 将片段分组为LLM大小的批次。 |
|
|
374
|
+
| `validateTranslation` | 翻译后的结构检查。 |
|
|
375
|
+
| `resolveDocumentationOutputPath` | 解析翻译文档的输出文件路径。 |
|
|
376
|
+
| `Glossary` / `GlossaryMatcher` | 加载和应用翻译词汇表。 |
|
|
377
|
+
| `runTranslateUI` | 编程翻译UI入口点。 |
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## 扩展点
|
|
382
|
+
|
|
383
|
+
### 自定义函数名称(UI提取)
|
|
384
|
+
|
|
385
|
+
通过配置添加非标准翻译函数名称:
|
|
386
|
+
|
|
387
|
+
```json
|
|
388
|
+
{
|
|
389
|
+
"ui": {
|
|
390
|
+
"reactExtractor": {
|
|
391
|
+
"funcNames": ["t", "i18n.t", "translate", "i18n.translate"]
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### 自定义提取器
|
|
398
|
+
|
|
399
|
+
从包中实现 `ContentExtractor`:
|
|
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
|
+
通过以编程方式导入 `doc-translate.ts` 工具,将其传递给文档翻译管道。
|
|
413
|
+
|
|
414
|
+
### 自定义输出路径
|
|
415
|
+
|
|
416
|
+
使用 `markdownOutput.pathTemplate` 进行任何文件布局:
|
|
417
|
+
|
|
418
|
+
```json
|
|
419
|
+
{
|
|
420
|
+
"documentations": [
|
|
421
|
+
{
|
|
422
|
+
"markdownOutput": {
|
|
423
|
+
"pathTemplate": "{outputDir}/{locale}/{relativeToDocsRoot}"
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
]
|
|
427
|
+
}
|
|
428
|
+
```
|