@zzclub/z-cli 0.5.3 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,6 +1,30 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+ ## v0.6.0
5
+
6
+ [compare changes](https://github.com/aatrooox/z-cli/compare/v0.5.4...v0.6.0)
7
+
8
+ ### 🚀 Enhancements
9
+
10
+ - 改造i18n,使其能够直接提取中文 ([bb05eac](https://github.com/aatrooox/z-cli/commit/bb05eac))
11
+
12
+ ### ❤️ Contributors
13
+
14
+ - Aatrox <gnakzz@qq.com>
15
+
16
+ ## v0.5.4
17
+
18
+ [compare changes](https://github.com/aatrooox/z-cli/compare/v0.5.3...v0.5.4)
19
+
20
+ ### 🚀 Enhancements
21
+
22
+ - 增加node版本提示 ([5eb02cb](https://github.com/aatrooox/z-cli/commit/5eb02cb))
23
+
24
+ ### ❤️ Contributors
25
+
26
+ - Aatrox <gnakzz@qq.com>
27
+
4
28
  ## v0.5.3
5
29
 
6
30
  [compare changes](https://github.com/aatrooox/z-cli/compare/v0.5.2...v0.5.3)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zzclub/z-cli",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
4
4
  "description": "all-in-one 工具箱,专为提升日常及工作效率而生",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
@@ -68,14 +68,14 @@ const i18nCmd = {
68
68
  for (const file of filePaths) {
69
69
  const content = fs.readFileSync(file, 'utf-8');
70
70
  const fileName = path.basename(file, '.vue');
71
- const i18nKeys = extractI18nKeys(content);
71
+ const { keys: i18nKeys, commentMap } = extractI18nKeys(content);
72
72
 
73
73
  if (i18nKeys.length > 0) {
74
74
  file_spinner.succeed(`从 ${chalk.yellow(fileName)} 中提取了 ${chalk.green(i18nKeys.length)} 个国际化键值`);
75
75
 
76
76
  // 处理每个提取的键值
77
77
  for (const key of i18nKeys) {
78
- await processI18nKey(key, i18nMap);
78
+ await processI18nKey(key, i18nMap, commentMap);
79
79
  }
80
80
  }
81
81
  }
@@ -109,7 +109,7 @@ const i18nCmd = {
109
109
 
110
110
  const content = fs.readFileSync(filePath, 'utf-8');
111
111
  const fileName = path.basename(filePath, '.vue');
112
- const i18nKeys = extractI18nKeys(content);
112
+ const { keys: i18nKeys, commentMap } = extractI18nKeys(content);
113
113
 
114
114
  if (i18nKeys.length > 0) {
115
115
  const i18nMap = {};
@@ -118,7 +118,7 @@ const i18nCmd = {
118
118
 
119
119
  // 处理每个提取的键值
120
120
  for (const key of i18nKeys) {
121
- await processI18nKey(key, i18nMap);
121
+ await processI18nKey(key, i18nMap, commentMap);
122
122
  }
123
123
 
124
124
  // 如果没有指定输出目录,使用当前处理的文件所在目录
@@ -163,25 +163,81 @@ function getAllVueFiles(dirPath, filePaths) {
163
163
  * 从 Vue 文件内容中提取国际化键值
164
164
  * @param {string} content 文件内容
165
165
  * @param {string} ignorePrefix 要忽略的前缀
166
- * @returns {Array} 提取的键值数组
166
+ * @returns {Object} 提取的键值数组和注释映射
167
167
  */
168
168
  function extractI18nKeys(content, ignorePrefix = "common") {
169
+ // 原有正则表达式,提取键名
169
170
  const regex = /\$t\(['"]i18n\.([^'"]+)['"]\)/g;
171
+ // 提取键名和注释中的中文
172
+ const regexWithComment = /\$t\(['"]i18n\.([^'"]+)['"]\)[\s,]*\/\/\s*([\u4e00-\u9fa5].*?)(?=\n|$)/g;
173
+ // 新增:提取HTML注释中的i18n信息
174
+ const regexHtmlComment = /<!--i18n\s+(.*?)-->/g;
175
+
170
176
  const keys = [];
177
+ const commentMap = {}; // 存储键名和对应的注释内容
171
178
  let match;
172
179
 
180
+ // 提取HTML注释中的i18n信息
181
+ while ((match = regexHtmlComment.exec(content)) !== null) {
182
+ const commentContent = match[1].trim();
183
+ // 解析注释内容中的多个键值对
184
+ const keyValuePairs = commentContent.split(/\s+/);
185
+
186
+ for (const pair of keyValuePairs) {
187
+ const [key, value] = pair.split('=');
188
+ if (key && value) {
189
+ // 将简短键(如addTitle)与完整键(如monthlyForecast.pageTitle.addTitle)进行匹配
190
+ // 这里我们需要在后续处理中找到对应的完整键
191
+ commentMap[key] = value;
192
+ }
193
+ }
194
+ }
195
+
196
+ // 提取带注释的国际化键
197
+ while ((match = regexWithComment.exec(content)) !== null) {
198
+ const key = match[1];
199
+ const comment = match[2].trim();
200
+
201
+ // 如果设置了忽略前缀且键以该前缀开头,则跳过
202
+ if (ignorePrefix && key.startsWith(`${ignorePrefix}.`)) {
203
+ continue;
204
+ }
205
+
206
+ keys.push(key);
207
+ // JS注释优先级高于HTML注释
208
+ commentMap[key] = comment;
209
+
210
+ // 同时为简短键名存储注释
211
+ const shortKey = key.split('.').pop();
212
+ if (!commentMap[shortKey]) {
213
+ commentMap[shortKey] = comment;
214
+ }
215
+ }
216
+
217
+ // 提取不带注释的国际化键
173
218
  while ((match = regex.exec(content)) !== null) {
174
219
  const key = match[1];
220
+
175
221
  // 如果设置了忽略前缀且键以该前缀开头,则跳过
176
222
  if (ignorePrefix && key.startsWith(`${ignorePrefix}.`)) {
177
223
  continue;
178
224
  }
225
+
179
226
  keys.push(key);
227
+
228
+ // 检查是否有对应的HTML注释
229
+ const shortKey = key.split('.').pop();
230
+ if (commentMap[shortKey] && !commentMap[key]) {
231
+ commentMap[key] = commentMap[shortKey];
232
+ }
180
233
  }
181
234
 
182
- return [...new Set(keys)]; // 去重
235
+ // 返回去重后的键名数组和注释映射
236
+ return {
237
+ keys: [...new Set(keys)],
238
+ commentMap
239
+ };
183
240
  }
184
-
185
241
  function unquoteKeys(json) {
186
242
  return json.replace(/"(\\[^]|[^\\"])*"\s*:?/g, function (match) {
187
243
  if (/:$/.test(match)) {
@@ -196,8 +252,9 @@ function unquoteKeys(json) {
196
252
  * 处理单个国际化键值
197
253
  * @param {string} key 键值
198
254
  * @param {Object} i18nMap 国际化映射对象
255
+ * @param {Object} commentMap 注释映射
199
256
  */
200
- async function processI18nKey(key, i18nMap) {
257
+ async function processI18nKey(key, i18nMap, commentMap = {}) {
201
258
  // 解析键值 fee-forecast-maintain.placeholder.yearNum
202
259
  const parts = key.split('.');
203
260
 
@@ -223,8 +280,8 @@ async function processI18nKey(key, i18nMap) {
223
280
 
224
281
  // 设置最终的键值
225
282
  if (!current[lastKey]) {
226
- // 使用键名作为默认值
227
- current[lastKey] = lastKey;
283
+ // 如果有注释,使用注释作为值,否则使用键名
284
+ current[lastKey] = commentMap[key] || lastKey;
228
285
  }
229
286
  }
230
287
 
package/src/index.js CHANGED
@@ -7,11 +7,12 @@ import { configCmd } from "./command/config.js";
7
7
  import { setCmd } from "./command/set.js";
8
8
  import { tinyCmd } from "./command/tiny.js";
9
9
  import { picgoCmd } from "./command/picgo.js";
10
- import { checkUpdate } from './utils/common.js'
10
+ import { checkUpdate, checkNodeVersion } from './utils/common.js'
11
11
  import { i18nCmd } from "./command/i18n.js";
12
12
  const program = new Command();
13
13
 
14
14
  initProgram(program, async () => {
15
+ checkNodeVersion()
15
16
  await checkUpdate()
16
17
  registerCommand(program, translateCmd);
17
18
 
@@ -198,3 +198,21 @@ export async function checkUpdate() {
198
198
  // 静默处理错误
199
199
  }
200
200
  }
201
+
202
+
203
+ export async function checkNodeVersion() {
204
+ const currentNodeVersion = process.versions.node;
205
+ const semver = currentNodeVersion.split('.');
206
+ const major = parseInt(semver[0], 10);
207
+ const minor = parseInt(semver[1], 10);
208
+
209
+ if (major < 18 || (major === 18 && minor < 18)) {
210
+ console.error(
211
+ chalk.red('\n❌ Node版本过低:') +
212
+ chalk.yellow('建议升级到 ') +
213
+ chalk.green('18.18.0') +
214
+ chalk.yellow(' 或更高版本。\n') +
215
+ chalk.gray('当前版本:') + chalk.red(currentNodeVersion)
216
+ );
217
+ }
218
+ }