ai-yuca 1.4.6 → 1.4.7

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/dist/bin/cli.js CHANGED
@@ -45,6 +45,7 @@ const download_1 = require("../src/download");
45
45
  const uploadWithConfig_1 = require("../src/uploadWithConfig");
46
46
  const deploy_1 = require("../src/deploy");
47
47
  const transKey_1 = require("../src/transKey");
48
+ const useTrans_1 = require("../src/useTrans");
48
49
  const tinify_1 = require("../src/tinify");
49
50
  const pullCrowdin_1 = require("../src/pullCrowdin");
50
51
  const sharp_1 = require("../src/sharp");
@@ -399,6 +400,14 @@ program
399
400
  .action(async (options) => {
400
401
  await (0, transKey_1.transKey)(options);
401
402
  });
403
+ // 添加 useTrans 命令
404
+ program
405
+ .command('useTrans')
406
+ .description('将 un-trans.json 中的翻译合并到 source 目录中')
407
+ .option('-c, --config <path>', '指定配置文件路径(默认为项目根目录下的vs.config.json)')
408
+ .action(async (options) => {
409
+ await (0, useTrans_1.useTrans)(options);
410
+ });
402
411
  // 添加pull-crowdin命令
403
412
  program
404
413
  .command('cr-pull')
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-yuca",
3
- "version": "1.4.6",
3
+ "version": "1.4.7",
4
4
  "description": "一个用AI生成的开发辅助工具",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
@@ -40,6 +40,7 @@ exports.transKey = transKey;
40
40
  const fs = __importStar(require("fs"));
41
41
  const path = __importStar(require("path"));
42
42
  const fast_glob_1 = __importDefault(require("fast-glob"));
