td-octopus 0.1.16 → 0.1.18

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.
@@ -0,0 +1,9 @@
1
+ const { main } = require('../src/storage');
2
+
3
+ exports.command = 'storage';
4
+
5
+ exports.describe = 'storage 将项目中用到的中英文存储到缓存中';
6
+
7
+ exports.handler = () => {
8
+ main()
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "td-octopus",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
4
4
  "description": "I18N tool",
5
5
  "author": "Anthony Li",
6
6
  "bin": {
@@ -27,7 +27,8 @@
27
27
  "update-notifier": "^4.1.0",
28
28
  "vue-template-compiler": "^2.6.14",
29
29
  "xlsx": "0.16.9",
30
- "yargs": "^15.3.1"
30
+ "yargs": "^15.3.1",
31
+ "eslint": "^8.15.0"
31
32
  },
32
33
  "keywords": [
33
34
  "I18N",
package/src/back/index.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * @Author: 郑泳健
4
4
  * @Date: 2022-06-01 13:56:18
5
5
  * @LastEditors: 郑泳健
6
- * @LastEditTime: 2023-01-18 15:25:47
6
+ * @LastEditTime: 2025-11-11 10:10:55
7
7
  */
8
8
  const path = require('path')
9
9
  const fs = require('fs')
@@ -27,8 +27,6 @@ const TEMPLATE_INNER_REGEX = /I18N\.template\(([\s\S]*?})\)/g
27
27
  // 匹配{}之间的内容
28
28
  const JSON_KEY_REGEX = /{([\s\S]*?)}/g
29
29
 
30
- // 匹配{}之间的value
31
- const JSON_VALYR_REGEX = /(?<=: )[^,}]+/g
32
30
 
33
31
  /**
34
32
  * 获取需要back的所有文件目录
@@ -61,14 +59,39 @@ function getFilePaths() {
61
59
  /**
62
60
  * 获取I18N.template里面{}每个value对应的value
63
61
  * @param {*} str {val1: h, val2: m, val3: s}
64
- * @returns [h, m, s]
62
+ * @returns obj
65
63
  */
66
64
  function getTemplateValue(str) {
67
65
  try {
68
- const values = str.match(JSON_VALYR_REGEX)
69
- return values;
66
+ const result = {};
67
+ const regex = /(\w+)\s*:\s*/g;
68
+ let match;
69
+
70
+ while ((match = regex.exec(objStr)) !== null) {
71
+ const key = match[1].trim();
72
+ let valueStart = regex.lastIndex;
73
+ let bracketCount = 0;
74
+ let valueEnd = valueStart;
75
+
76
+ for (let i = valueStart; i < objStr.length; i++) {
77
+ const char = objStr[i];
78
+ if (char === '(') bracketCount++;
79
+ if (char === ')') bracketCount--;
80
+ if ((char === ',' && bracketCount === 0) || (char === '}' && bracketCount === 0)) {
81
+ valueEnd = i;
82
+ break;
83
+ }
84
+ }
85
+
86
+ const value = objStr.slice(valueStart, valueEnd).trim();
87
+ result[key] = value;
88
+
89
+ regex.lastIndex = valueEnd + 1; // 继续匹配下一个
90
+ }
91
+
92
+ return result;
70
93
  } catch (e) {
71
- throw e;
94
+ throw new Error(`获取I8N.template内的变量出错: ${e.message}`);
72
95
  }
73
96
  }
74
97
 
