@maiyunnet/kebab 8.2.1 → 8.3.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/doc/kebab-rag.md CHANGED
@@ -1389,7 +1389,7 @@ index/variables/VER.md
1389
1389
 
1390
1390
  # Variable: VER
1391
1391
 
1392
- > `const` **VER**: `"8.2.1"` = `'8.2.1'`
1392
+ > `const` **VER**: `"8.3.0"` = `'8.3.0'`
1393
1393
 
1394
1394
  Defined in: [index.ts:10](https://github.com/maiyunnet/kebab/blob/master/index.ts#L10)
1395
1395
 
package/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * --- 本文件用来定义每个目录实体地址的常量 ---
6
6
  */
7
7
  /** --- 当前系统版本号 --- */
8
- export declare const VER = "8.2.1";
8
+ export declare const VER = "8.3.0";
9
9
  /** --- 框架根目录,以 / 结尾 --- */
10
10
  export declare const ROOT_PATH: string;
11
11
  /** --- 框架的 LIB,以 / 结尾 --- */
package/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * --- 本文件用来定义每个目录实体地址的常量 ---
7
7
  */
8
8
  /** --- 当前系统版本号 --- */
9
- export const VER = '8.2.1';
9
+ export const VER = '8.3.0';
10
10
  // --- 服务端用的路径 ---
11
11
  const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
12
12
  /** --- /xxx/xxx --- */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maiyunnet/kebab",
3
- "version": "8.2.1",
3
+ "version": "8.3.0",
4
4
  "description": "Simple, easy-to-use, and fully-featured Node.js framework that is ready-to-use out of the box.",
5
5
  "type": "module",
6
6
  "keywords": [
package/sys/cmd.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Project: Kebab, User: JianSuoQiYue
3
3
  * Date: 2020-3-7 23:51:15
4
- * Last: 2020-3-7 23:51:18, 2022-07-22 14:14:09, 2022-9-27 14:52:19, 2023-5-23 21:42:46, 2024-7-2 15:12:28
4
+ * Last: 2020-3-7 23:51:18, 2022-07-22 14:14:09, 2022-9-27 14:52:19, 2023-5-23 21:42:46, 2024-7-2 15:12:28, 2026-2-23 13:08:11
5
5
  */
6
6
  import * as http from 'http';
7
7
  import * as lFs from '#kebab/lib/fs.js';
@@ -10,6 +10,7 @@ import * as lTime from '#kebab/lib/time.js';
10
10
  import * as lCore from '#kebab/lib/core.js';
11
11
  import * as lCrypto from '#kebab/lib/crypto.js';
12
12
  import * as kebab from '#kebab/index.js';
13
+ // --- 检查语言包:node ./source/main locale -l ./source/www/example/data/locale/sc -d ./source/www/example ---
13
14
  /** --- 解析命令 --- */
14
15
  const cmds = process.argv.slice(2);
15
16
  /** --- 批量创建目录 --- */
@@ -222,6 +223,126 @@ async function run() {
222
223
  }
223
224
  }
224
225
  lCore.display('DONE');
226
+ // --- 退出进程 ---
227
+ process.exit();
228
+ }
229
+ if (cmds[0] === 'locale') {
230
+ let localePath = '';
231
+ let dirPath = '';
232
+ for (let i = 1; i < cmds.length; i++) {
233
+ if (cmds[i] === '-l' || cmds[i] === '--locale') {
234
+ localePath = cmds[i + 1];
235
+ i++;
236
+ }
237
+ else if (cmds[i] === '-d' || cmds[i] === '--dir') {
238
+ dirPath = cmds[i + 1];
239
+ i++;
240
+ }
241
+ }
242
+ if (!localePath || !dirPath) {
243
+ process.exit();
244
+ }
245
+ const appLocaleList = [];
246
+ const readDir = async (path) => {
247
+ const dlist = await lFs.readDir(path);
248
+ for (const item of dlist) {
249
+ if (item.name === '.' || item.name === '..') {
250
+ continue;
251
+ }
252
+ if (item.isDirectory()) {
253
+ await readDir(path + '/' + item.name);
254
+ continue;
255
+ }
256
+ if (!item.name.endsWith('.ejs') &&
257
+ !item.name.endsWith('.ts')) {
258
+ continue;
259
+ }
260
+ // --- ts 文件可能是前端的代码,所以要排除掉前端的 ts 文件 ---
261
+ let content = await lFs.getContent(path + '/' + item.name, 'utf8');
262
+ if (!content) {
263
+ continue;
264
+ }
265
+ if (item.name.endsWith('.ts')) {
266
+ // --- ts 文件可能是前端的代码,所以要排除掉前端的 ts 文件 ---
267
+ if (content.includes('AbstractPage')) {
268
+ continue;
269
+ }
270
+ // --- 移除 TS 多行注释 ---
271
+ content = content.replace(/\/\*[\s\S]*?\*\//g, '');
272
+ // --- 移除 TS 单行注释 ---
273
+ content = content.replace(/(^|[^\:])\/\/.*/g, '$1');
274
+ }
275
+ else if (item.name.endsWith('.ejs')) {
276
+ // --- ejs 文件,只保留 <% %> 内部的内容,因为外部是前端代码 ---
277
+ const matches = content.match(/<%[\s\S]*?%>/g);
278
+ if (!matches) {
279
+ continue;
280
+ }
281
+ content = matches.join('\n');
282
+ // --- 移除多行注释 ---
283
+ content = content.replace(/\/\*[\s\S]*?\*\//g, '');
284
+ // --- 移除单行注释 ---
285
+ content = content.replace(/(^|[^\:])\/\/.*/g, '$1');
286
+ }
287
+ const reg = /(?:\b|_)l\s*\(\s*(['"])(.+?)\1/g;
288
+ let match;
289
+ while (match = reg.exec(content)) {
290
+ const key = match[2];
291
+ if (appLocaleList.includes(key)) {
292
+ continue;
293
+ }
294
+ appLocaleList.push(key);
295
+ }
296
+ }
297
+ };
298
+ /** --- 提取目录 --- */
299
+ const lastSlash = localePath.lastIndexOf('/');
300
+ const dir = lastSlash === -1 ? '.' : localePath.slice(0, lastSlash);
301
+ /** --- 提取前缀,如 'sc' --- */
302
+ const prefix = lastSlash === -1 ? localePath : localePath.slice(lastSlash + 1);
303
+ const localeList = [];
304
+ const getKeys = (o, p = '') => {
305
+ for (const k in o) {
306
+ const nk = p ? p + '.' + k : k;
307
+ if (typeof o[k] === 'object' && o[k] !== null && !Array.isArray(o[k])) {
308
+ getKeys(o[k], nk);
309
+ }
310
+ else {
311
+ localeList.push(nk);
312
+ }
313
+ }
314
+ };
315
+ const files = await lFs.readDir(dir);
316
+ let found = false;
317
+ for (const file of files) {
318
+ if (file.isFile() && file.name.startsWith(prefix + '.') && file.name.endsWith('.json')) {
319
+ found = true;
320
+ const content = await lFs.getContent(dir + '/' + file.name, 'utf8');
321
+ if (!content) {
322
+ continue;
323
+ }
324
+ const obj = lText.parseJson(content);
325
+ if (typeof obj !== 'object') {
326
+ continue;
327
+ }
328
+ getKeys(obj);
329
+ }
330
+ }
331
+ if (!found) {
332
+ lCore.display('Locale files not found: ' + localePath + '.*.json');
333
+ process.exit();
334
+ }
335
+ appLocaleList.length = 0;
336
+ await readDir(dirPath);
337
+ const set1 = new Set(localeList);
338
+ const set2 = new Set(appLocaleList);
339
+ /** --- 只在第一个数组中存在的元素 --- */
340
+ const onlyInFirst = localeList.filter(item => !set2.has(item));
341
+ /** --- 只在第二个数组中存在的元素 --- */
342
+ const onlyInSecond = appLocaleList.filter(item => !set1.has(item));
343
+ lCore.display('More', onlyInFirst);
344
+ lCore.display('Less', onlyInSecond);
345
+ // --- 退出进程 ---
225
346
  process.exit();
226
347
  }
227
348
  // --- 读取配置文件 ---