vite-plugin-ai-i18n 1.0.3 → 1.0.5

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/index.js CHANGED
@@ -1,20 +1,50 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var fs3 = require('fs');
6
- var path = require('path');
7
- var pc3 = require('picocolors');
8
- var openai = require('@langchain/openai');
9
- var messages = require('@langchain/core/messages');
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
10
29
 
11
- function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ default: () => index_default,
34
+ vitePluginAII18n: () => vitePluginAII18n
35
+ });
36
+ module.exports = __toCommonJS(index_exports);
37
+ var import_fs4 = __toESM(require("fs"));
38
+ var import_path4 = __toESM(require("path"));
39
+ var import_picocolors3 = __toESM(require("picocolors"));
12
40
 
13
- var fs3__default = /*#__PURE__*/_interopDefault(fs3);
14
- var path__default = /*#__PURE__*/_interopDefault(path);
15
- var pc3__default = /*#__PURE__*/_interopDefault(pc3);
41
+ // src/scanner.ts
42
+ var import_fs2 = __toESM(require("fs"));
43
+ var import_path2 = __toESM(require("path"));
16
44
 
17
- // src/index.ts
45
+ // src/utils.ts
46
+ var import_fs = __toESM(require("fs"));
47
+ var import_path = __toESM(require("path"));
18
48
  async function glob(patterns, excludePatterns) {
19
49
  const results = [];
20
50
  const cwd = process.cwd();
@@ -23,7 +53,7 @@ async function glob(patterns, excludePatterns) {
23
53
  results.push(...files);
24
54
  }
25
55
  return results.filter((file) => {
26
- const relativePath = path__default.default.relative(cwd, file);
56
+ const relativePath = import_path.default.relative(cwd, file);
27
57
  return !excludePatterns.some((p) => matchGlob(relativePath, p));
28
58
  });
29
59
  }
