vite-gc-i18n-plugin 1.1.5 → 1.1.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/index.cjs CHANGED
@@ -7,10 +7,10 @@ var tunnel = require('tunnel');
7
7
  var axios = require('axios');
8
8
  var CryptoJS = require('crypto-js');
9
9
  var OpenCC = require('opencc-js');
10
+ var fs = require('node:fs');
11
+ var path = require('node:path');
10
12
  var types = require('@babel/types');
11
13
  var _ = require('lodash');
12
- var path = require('node:path');
13
- var fs = require('node:fs');
14
14
  var babel = require('@babel/core');
15
15
  var generate = require('@babel/generator');
16
16
 
@@ -1313,11 +1313,32 @@ var file = /*#__PURE__*/Object.freeze({
1313
1313
  const SEPARATOR = '\n┇┇┇\n';
1314
1314
  const SPLIT_SEPARATOR_REGEX = /\n┇ *┇ *┇\n/;
1315
1315
  let langObj = {};
1316
- function getLangKeyByValue(value) {
1317
- return Object.entries(langObj).find(_ref => {
1316
+ function normalizeValueForDedupe(value) {
1317
+ return String(value || '').trim();
1318
+ }
1319
+ function findKeyByValue(valueMap, value) {
1320
+ const exactKey = Object.entries(valueMap).find(_ref => {
1318
1321
  let [, oldValue] = _ref;
1319
1322
  return oldValue === value;
1320
1323
  })?.[0];
1324
+ if (exactKey) return exactKey;
1325
+ const normalizedValue = normalizeValueForDedupe(value);
1326
+ return Object.entries(valueMap).find(_ref2 => {
1327
+ let [, oldValue] = _ref2;
1328
+ return normalizeValueForDedupe(oldValue) === normalizedValue;
1329
+ })?.[0];
1330
+ }
1331
+ function getExistingOriginLangObj() {
1332
+ try {
1333
+ const filePath = path.join(exports.option.globalPath, 'index.json');
1334
+ if (!fs.existsSync(filePath)) return {};
1335
+ return getLangObjByJSONFileWithLangKey(exports.option.originLang);
1336
+ } catch (error) {
1337
+ return {};
1338
+ }
1339
+ }
1340
+ function getLangKeyByValue(value) {
1341
+ return findKeyByValue(langObj, value) || findKeyByValue(getExistingOriginLangObj(), value);
1321
1342
  }
1322
1343
  function resolveLangKey(key, value) {
1323
1344
  return getLangKeyByValue(value) || key;
@@ -1325,14 +1346,30 @@ function resolveLangKey(key, value) {
1325
1346
  function isTemplateValue(value) {
1326
1347
  return /\$\{[^}]+}/.test(value);
1327
1348
  }
1328
- function getTemplateStaticSegments(value) {
1329
- return value.split(/\$\{[^}]+}/g).filter(item => item);
1349
+ function hasOriginSymbols$1(value) {
1350
+ const originRegex = REGEX_MAP[exports.option.originLang];
1351
+ return originRegex ? originRegex.test(value) : false;
1352
+ }
1353
+ function getTemplateSemanticSplitSegments(value) {
1354
+ const segments = value.split(/\$\{[^}]+}/g);
1355
+ const result = new Set();
1356
+ for (let index = 0; index < segments.length - 1; index++) {
1357
+ const beforeValue = segments[index];
1358
+ const afterValue = segments[index + 1];
1359
+ if (!hasOriginSymbols$1(beforeValue) || !hasOriginSymbols$1(afterValue)) continue;
1360
+ [beforeValue, afterValue].forEach(segment => {
1361
+ if (segment.trim().length > 1) {
1362
+ result.add(segment);
1363
+ }
1364
+ });
1365
+ }
1366
+ return [...result];
1330
1367
  }
1331
1368
  function isTemplateStaticSegment(value) {
1332
- return Object.values(langObj).some(oldValue => isTemplateValue(oldValue) && getTemplateStaticSegments(oldValue).includes(value));
1369
+ return Object.values(langObj).some(oldValue => isTemplateValue(oldValue) && getTemplateSemanticSplitSegments(oldValue).includes(value));
1333
1370
  }
1334
1371
  function removeTemplateStaticSegments(value) {
1335
- const segments = new Set(getTemplateStaticSegments(value));
1372
+ const segments = new Set(getTemplateSemanticSplitSegments(value));
1336
1373
  Object.keys(langObj).forEach(key => {
1337
1374
  if (segments.has(langObj[key])) {
1338
1375
  delete langObj[key];
@@ -1360,6 +1397,22 @@ function setLangObj(key, value) {
1360
1397
  langObj[key] = value;
1361
1398
  }
1362
1399
  }
1400
+ function dedupeLangObjMapByOriginValue(originLangObjMap) {
1401
+ const originMap = originLangObjMap[exports.option.originLang];
1402
+ const valueKeyMap = new Map();
1403
+ Object.keys(originMap).forEach(key => {
1404
+ const value = originMap[key];
1405
+ const normalizedValue = normalizeValueForDedupe(value);
1406
+ const existingKey = valueKeyMap.get(normalizedValue);
1407
+ if (!existingKey) {
1408
+ valueKeyMap.set(normalizedValue, key);
1409
+ return;
1410
+ }
1411
+ exports.option.langKey.forEach(lang => {
1412
+ delete originLangObjMap[lang][key];
1413
+ });
1414
+ });
1415
+ }
1363
1416
 
1364
1417
  /**
1365
1418
  * @description: 读取翻译对象
@@ -1461,6 +1514,7 @@ async function autoTranslate() {
1461
1514
  originLangObjMap[item][key] = newLangObjMap[item][index];
1462
1515
  });
1463
1516
  });
1517
+ dedupeLangObjMapByOriginValue(originLangObjMap);
1464
1518
 
1465
1519
  // ─── 生成最终配置文件结构 ───
1466
1520
  console.log('📄 构建配置文件数据结构...');
@@ -2374,6 +2428,9 @@ function handleTemplateLiteralWithExpressions(node, path) {
2374
2428
  }
2375
2429
  return false;
2376
2430
  }
2431
+ if (!hasExpressionInsideOriginContent(node)) {
2432
+ return false;
2433
+ }
2377
2434
  const {
2378
2435
  trimmedValue,
2379
2436
  valStr
@@ -2384,6 +2441,24 @@ function handleTemplateLiteralWithExpressions(node, path) {
2384
2441
  setLangObj(id, trimmedValue);
2385
2442
  return true;
2386
2443
  }
2444
+ function hasExpressionInsideOriginContent(node) {
2445
+ return node.expressions.some((_, index) => {
2446
+ const beforeValue = node.quasis.slice(0, index + 1).map(getTemplateElementValue).join('');
2447
+ const afterValue = node.quasis.slice(index + 1).map(getTemplateElementValue).join('');
2448
+ return hasOriginSymbols(beforeValue) && hasOriginSymbols(afterValue);
2449
+ });
2450
+ }
2451
+ function getTemplateElementValue(quasi) {
2452
+ let value = quasi.value.raw || quasi.value.cooked || '';
2453
+ if (asianLangs.some(lang => exports.option.originLang.includes(lang) || exports.option.originLang === lang)) {
2454
+ try {
2455
+ value = unicodeToString(value);
2456
+ } catch (error) {
2457
+ console.log('转换异常');
2458
+ }
2459
+ }
2460
+ return value;
2461
+ }
2387
2462
  function getExpressionPlaceholder(expression) {
2388
2463
  if (types.isStringLiteral(expression) || types.isNumericLiteral(expression)) {
2389
2464
  return String(expression.value);
@@ -2477,6 +2552,9 @@ function createTemplateLiteralTranslateCall(node) {
2477
2552
  if (!fullValue || !hasOriginSymbols(fullValue) || !exports.option.excludedPattern.length || checkAgainstRegexArray(fullValue, [...exports.option.excludedPattern])) {
2478
2553
  return null;
2479
2554
  }
2555
+ if (!hasExpressionInsideOriginContent(node)) {
2556
+ return createTemplateLiteralWithTranslatedQuasis(node, expressions);
2557
+ }
2480
2558
  const {
2481
2559
  trimmedValue,
2482
2560
  valStr
@@ -2487,6 +2565,40 @@ function createTemplateLiteralTranslateCall(node) {
2487
2565
  }
2488
2566
  return createTranslateCall(id, valStr, expressionLabels, expressions);
2489
2567
  }
2568
+ function createTemplateLiteralWithTranslatedQuasis(node, expressions) {
2569
+ const quasis = [];
2570
+ const nextExpressions = [];
2571
+ let pendingText = '';
2572
+ let hasTranslatedQuasi = false;
2573
+ node.quasis.forEach((quasi, index) => {
2574
+ const value = getTemplateElementValue(quasi);
2575
+ if (value && hasOriginSymbols(value) && exports.option.excludedPattern.length && !checkAgainstRegexArray(value, [...exports.option.excludedPattern])) {
2576
+ quasis.push(types.templateElement({
2577
+ raw: pendingText,
2578
+ cooked: pendingText
2579
+ }, false));
2580
+ nextExpressions.push(createTrackedTranslateCall(value));
2581
+ pendingText = '';
2582
+ hasTranslatedQuasi = true;
2583
+ } else {
2584
+ pendingText += value;
2585
+ }
2586
+ if (index < expressions.length) {
2587
+ quasis.push(types.templateElement({
2588
+ raw: pendingText,
2589
+ cooked: pendingText
2590
+ }, false));
2591
+ nextExpressions.push(types.cloneNode(expressions[index]));
2592
+ pendingText = '';
2593
+ }
2594
+ });
2595
+ if (!hasTranslatedQuasi) return null;
2596
+ quasis.push(types.templateElement({
2597
+ raw: pendingText,
2598
+ cooked: pendingText
2599
+ }, true));
2600
+ return types.templateLiteral(quasis, nextExpressions);
2601
+ }
2490
2602
  function getConditionalExpressionLabel(expression) {
2491
2603
  const test = expression.test;
2492
2604
  if (types.isBinaryExpression(test) || types.isLogicalExpression(test)) {
@@ -2626,12 +2738,22 @@ function translateSetLang(node) {
2626
2738
  let arg = node.arguments || [];
2627
2739
  // 提取参数作为值
2628
2740
  // 检查参数是否为字符串字面量
2629
- const id = types__namespace.isStringLiteral(arg[0]) ? arg[0].value : '';
2630
- const value = types__namespace.isStringLiteral(arg[1]) ? arg[1].value : '';
2741
+ const idArg = arg[0];
2742
+ const valueArg = arg[1];
2743
+ const id = types__namespace.isStringLiteral(idArg) ? idArg.value : '';
2744
+ const value = types__namespace.isStringLiteral(valueArg) ? valueArg.value : '';
2631
2745
  // 检查 ID 和值是否存在,并且第二个参数是字符串字面量
2632
- if (id && value && types__namespace.isStringLiteral(arg[1])) {
2746
+ if (id && value && types__namespace.isStringLiteral(idArg) && types__namespace.isStringLiteral(valueArg)) {
2747
+ const resolvedId = resolveLangKey(id, value);
2748
+ if (resolvedId !== id) {
2749
+ idArg.value = resolvedId;
2750
+ idArg.extra = {
2751
+ raw: `'${resolvedId}'`,
2752
+ rawValue: resolvedId
2753
+ };
2754
+ }
2633
2755
  // 调用翻译工具的 setLangObj 方法设置语言对象属性
2634
- setLangObj(id, value);
2756
+ setLangObj(resolvedId, value);
2635
2757
  }
2636
2758
  }
2637
2759