@@ -89,13 +112,8 @@ function transformTemplate(filePath, code, flatObj) {
89
112
  let matchList = getValueByI18N(filePath, i, flatObj) || [];
90
113
  matchText = matchList[0] && matchList[0]['value']
91
114
  if (matchText) {
92
- matchText = matchText.replace(/{(val\d+)}/g, (match, group, index) => {
93
- if (!keys[0]) {
94
- throw new Error(`${filePath}文件中的 ${highlightText(i)} 转换有问题,请手动检查`)
95
- }
96
- const res = '${' + keys[0].trim() + '}'
97
- keys.splice(0, 1)
98
- return res
115
+ matchText = matchText.replace(/{(val\d+)}/g, (_, transKey) => {
116
+ return `\${${keys[transKey]}}`;
99
117
  })
100
118
 
101
119
  code = code.replace(i, '`' + matchText + '`')
@@ -3,19 +3,19 @@
3
3
  * @Author: 郑泳健
4
4
  * @Date: 2024-12-12 15:00:24
5
5
  * @LastEditors: 郑泳健
6
- * @LastEditTime: 2025-09-11 09:56:54
6
+ * @LastEditTime: 2025-11-11 09:57:48
7
7
  */
8
- const path = require('path')
9
- const fs = require('fs')
10
- const shell = require('shelljs');
11
- const { getSpecifiedFiles, isFile } = require('../utils/file')
12
- const syncLang = require('../utils/syncLang')
13
- const { flatObject, rewriteFiles, getFileKeyValueList, getAdjustLangObjAndAddList } = require('../utils/translate');
14
- const { failInfo, highlightText } = require('../utils/colors');
15
- const { getProjectConfig, autoImportJSFiles } = require('../utils/index')
16
- const ora = require('ora');
8
+ const path = require('path');
9
+ const fs = require('fs');
10
+ const { parse } = require('@babel/parser');
11
+ const generate = require('@babel/generator').default;
12
+ const syncLang = require('../utils/syncLang');
13
+ const { flatObject, rewriteFiles, getFileKeyValueList } = require('../utils/translate');
14
+ const { autoImportJSFiles } = require('../utils/index');
15
+
16
+ const { ESLint } = require('eslint');
17
17
 
18
- const CONFIG = getProjectConfig();
18
+ const ora = require('ora');
19
19
 
20
20
  const spinner = ora('开始check');
21
21
 
@@ -23,9 +23,9 @@ function extractThreeLevelI18NKeys(code) {
23
23
  // 匹配恰好三级的I18N键值(I18N.xxx.xxx.xxx)
24
24
  // 使用正则表达式确保前面不是点,后面也不是点或字母数字下划线
25
25
  const pattern = /(?<!\.)I18N\.[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+\.[a-zA-Z0-9_]+(?![a-zA-Z0-9_\.])/g;
26
-
26
+
27
27
  const matches = code.match(pattern) || [];
28
-
28
+
29
29
  // 去重并返回
30
30
  return [...new Set(matches)];
31
31
  }
@@ -33,84 +33,82 @@ function extractThreeLevelI18NKeys(code) {
33
33
  // 递归读取文件夹中所有 .js 文件内容
34
34
  function readJsFiles(folderPath) {
35
35
  let jsContent = '';
36
-
36
+
37
37
  const files = fs.readdirSync(folderPath); // 读取文件夹内容
38
38
  for (const file of files) {
39
- const fullPath = path.join(folderPath, file);
40
- const stats = fs.statSync(fullPath); // 获取文件或文件夹状态
41
-
42
- if (stats.isDirectory()) {
43
- // 如果是文件夹,递归处理
44
- jsContent += readJsFiles(fullPath);
45
- } else if (path.extname(fullPath) === '.js') {
46
- // 如果是 .js 文件,读取文件内容
47
- const content = fs.readFileSync(fullPath, 'utf-8');
48
- jsContent += `\n/* File: ${fullPath} */\n${content}\n`;
49
- }
39
+ const fullPath = path.join(folderPath, file);
40
+ const stats = fs.statSync(fullPath); // 获取文件或文件夹状态
41
+
42
+ if (stats.isDirectory()) {
43
+ // 如果是文件夹,递归处理
44
+ jsContent += readJsFiles(fullPath);
45
+ } else if (path.extname(fullPath) === '.js') {
46
+ // 如果是 .js 文件,读取文件内容
47
+ let content = fs.readFileSync(fullPath, 'utf-8');
48
+ const ast = parse(source, { sourceType: 'module', plugins: ['jsx', 'typescript'] });
49
+ const output = generate(ast, { comments: false });
50
+ content = output.code;
51
+ jsContent += `\n/* File: ${fullPath} */\n${content}\n`;
52
+ }
50
53
  }
51
-
54
+
52
55
  return jsContent;
53
- }
56
+ }
54
57
 
55
58
  // 同步不同的语言包
56
59
  function main() {
57
60
  (async () => {
58
- const distLang = Array.isArray(CONFIG.distLangs) ? CONFIG.distLangs : []
59
61
  const zhCN = syncLang('zh-CN');
60
62
  const zhCNFlat = flatObject(zhCN);
61
- // 当前项目所有的key
62
- const keys = Object.keys(zhCNFlat)
63
- const totalText = readJsFiles(path.resolve(process.cwd(), 'src'))
63
+ const totalText = readJsFiles(path.resolve(process.cwd(), 'src'));
64
64
  const totalTranslateList = extractThreeLevelI18NKeys(totalText);
65
- const zhCnKey = Object.keys(zhCNFlat)
66
- let result = {}
67
- const lostKey = totalTranslateList.filter(item => !zhCnKey.includes(item.replace('I18N.', '')))
68
- fs.writeFileSync(path.resolve(process.cwd(), 'lostI18N.js'), JSON.stringify(lostKey, null, 4), 'utf-8')
69
-
70
- if(!lostKey.length) {
71
- spinner.succeed(`查询完毕,无丢失`);
72
- return
65
+ const zhCnKey = Object.keys(zhCNFlat);
66
+ const lostKey = totalTranslateList.filter((item) => !zhCnKey.includes(item.replace('I18N.', '')));
67
+ fs.writeFileSync(path.resolve(process.cwd(), 'lostI18N.js'), JSON.stringify(lostKey, null, 4), 'utf-8');
68
+
69
+ if (!lostKey.length) {
70
+ spinner.succeed('查询完毕,无丢失');
71
+ return;
73
72
  }
74
-
75
- if (!fs.existsSync(path.resolve(process.cwd(), 'public/.octopus'))) {
73
+
74
+ if (!fs.existsSync(path.resolve(__dirname, '../octopus/zh-CN.js'))) {
76
75
  spinner.succeed(`查询完毕,共计丢失${lostKey.length}个,请在lostI18N.js中查看`);
77
- spinner.warn('请将原始项目的.octopus复制到当前项目public目录下,会帮你自助将缺失的key补充上去');
76
+ spinner.warn('请先执行otp storage');
78
77
  return;
79
78
  }
80
79
  spinner.start(`查询完毕,共计丢失${lostKey.length}个,开始同步开始`);
81
- const zhFrom = syncLang('zh-CN', path.resolve(process.cwd(), 'public/.octopus'))
82
- const enFrom = syncLang('en-US', path.resolve(process.cwd(), 'public/.octopus'))
83
- const zhFromFlat = flatObject(zhFrom);
84
- const enFromFlat = flatObject(enFrom);
80
+ const zhFromFlat = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../octopus/zh-CN.js'), 'utf-8'));
81
+ const enFromFlat = JSON.parse(fs.readFileSync(path.resolve(__dirname, '../octopus/en-US.js'), 'utf-8'));
85
82
 
86
83
  const enUS = syncLang('en-US');
87
84
  const enUSFlat = flatObject(enUS);
88
85
 
89
86
  const zhCNResult = lostKey.reduce((total, item) => {
90
- if(zhFromFlat[item.replace('I18N.', '')]){
91
- total[item.replace('I18N.', '')] = zhFromFlat[item.replace('I18N.', '')]
87
+ if (zhFromFlat[item.replace('I18N.', '')]) {
88
+ total[item.replace('I18N.', '')] = zhFromFlat[item.replace('I18N.', '')];
92
89
  }
93
90
  return total;
94
- }, zhCNFlat)
95
-
91
+ }, zhCNFlat);
92
+
96
93
  const enCNResult = lostKey.reduce((total, item) => {
97
- if(enFromFlat[item.replace('I18N.', '')]){
98
- total[item.replace('I18N.', '')] = enFromFlat[item.replace('I18N.', '')]
94
+ if (enFromFlat[item.replace('I18N.', '')]) {
95
+ total[item.replace('I18N.', '')] = enFromFlat[item.replace('I18N.', '')];
99
96
  }
100
97
  return total;
101
- }, enUSFlat)
98
+ }, enUSFlat);
102
99
 
103
100
  rewriteFiles(getFileKeyValueList(zhCNResult), 'zh-CN');
104
101
  rewriteFiles(getFileKeyValueList(enCNResult), 'en-US');
105
102
  const cnJSON = fs.readFileSync(path.resolve(process.cwd(), '.octopus/zh-CN/index.js'), 'utf-8');
106
103
  const enJSON = fs.readFileSync(path.resolve(process.cwd(), '.octopus/en-US/index.js'), 'utf-8');
107
104
 
108
- autoImportJSFiles(path.resolve(process.cwd(), '.octopus/zh-CN'), cnJSON)
109
- autoImportJSFiles(path.resolve(process.cwd(), '.octopus/en-US'), enJSON)
110
- spinner.succeed(`同步完成`);
111
- })()
105
+ autoImportJSFiles(path.resolve(process.cwd(), '.octopus/zh-CN'), cnJSON);
106
+ autoImportJSFiles(path.resolve(process.cwd(), '.octopus/en-US'), enJSON);
107
+ fs.rmSync(path.resolve(__dirname, '../octopus'), { recursive: true, force: true });
108
+ spinner.succeed('同步完成,如果需要重新check,请先执行otp storage');
109
+ })();
112
110
  }
113
111
 
114
112
  module.exports = {
115
113
  main
116
- }
114
+ };
@@ -0,0 +1,35 @@
1
+ /*
2
+ * @Descripttion: 将项目中用到的中英文存储到缓存中
3
+ * @Author: 郑泳健
4
+ * @Date: 2024-12-12 15:00:24
5
+ * @LastEditors: 郑泳健
6
+ * @LastEditTime: 2025-10-13 10:55:39
7
+ */
8
+ const path = require('path');
9
+ const fs = require('fs');
10
+ const syncLang = require('../utils/syncLang');
11
+ const { flatObject } = require('../utils/translate');
12
+ const ora = require('ora');
13
+
14
+ const spinner = ora('开始check');
15
+
16
+ // 同步不同的语言包
17
+ function main() {
18
+ (async () => {
19
+ const zhCN = syncLang('zh-CN');
20
+ const zhCNFlat = flatObject(zhCN);
21
+ const enUS = syncLang('en-US');
22
+ const enUSFlat = flatObject(enUS);
23
+ const outpuDir = path.resolve(__dirname, '../octopus');
24
+
25
+ fs.mkdirSync(outpuDir, { recursive: true });
26
+ spinner.start('开始缓存');
27
+ fs.writeFileSync(path.resolve(outpuDir, 'zh-CN.js'), JSON.stringify(zhCNFlat, null, 2), 'utf-8');
28
+ fs.writeFileSync(path.resolve(outpuDir, 'en-US.js'), JSON.stringify(enUSFlat, null, 2), 'utf-8');
29
+ spinner.succeed('缓存完成');
30
+ })();
31
+ }
32
+
33
+ module.exports = {
34
+ main
35
+ };