43
+ // {#测试的内容#}
43
44
  async function transKey(options) {
44
45
  try {
45
46
  // 1. 读取配置文件
@@ -109,6 +110,7 @@ async function transKey(options) {
109
110
  // 旧文件目录:Obj.crowdin.keysDir
110
111
  const oldFilesDir = path.join(process.cwd(), keysDir);
111
112
  // 4. 遍历语言生成文件
113
+ const untranslatedKeys = {};
112
114
  for (const lang of langMap) {
113
115
  const fileName = `${lang}.json`;
114
116
  const outputPath = path.join(outputDir, fileName);
@@ -151,6 +153,7 @@ async function transKey(options) {
151
153
  const newData = {};
152
154
  const sortedKeys = Array.from(keys).sort();
153
155
  let matchedCount = 0;
156
+ untranslatedKeys[lang] = {};
154
157
  for (const key of sortedKeys) {
155
158
  // 优先使用整合后的 oldData
156
159
  if (oldData[key]) {
@@ -159,12 +162,66 @@ async function transKey(options) {
159
162
  }
160
163
  else {
161
164
  newData[key] = '';
165
+ // 记录未翻译的词条
166
+ untranslatedKeys[lang][key] = "";
162
167
  }
163
168
  }
164
169
  // 写入文件到 source 目录
165
170
  fs.writeFileSync(outputPath, JSON.stringify(newData, null, 2), 'utf8');
166
171
  console.log(`✅ 生成 ${fileName}: 总 Key 数 ${sortedKeys.length}, 已翻译 ${matchedCount}`);
167
172
  }
173
+ // 5. 生成未翻译词条文件 (un-trans.json)
174
+ // 根据需求 "un-trans.json 存放在 source 中"
175
+ const untransPath = path.join(outputDir, 'un-trans.json');
176
+ let existingUntransData = {};
177
+ // 读取 un-trans.json 的存量数据
178
+ if (fs.existsSync(untransPath)) {
179
+ try {
180
+ existingUntransData = JSON.parse(fs.readFileSync(untransPath, 'utf8'));
181
+ }
182
+ catch (e) {
183
+ console.warn(`无法解析 un-trans.json: ${e}`);
184
+ }
185
+ }
186
+ // 合并新旧未翻译数据(保留旧数据)
187
+ // 逻辑:以新的 untranslatedKeys 为主,如果旧数据里有该语言该key且有值(虽然理论上未翻译文件里的值应该是空的,但也许用户手动填了?),
188
+ // 还是保留空值,因为既然在 source 里没值,说明还是未翻译。
189
+ // 但用户说 "每次执行这个操作前这个文件的存量数据",意思是把新生成的未翻译数据和旧的合并?
190
+ // 通常 un-trans.json 只是一个报告文件。
191
+ // 如果用户想保留 un-trans.json 里的数据,可能是想看累计的未翻译?
192
+ // 但如果某个 key 在本次运行中已经翻译了(在 oldData 中有值),它就不应该出现在 un-trans.json 中了。
193
+ // 所以,un-trans.json 应该只包含当前真正未翻译的 key。
194
+ // "存量数据" 可能指的是:如果 un-trans.json 里有一些 key 是本次扫描没扫到的(比如代码删了),是否要保留?
195
+ // 或者,用户只是想把新发现的未翻译 key 合并进去?
196
+ // 根据需求 "每次执行这个操作前这个文件的存量数据" -> 可能是指读取它,然后做某种合并。
197
+ // 但最合理的逻辑是:un-trans.json 应该反映当前的未翻译状态。
198
+ // 如果 key 在代码中存在且未翻译 -> 写入 un-trans.json
199
+ // 如果 key 在代码中不存在 -> 不写入
200
+ // 如果 key 已翻译 -> 不写入
201
+ // 但既然提到了 "存量数据",我将采用以下策略:
202
+ // 1. 读取旧 un-trans.json
203
+ // 2. 将本次检测到的未翻译 key 合并进去 (如果旧文件里有额外的内容,保留之?不,这会导致废弃 key 堆积)
204
+ // 让我们假设 "存量数据" 是指保留那些在本次扫描中依然未翻译的条目,或者仅仅是做一次全量覆盖?
205
+ // 如果是全量覆盖,那就不需要读取存量数据了。
206
+ // 既然明确要求 "每次执行这个操作前这个文件的存量数据",那我就把旧数据读出来,
207
+ // 然后把本次的未翻译数据合并进去(覆盖旧的)。
208
+ // 修正:按照 "un-trans.json" 的通常用途,它应该是“当前未翻译词条的快照”。
209
+ // 但为了满足 "保留存量数据" 的字面意思,我会把旧数据 merge 进去。
210
+ // 比如:旧数据有 { "en": { "A": "" } },本次扫描发现 { "en": { "B": "" } }
211
+ // 结果是 { "en": { "A": "", "B": "" } }
212
+ // 风险:如果 "A" 已经在代码中删除了,它还会留在 un-trans.json 中。
213
+ const finalUntransData = { ...existingUntransData };
214
+ for (const lang of langMap) {
215
+ if (!finalUntransData[lang]) {
216
+ finalUntransData[lang] = {};
217
+ }
218
+ // 合并当前未翻译的
219
+ for (const key in untranslatedKeys[lang]) {
220
+ finalUntransData[lang][key] = "";
221
+ }
222
+ }
223
+ fs.writeFileSync(untransPath, JSON.stringify(finalUntransData, null, 2), 'utf8');
224
+ console.log(`\n📋 未翻译词条已导出至: ${untransPath}`);
168
225
  console.log('\n所有文件生成完毕!');
169
226
  }
170
227
  catch (err) {
@@ -0,0 +1,5 @@
1
+ interface UseTransOptions {
2
+ config?: string;
3
+ }
4
+ export declare function useTrans(options: UseTransOptions): Promise<void>;
5
+ export {};
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.useTrans = useTrans;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const chalk_1 = __importDefault(require("chalk"));
43
+ async function useTrans(options) {
44
+ try {
45
+ // 1. 读取配置文件
46
+ const configPath = options.config || path.join(process.cwd(), 'vs.config.json');
47
+ if (!fs.existsSync(configPath)) {
48
+ throw new Error(`配置文件不存在: ${configPath}`);
49
+ }
50
+ console.log(`读取配置文件: ${configPath}`);
51
+ const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
52
+ const crowdinConfig = config.crowdin;
53
+ if (!crowdinConfig) {
54
+ throw new Error('配置文件中缺少 crowdin 配置');
55
+ }
56
+ const { keysDir, langMap } = crowdinConfig;
57
+ if (!keysDir || !langMap) {
58
+ throw new Error('crowdin 配置缺少必要字段: keysDir, langMap');
59
+ }
60
+ // source 目录: keysDir/source
61
+ const sourceDir = path.join(process.cwd(), keysDir, 'source');
62
+ // 根据需求 "un-trans.json 存放在 source 中"
63
+ const untransPath = path.join(sourceDir, 'un-trans.json');
64
+ if (!fs.existsSync(untransPath)) {
65
+ console.log(chalk_1.default.yellow(`未找到未翻译文件: ${untransPath}`));
66
+ return;
67
+ }
68
+ console.log(chalk_1.default.blue(`读取未翻译文件: ${untransPath}`));
69
+ let untransData = {};
70
+ try {
71
+ untransData = JSON.parse(fs.readFileSync(untransPath, 'utf8'));
72
+ }
73
+ catch (e) {
74
+ throw new Error(`解析 un-trans.json 失败: ${e}`);
75
+ }
76
+ // 2. 遍历语言并合并
77
+ for (const lang of langMap) {
78
+ // untransData 中的 key 就是 lang
79
+ const langUntrans = untransData[lang];
80
+ if (!langUntrans) {
81
+ console.log(chalk_1.default.gray(` - 未找到语言 ${lang} 的未翻译数据,跳过`));
82
+ continue;
83
+ }
84
+ const fileName = `${lang}.json`;
85
+ const sourceFilePath = path.join(sourceDir, fileName);
86
+ if (!fs.existsSync(sourceFilePath)) {
87
+ console.log(chalk_1.default.yellow(`源文件不存在,跳过: ${fileName}`));
88
+ continue;
89
+ }
90
+ console.log(`处理语言: ${lang}`);
91
+ let sourceData = {};
92
+ try {
93
+ sourceData = JSON.parse(fs.readFileSync(sourceFilePath, 'utf8'));
94
+ }
95
+ catch (e) {
96
+ console.error(chalk_1.default.red(`无法解析源文件 ${fileName}: ${e}`));
97
+ continue;
98
+ }
99
+ let mergedCount = 0;
100
+ for (const key in langUntrans) {
101
+ // 如果 un-trans.json 中有值(用户已翻译)
102
+ const transValue = langUntrans[key];
103
+ if (transValue && transValue.trim() !== '') {
104
+ // 如果 sourceData 里有这个 key,我们就更新它。
105
+ if (Object.prototype.hasOwnProperty.call(sourceData, key)) {
106
+ sourceData[key] = transValue;
107
+ mergedCount++;
108
+ }
109
+ else {
110
+ // 如果 sourceData 里没有,我们选择添加进去。
111
+ sourceData[key] = transValue;
112
+ mergedCount++;
113
+ }
114
+ }
115
+ }
116
+ if (mergedCount > 0) {
117
+ fs.writeFileSync(sourceFilePath, JSON.stringify(sourceData, null, 2), 'utf8');
118
+ console.log(chalk_1.default.green(` ✓ 已合并 ${mergedCount} 条翻译到 ${fileName}`));
119
+ }
120
+ else {
121
+ console.log(chalk_1.default.gray(` - 无需合并 (未翻译文件中没有已翻译的值)`));
122
+ }
123
+ }
124
+ console.log(chalk_1.default.blue('\n合并完成!'));
125
+ console.log(chalk_1.default.yellow('注意:合并后的更改目前只在 source 目录中。下次运行 transKey 时,这些更改会被整合回 keysDir 主文件。'));
126
+ }
127
+ catch (err) {
128
+ console.error(chalk_1.default.red(`UseTrans 操作失败: ${err instanceof Error ? err.message : String(err)}`));
129
+ process.exit(1);
130
+ }
131
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-yuca",
3
- "version": "1.4.6",
3
+ "version": "1.4.7",
4
4
  "description": "一个用AI生成的开发辅助工具",
5
5
  "main": "dist/src/index.js",
6
6
  "types": "dist/src/index.d.ts",
package/un-trans.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "zh-cn": {
3
+ "测试的内容": ""
4
+ },
5
+ "en-us": {
6
+ "测试的内容": ""
7
+ },
8
+ "de-de": {
9
+ "测试的内容": ""
10
+ },
11
+ "pt-pt": {
12
+ "测试的内容": ""
13
+ },
14
+ "fr-fr": {
15
+ "测试的内容": ""
16
+ },
17
+ "es-es": {
18
+ "测试的内容": ""
19
+ },
20
+ "it-it": {
21
+ "测试的内容": ""
22
+ },
23
+ "ru-ru": {
24
+ "测试的内容": ""
25
+ }
26
+ }