@@ -34,20 +64,20 @@ async function matchPattern(pattern, cwd) {
34
64
  if (hasGlobstar) {
35
65
  const baseDir = parts.slice(0, parts.indexOf("**")).join("/") || ".";
36
66
  const filePattern = parts.slice(parts.indexOf("**") + 1).join("/");
37
- await walkDir(path__default.default.join(cwd, baseDir), filePattern, results);
67
+ await walkDir(import_path.default.join(cwd, baseDir), filePattern, results);
38
68
  } else {
39
- const fullPath = path__default.default.join(cwd, pattern);
40
- if (fs3__default.default.existsSync(fullPath)) {
69
+ const fullPath = import_path.default.join(cwd, pattern);
70
+ if (import_fs.default.existsSync(fullPath)) {
41
71
  results.push(fullPath);
42
72
  }
43
73
  }
44
74
  return results;
45
75
  }
46
76
  async function walkDir(dir, pattern, results) {
47
- if (!fs3__default.default.existsSync(dir)) return;
48
- const entries = fs3__default.default.readdirSync(dir, { withFileTypes: true });
77
+ if (!import_fs.default.existsSync(dir)) return;
78
+ const entries = import_fs.default.readdirSync(dir, { withFileTypes: true });
49
79
  for (const entry of entries) {
50
- const fullPath = path__default.default.join(dir, entry.name);
80
+ const fullPath = import_path.default.join(dir, entry.name);
51
81
  if (entry.isDirectory()) {
52
82
  if (entry.name === "node_modules" || entry.name.startsWith(".")) {
53
83
  continue;
@@ -98,9 +128,9 @@ var I18nScanner = class {
98
128
  * 扫描单个文件
99
129
  */
100
130
  scanFile(filePath) {
101
- if (!fs3__default.default.existsSync(filePath)) return [];
102
- const content = fs3__default.default.readFileSync(filePath, "utf-8");
103
- const ext = path__default.default.extname(filePath);
131
+ if (!import_fs2.default.existsSync(filePath)) return [];
132
+ const content = import_fs2.default.readFileSync(filePath, "utf-8");
133
+ const ext = import_path2.default.extname(filePath);
104
134
  let texts = [];
105
135
  if (ext === ".vue") {
106
136
  texts = this.scanVueFile(content);
@@ -261,83 +291,88 @@ var I18nScanner = class {
261
291
  isValidText(text) {
262
292
  const debug = this.options.debug;
263
293
  if (text.length < 2) {
264
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u6587\u672C\u592A\u77ED`);
294
+ if (debug) console.log(`[过滤] "${text}" - 原因: 文本太短`);
265
295
  return false;
266
296
  }
267
297
  if (!/[\u4e00-\u9fa5]/.test(text)) {
268
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u4E0D\u5305\u542B\u4E2D\u6587`);
298
+ if (debug) console.log(`[过滤] "${text}" - 原因: 不包含中文`);
269
299
  return false;
270
300
  }
271
301
  if (/^\s*$/.test(text)) {
272
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u7EAF\u7A7A\u683C`);
302
+ if (debug) console.log(`[过滤] "${text}" - 原因: 纯空格`);
273
303
  return false;
274
304
  }
275
305
  if (/^\$t\(|^t\(|^i18n\.|_uni_app$|^[a-z_]+_[a-z_]+$/.test(text)) {
276
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: i18n key`);
306
+ if (debug) console.log(`[过滤] "${text}" - 原因: i18n key`);
277
307
  return false;
278
308
  }
279
309
  if (/^[⚠️❌✅🔍📝💡🎯🚀🔧📊]/.test(text)) {
280
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u7CFB\u7EDF\u63D0\u793A`);
310
+ if (debug) console.log(`[过滤] "${text}" - 原因: 系统提示`);
281
311
  return false;
282
312
  }
283
313
  if (/\.(json|js|ts|vue|md|txt|html|css|jsx|tsx)\s*(文件|不存在|已|错误)/.test(
284
314
  text
285
315
  )) {
286
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u6280\u672F\u672F\u8BED`);
316
+ if (debug) console.log(`[过滤] "${text}" - 原因: 技术术语`);
287
317
  return false;
288
318
  }
289
319
  if (/^[a-zA-Z0-9_\-\.]+\s*(文件|不存在|错误|失败)/.test(text)) {
290
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u6280\u672F\u9519\u8BEF\u4FE1\u606F`);
320
+ if (debug) console.log(`[过滤] "${text}" - 原因: 技术错误信息`);
291
321
  return false;
292
322
  }
293
323
  if (/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(text)) {
294
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u53D8\u91CF\u540D`);
324
+ if (debug) console.log(`[过滤] "${text}" - 原因: 变量名`);
295
325
  return false;
296
326
  }
297
327
  if (/^\/[a-zA-Z0-9_\-\/]*$/.test(text)) {
298
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u8DEF\u5F84`);
328
+ if (debug) console.log(`[过滤] "${text}" - 原因: 路径`);
299
329
  return false;
300
330
  }
301
331
  if (/^https?:\/\//.test(text)) {
302
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: URL`);
332
+ if (debug) console.log(`[过滤] "${text}" - 原因: URL`);
303
333
  return false;
304
334
  }
305
335
  if (/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/.test(text)) {
306
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u90AE\u7BB1`);
336
+ if (debug) console.log(`[过滤] "${text}" - 原因: 邮箱`);
307
337
  return false;
308
338
  }
309
339
  if (/^\d+$/.test(text)) {
310
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u7EAF\u6570\u5B57`);
340
+ if (debug) console.log(`[过滤] "${text}" - 原因: 纯数字`);
311
341
  return false;
312
342
  }
313
343
  if (/^\d{4}-\d{2}-\d{2}/.test(text)) {
314
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u65E5\u671F`);
344
+ if (debug) console.log(`[过滤] "${text}" - 原因: 日期`);
315
345
  return false;
316
346
  }
317
347
  if (/^(const|let|var|function|class|import|export|return)\s/.test(text)) {
318
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u4EE3\u7801\u7247\u6BB5`);
348
+ if (debug) console.log(`[过滤] "${text}" - 原因: 代码片段`);
319
349
  return false;
320
350
  }
321
351
  if (text.length > 100) {
322
- if (debug) console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u6587\u672C\u8FC7\u957F`);
352
+ if (debug) console.log(`[过滤] "${text}" - 原因: 文本过长`);
323
353
  return false;
324
354
  }
325
355
  const specialCharCount = (text.match(/[^\u4e00-\u9fa5a-zA-Z0-9\s,。!?、;:""''()《》]/g) || []).length;
326
356
  if (specialCharCount > text.length * 0.3) {
327
357
  if (debug)
328
- console.log(`[\u8FC7\u6EE4] "${text}" - \u539F\u56E0: \u7279\u6B8A\u5B57\u7B26\u8FC7\u591A (${specialCharCount})`);
358
+ console.log(`[过滤] "${text}" - 原因: 特殊字符过多 (${specialCharCount})`);
329
359
  return false;
330
360
  }
331
- if (debug) console.log(`[\u4FDD\u7559] "${text}"`);
361
+ if (debug) console.log(`[保留] "${text}"`);
332
362
  return true;
333
363
  }
334
364
  };
365
+
366
+ // src/translator.ts
367
+ var import_openai = require("@langchain/openai");
368
+ var import_messages = require("@langchain/core/messages");
369
+ var import_picocolors = __toESM(require("picocolors"));
335
370
  var I18nTranslator = class {
336
371
  constructor(options) {
337
372
  this.llm = null;
338
373
  this.options = options;
339
374
  if (options.apiKey) {
340
- this.llm = new openai.ChatOpenAI({
375
+ this.llm = new import_openai.ChatOpenAI({
341
376
  openAIApiKey: options.apiKey,
342
377
  configuration: { baseURL: options.apiUrl },
343
378
  modelName: options.model,
@@ -351,7 +386,7 @@ var I18nTranslator = class {
351
386
  */
352
387
  async translate(texts, sourceLocale, targetLocale, existingTranslations) {
353
388
  if (!this.llm) {
354
- console.warn(pc3__default.default.yellow("\u26A0\uFE0F \u672A\u914D\u7F6E API Key\uFF0C\u8DF3\u8FC7\u7FFB\u8BD1"));
389
+ console.warn(import_picocolors.default.yellow("⚠️ 未配置 API Key,跳过翻译"));
355
390
  const results2 = /* @__PURE__ */ new Map();
356
391
  for (const [file, fileTexts] of texts) {
357
392
  const textMap = /* @__PURE__ */ new Map();
@@ -374,19 +409,19 @@ var I18nTranslator = class {
374
409
  textsToTranslate.push(text);
375
410
  }
376
411
  });
377
- console.log(pc3__default.default.blue("\u{1F4CA} \u7FFB\u8BD1\u7EDF\u8BA1:"));
378
- console.log(` \u603B\u8BA1: ${pc3__default.default.cyan(uniqueTexts.length.toString())} \u6761`);
412
+ console.log(import_picocolors.default.blue("📊 翻译统计:"));
413
+ console.log(` 总计: ${import_picocolors.default.cyan(uniqueTexts.length.toString())} 条`);
379
414
  console.log(
380
- ` \u2705 \u5DF2\u6709: ${pc3__default.default.green(cachedTranslations.size.toString())} \u6761`
415
+ ` 已有: ${import_picocolors.default.green(cachedTranslations.size.toString())} 条`
381
416
  );
382
417
  console.log(
383
- ` \u{1F195} \u65B0\u589E: ${pc3__default.default.yellow(textsToTranslate.length.toString())} \u6761`
418
+ ` 🆕 新增: ${import_picocolors.default.yellow(textsToTranslate.length.toString())} 条`
384
419
  );
385
420
  try {
386
421
  let newTranslations = [];
387
422
  if (textsToTranslate.length > 0) {
388
- console.log(pc3__default.default.cyan(`
389
- \u{1F916} \u6B63\u5728\u7FFB\u8BD1\u65B0\u589E\u6587\u672C...`));
423
+ console.log(import_picocolors.default.cyan(`
424
+ 🤖 正在翻译新增文本...`));
390
425
  newTranslations = await this.batchTranslate(
391
426
  textsToTranslate,
392
427
  sourceLocale,
@@ -406,7 +441,7 @@ var I18nTranslator = class {
406
441
  }
407
442
  return results;
408
443
  } catch (error) {
409
- console.error(pc3__default.default.red("\u274C \u7FFB\u8BD1\u5931\u8D25:"), error.message);
444
+ console.error(import_picocolors.default.red(" 翻译失败:"), error.message);
410
445
  const results2 = /* @__PURE__ */ new Map();
411
446
  for (const [file, fileTexts] of texts) {
412
447
  const textMap = /* @__PURE__ */ new Map();
@@ -456,8 +491,8 @@ var I18nTranslator = class {
456
491
  results.push(...translated);
457
492
  const progress = Math.min(i + batchSize, texts.length);
458
493
  console.log(
459
- pc3__default.default.gray(
460
- ` \u{1F4CA} \u7FFB\u8BD1\u8FDB\u5EA6: ${pc3__default.default.cyan(progress.toString())}/${pc3__default.default.cyan(
494
+ import_picocolors.default.gray(
495
+ ` 📊 翻译进度: ${import_picocolors.default.cyan(progress.toString())}/${import_picocolors.default.cyan(
461
496
  texts.length.toString()
462
497
  )}`
463
498
  )
@@ -470,19 +505,19 @@ var I18nTranslator = class {
470
505
  */
471
506
  async translateBatch(texts, sourceLocale, targetLocale) {
472
507
  const localeName = this.getLocaleName(targetLocale);
473
- const systemPrompt = new messages.SystemMessage(
474
- `\u4F60\u662F\u4E13\u4E1A\u7684\u8F6F\u4EF6\u672C\u5730\u5316\u7FFB\u8BD1\u4E13\u5BB6\u3002\u8BF7\u5C06\u4EE5\u4E0B${this.getLocaleName(
508
+ const systemPrompt = new import_messages.SystemMessage(
509
+ `你是专业的软件本地化翻译专家。请将以下${this.getLocaleName(
475
510
  sourceLocale
476
- )}\u6587\u672C\u7FFB\u8BD1\u6210${localeName}\u3002
477
- \u8981\u6C42\uFF1A
478
- 1. \u4FDD\u6301\u4E13\u4E1A\u672F\u8BED\u7684\u51C6\u786E\u6027
479
- 2. \u7FFB\u8BD1\u8981\u81EA\u7136\u6D41\u7545\uFF0C\u7B26\u5408\u76EE\u6807\u8BED\u8A00\u4E60\u60EF
480
- 3. \u4FDD\u7559\u539F\u6587\u4E2D\u7684\u53D8\u91CF\u5360\u4F4D\u7B26\uFF08\u5982 {name}\u3001%s \u7B49\uFF09
481
- 4. \u6BCF\u884C\u4E00\u4E2A\u7FFB\u8BD1\uFF0C\u4E0E\u8F93\u5165\u987A\u5E8F\u4E25\u683C\u5BF9\u5E94
482
- 5. \u53EA\u8F93\u51FA\u7FFB\u8BD1\u7ED3\u679C\uFF0C\u4E0D\u8981\u89E3\u91CA
483
- 6. \u5982\u679C\u539F\u6587\u5305\u542B\u6362\u884C\uFF0C\u7FFB\u8BD1\u4E5F\u4FDD\u6301\u76F8\u540C\u7684\u6362\u884C`
511
+ )}文本翻译成${localeName}
512
+ 要求:
513
+ 1. 保持专业术语的准确性
514
+ 2. 翻译要自然流畅,符合目标语言习惯
515
+ 3. 保留原文中的变量占位符(如 {name}、%s 等)
516
+ 4. 每行一个翻译,与输入顺序严格对应
517
+ 5. 只输出翻译结果,不要解释
518
+ 6. 如果原文包含换行,翻译也保持相同的换行`
484
519
  );
485
- const userPrompt = new messages.HumanMessage(
520
+ const userPrompt = new import_messages.HumanMessage(
486
521
  texts.map((t, i) => `${i + 1}. ${t}`).join("\n")
487
522
  );
488
523
  const response = await this.llm.invoke([systemPrompt, userPrompt]);
@@ -504,21 +539,26 @@ var I18nTranslator = class {
504
539
  */
505
540
  getLocaleName(locale) {
506
541
  const names = {
507
- "zh-CN": "\u7B80\u4F53\u4E2D\u6587",
508
- "zh-TW": "\u7E41\u4F53\u4E2D\u6587",
509
- "en-US": "\u82F1\u8BED",
510
- "ja-JP": "\u65E5\u8BED",
511
- "ko-KR": "\u97E9\u8BED",
512
- "fr-FR": "\u6CD5\u8BED",
513
- "de-DE": "\u5FB7\u8BED",
514
- "es-ES": "\u897F\u73ED\u7259\u8BED",
515
- "pt-BR": "\u8461\u8404\u7259\u8BED",
516
- "ru-RU": "\u4FC4\u8BED",
517
- "ar-SA": "\u963F\u62C9\u4F2F\u8BED"
542
+ "zh-CN": "简体中文",
543
+ "zh-TW": "繁体中文",
544
+ "en-US": "英语",
545
+ "ja-JP": "日语",
546
+ "ko-KR": "韩语",
547
+ "fr-FR": "法语",
548
+ "de-DE": "德语",
549
+ "es-ES": "西班牙语",
550
+ "pt-BR": "葡萄牙语",
551
+ "ru-RU": "俄语",
552
+ "ar-SA": "阿拉伯语"
518
553
  };
519
554
  return names[locale] || locale;
520
555
  }
521
556
  };
557
+
558
+ // src/generator.ts
559
+ var import_fs3 = __toESM(require("fs"));
560
+ var import_path3 = __toESM(require("path"));
561
+ var import_picocolors2 = __toESM(require("picocolors"));
522
562
  var I18nGenerator = class {
523
563
  constructor(options) {
524
564
  this.options = options;
@@ -528,16 +568,16 @@ var I18nGenerator = class {
528
568
  */
529
569
  async generate(texts, locale) {
530
570
  const { localesDir } = this.options;
531
- if (!fs3__default.default.existsSync(localesDir)) {
532
- fs3__default.default.mkdirSync(localesDir, { recursive: true });
571
+ if (!import_fs3.default.existsSync(localesDir)) {
572
+ import_fs3.default.mkdirSync(localesDir, { recursive: true });
533
573
  }
534
- const filePath = path__default.default.join(localesDir, `${locale}.json`);
574
+ const filePath = import_path3.default.join(localesDir, `${locale}.json`);
535
575
  let existing = {};
536
- if (fs3__default.default.existsSync(filePath)) {
576
+ if (import_fs3.default.existsSync(filePath)) {
537
577
  try {
538
- existing = JSON.parse(fs3__default.default.readFileSync(filePath, "utf-8"));
578
+ existing = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
539
579
  } catch (e) {
540
- console.warn(pc3__default.default.yellow(`\u26A0\uFE0F \u65E0\u6CD5\u89E3\u6790\u73B0\u6709\u8BED\u8A00\u6587\u4EF6: ${filePath}`));
580
+ console.warn(import_picocolors2.default.yellow(`⚠️ 无法解析现有语言文件: ${filePath}`));
541
581
  }
542
582
  }
543
583
  const translations = { ...existing };
@@ -555,10 +595,10 @@ var I18nGenerator = class {
555
595
  obj[key] = translations[key];
556
596
  return obj;
557
597
  }, {});
558
- fs3__default.default.writeFileSync(filePath, JSON.stringify(sorted, null, 2), "utf-8");
559
- console.log(pc3__default.default.green(`\u2705 \u5DF2\u66F4\u65B0 ${pc3__default.default.cyan(locale)} \u8BED\u8A00\u6587\u4EF6: ${pc3__default.default.gray(filePath)}`));
598
+ import_fs3.default.writeFileSync(filePath, JSON.stringify(sorted, null, 2), "utf-8");
599
+ console.log(import_picocolors2.default.green(`✅ 已更新 ${import_picocolors2.default.cyan(locale)} 语言文件: ${import_picocolors2.default.gray(filePath)}`));
560
600
  if (newCount > 0) {
561
- console.log(pc3__default.default.gray(` \u65B0\u589E ${pc3__default.default.yellow(newCount.toString())} \u6761\u7FFB\u8BD1`));
601
+ console.log(import_picocolors2.default.gray(` 新增 ${import_picocolors2.default.yellow(newCount.toString())} 条翻译`));
562
602
  }
563
603
  }
564
604
  /**
@@ -566,16 +606,16 @@ var I18nGenerator = class {
566
606
  */
567
607
  async generateTranslated(originalTexts, translations, locale) {
568
608
  const { localesDir } = this.options;
569
- if (!fs3__default.default.existsSync(localesDir)) {
570
- fs3__default.default.mkdirSync(localesDir, { recursive: true });
609
+ if (!import_fs3.default.existsSync(localesDir)) {
610
+ import_fs3.default.mkdirSync(localesDir, { recursive: true });
571
611
  }
572
- const filePath = path__default.default.join(localesDir, `${locale}.json`);
612
+ const filePath = import_path3.default.join(localesDir, `${locale}.json`);
573
613
  let existing = {};
574
- if (fs3__default.default.existsSync(filePath)) {
614
+ if (import_fs3.default.existsSync(filePath)) {
575
615
  try {
576
- existing = JSON.parse(fs3__default.default.readFileSync(filePath, "utf-8"));
616
+ existing = JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
577
617
  } catch (e) {
578
- console.warn(pc3__default.default.yellow(`\u26A0\uFE0F \u65E0\u6CD5\u89E3\u6790\u73B0\u6709\u8BED\u8A00\u6587\u4EF6: ${filePath}`));
618
+ console.warn(import_picocolors2.default.yellow(`⚠️ 无法解析现有语言文件: ${filePath}`));
579
619
  }
580
620
  }
581
621
  const translationsObj = { ...existing };
@@ -596,13 +636,13 @@ var I18nGenerator = class {
596
636
  obj[key] = translationsObj[key];
597
637
  return obj;
598
638
  }, {});
599
- fs3__default.default.writeFileSync(filePath, JSON.stringify(sorted, null, 2), "utf-8");
600
- console.log(pc3__default.default.green(`\u2705 \u5DF2\u66F4\u65B0 ${pc3__default.default.cyan(locale)} \u8BED\u8A00\u6587\u4EF6: ${pc3__default.default.gray(filePath)}`));
639
+ import_fs3.default.writeFileSync(filePath, JSON.stringify(sorted, null, 2), "utf-8");
640
+ console.log(import_picocolors2.default.green(`✅ 已更新 ${import_picocolors2.default.cyan(locale)} 语言文件: ${import_picocolors2.default.gray(filePath)}`));
601
641
  if (newCount > 0) {
602
- console.log(pc3__default.default.gray(` \u2728 \u65B0\u589E ${pc3__default.default.yellow(newCount.toString())} \u6761\u7FFB\u8BD1`));
642
+ console.log(import_picocolors2.default.gray(` 新增 ${import_picocolors2.default.yellow(newCount.toString())} 条翻译`));
603
643
  }
604
644
  if (skippedCount > 0) {
605
- console.log(pc3__default.default.gray(` \u23ED\uFE0F \u8DF3\u8FC7 ${pc3__default.default.blue(skippedCount.toString())} \u6761\u5DF2\u6709\u7FFB\u8BD1`));
645
+ console.log(import_picocolors2.default.gray(` ⏭️ 跳过 ${import_picocolors2.default.blue(skippedCount.toString())} 条已有翻译`));
606
646
  }
607
647
  }
608
648
  /**
@@ -610,12 +650,12 @@ var I18nGenerator = class {
610
650
  */
611
651
  loadExistingTranslations(locale) {
612
652
  const { localesDir } = this.options;
613
- const filePath = path__default.default.join(localesDir, `${locale}.json`);
614
- if (fs3__default.default.existsSync(filePath)) {
653
+ const filePath = import_path3.default.join(localesDir, `${locale}.json`);
654
+ if (import_fs3.default.existsSync(filePath)) {
615
655
  try {
616
- return JSON.parse(fs3__default.default.readFileSync(filePath, "utf-8"));
656
+ return JSON.parse(import_fs3.default.readFileSync(filePath, "utf-8"));
617
657
  } catch (e) {
618
- console.warn(pc3__default.default.yellow(`\u26A0\uFE0F \u65E0\u6CD5\u89E3\u6790\u73B0\u6709\u8BED\u8A00\u6587\u4EF6: ${filePath}`));
658
+ console.warn(import_picocolors2.default.yellow(`⚠️ 无法解析现有语言文件: ${filePath}`));
619
659
  }
620
660
  }
621
661
  return {};
@@ -668,52 +708,52 @@ function vitePluginAII18n(options = {}) {
668
708
  name: "vite-plugin-ai-i18n",
669
709
  enforce: "pre",
670
710
  configResolved(config) {
671
- const fullLocalesDir = path__default.default.resolve(config.root, localesDir);
672
- if (!fs3__default.default.existsSync(fullLocalesDir)) {
673
- fs3__default.default.mkdirSync(fullLocalesDir, { recursive: true });
711
+ const fullLocalesDir = import_path4.default.resolve(config.root, localesDir);
712
+ if (!import_fs4.default.existsSync(fullLocalesDir)) {
713
+ import_fs4.default.mkdirSync(fullLocalesDir, { recursive: true });
674
714
  }
675
715
  const allLocales = [defaultLocale, ...targetLocales];
676
716
  for (const locale of allLocales) {
677
- const filePath = path__default.default.join(fullLocalesDir, `${locale}.json`);
678
- if (!fs3__default.default.existsSync(filePath)) {
679
- fs3__default.default.writeFileSync(filePath, "{}", "utf-8");
717
+ const filePath = import_path4.default.join(fullLocalesDir, `${locale}.json`);
718
+ if (!import_fs4.default.existsSync(filePath)) {
719
+ import_fs4.default.writeFileSync(filePath, "{}", "utf-8");
680
720
  console.log(
681
- pc3__default.default.green(
682
- `\u2705 \u5DF2\u751F\u6210 ${pc3__default.default.cyan(locale)} \u8BED\u8A00\u6587\u4EF6: ${pc3__default.default.gray(
721
+ import_picocolors3.default.green(
722
+ `✅ 已生成 ${import_picocolors3.default.cyan(locale)} 语言文件: ${import_picocolors3.default.gray(
683
723
  `src\\locales\\${locale}.json`
684
724
  )}`
685
725
  )
686
726
  );
687
727
  }
688
728
  }
689
- console.log(pc3__default.default.cyan("\n\u{1F30D} AI \u56FD\u9645\u5316\u52A9\u624B\u5DF2\u542F\u52A8..."));
690
- console.log(`\u{1F4C2} \u8BED\u8A00\u6587\u4EF6\u76EE\u5F55: ${pc3__default.default.yellow(localesDir)}`);
691
- console.log(`\u{1F524} \u9ED8\u8BA4\u8BED\u8A00: ${pc3__default.default.cyan(defaultLocale)}`);
692
- console.log(`\u{1F3AF} \u76EE\u6807\u8BED\u8A00: ${pc3__default.default.cyan(targetLocales.join(", "))}`);
693
- console.log(`\u{1F50D} \u81EA\u52A8\u626B\u63CF: ${autoScan ? pc3__default.default.green("\u2705") : pc3__default.default.red("\u274C")}`);
729
+ console.log(import_picocolors3.default.cyan("\n🌍 AI 国际化助手已启动..."));
730
+ console.log(`📂 语言文件目录: ${import_picocolors3.default.yellow(localesDir)}`);
731
+ console.log(`🔤 默认语言: ${import_picocolors3.default.cyan(defaultLocale)}`);
732
+ console.log(`🎯 目标语言: ${import_picocolors3.default.cyan(targetLocales.join(", "))}`);
733
+ console.log(`🔍 自动扫描: ${autoScan ? import_picocolors3.default.green("") : import_picocolors3.default.red("")}`);
694
734
  console.log(
695
- `\u{1F916} \u81EA\u52A8\u7FFB\u8BD1: ${autoTranslate ? pc3__default.default.green("\u2705") : pc3__default.default.red("\u274C")}`
735
+ `🤖 自动翻译: ${autoTranslate ? import_picocolors3.default.green("") : import_picocolors3.default.red("")}`
696
736
  );
697
737
  console.log(
698
- `\u{1F511} API Key: ${apiKey ? pc3__default.default.green("\u5DF2\u914D\u7F6E") : pc3__default.default.yellow("\u672A\u914D\u7F6E")}
738
+ `🔑 API Key: ${apiKey ? import_picocolors3.default.green("已配置") : import_picocolors3.default.yellow("未配置")}
699
739
  `
700
740
  );
701
741
  },
702
742
  async buildStart() {
703
743
  if (!autoScan) return;
704
- console.log(pc3__default.default.cyan("\u{1F50D} \u6B63\u5728\u626B\u63CF\u4E2D\u6587\u6587\u672C...\n"));
744
+ console.log(import_picocolors3.default.cyan("🔍 正在扫描中文文本...\n"));
705
745
  scannedTexts = await scanner.scan();
706
746
  const totalTexts = Array.from(scannedTexts.values()).flat().length;
707
747
  console.log(
708
- pc3__default.default.blue(`\u{1F4DD} \u53D1\u73B0 ${pc3__default.default.yellow(totalTexts.toString())} \u6761\u5F85\u7FFB\u8BD1\u6587\u672C
748
+ import_picocolors3.default.blue(`📝 发现 ${import_picocolors3.default.yellow(totalTexts.toString())} 条待翻译文本
709
749
  `)
710
750
  );
711
751
  if (totalTexts === 0) return;
712
752
  await generator.generate(scannedTexts, defaultLocale);
713
753
  if (autoTranslate && apiKey) {
714
754
  for (const locale of targetLocales) {
715
- console.log(pc3__default.default.cyan(`
716
- \u{1F310} \u6B63\u5728\u7FFB\u8BD1\u5230 ${pc3__default.default.yellow(locale)}...`));
755
+ console.log(import_picocolors3.default.cyan(`
756
+ 🌐 正在翻译到 ${import_picocolors3.default.yellow(locale)}...`));
717
757
  const existingTranslations = generator.loadExistingTranslations(locale);
718
758
  const translations = await translator.translate(
719
759
  scannedTexts,
@@ -728,7 +768,7 @@ function vitePluginAII18n(options = {}) {
728
768
  );
729
769
  }
730
770
  }
731
- console.log(pc3__default.default.green("\n\u2728 \u56FD\u9645\u5316\u5904\u7406\u5B8C\u6210\n"));
771
+ console.log(import_picocolors3.default.green("\n 国际化处理完成\n"));
732
772
  },
733
773
  // 监听文件变化,增量更新
734
774
  async handleHotUpdate({ file, server }) {
@@ -736,10 +776,10 @@ function vitePluginAII18n(options = {}) {
736
776
  if (!file.match(/\.(vue|ts|tsx)$/)) return;
737
777
  if (file.includes("node_modules") || file.includes(localesDir)) return;
738
778
  console.log(`
739
- \u{1F504} \u68C0\u6D4B\u5230\u6587\u4EF6\u53D8\u5316: ${file}`);
779
+ 🔄 检测到文件变化: ${file}`);
740
780
  const texts = scanner.scanFile(file);
741
781
  if (texts.length > 0) {
742
- console.log(`\u{1F4DD} \u53D1\u73B0 ${texts.length} \u6761\u65B0\u6587\u672C`);
782
+ console.log(`📝 发现 ${texts.length} 条新文本`);
743
783
  scannedTexts.set(file, texts);
744
784
  await generator.generate(scannedTexts, defaultLocale);
745
785
  if (autoTranslate && apiKey) {
@@ -764,8 +804,8 @@ function vitePluginAII18n(options = {}) {
764
804
  };
765
805
  }
766
806
  var index_default = vitePluginAII18n;
767
-
768
- exports.default = index_default;
769
- exports.vitePluginAII18n = vitePluginAII18n;
770
- //# sourceMappingURL=index.js.map
807
+ // Annotate the CommonJS export names for ESM import in node:
808
+ 0 && (module.exports = {
809
+ vitePluginAII18n
810
+ });
771
811
  //# sourceMappingURL=index.js.map