@maiyunnet/kebab 9.3.1 → 9.3.3

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
@@ -1360,7 +1360,7 @@ index/variables/VER.md
1360
1360
 
1361
1361
  # Variable: VER
1362
1362
 
1363
- > `const` **VER**: `"9.3.1"` = `'9.3.1'`
1363
+ > `const` **VER**: `"9.3.3"` = `'9.3.3'`
1364
1364
 
1365
1365
  Defined in: [index.ts:10](https://github.com/maiyunnet/kebab/blob/master/index.ts#L10)
1366
1366
 
@@ -22208,7 +22208,7 @@ Defined in: [sys/ctr.ts:173](https://github.com/maiyunnet/kebab/blob/master/sys/
22208
22208
 
22209
22209
  > `protected` **\_checkInput**(`input`, `rule`, `rtn`): `boolean`
22210
22210
 
22211
- Defined in: [sys/ctr.ts:568](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L568)
22211
+ Defined in: [sys/ctr.ts:571](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L571)
22212
22212
 
22213
22213
  检测提交的数据类型
22214
22214
 
@@ -22242,7 +22242,7 @@ Defined in: [sys/ctr.ts:568](https://github.com/maiyunnet/kebab/blob/master/sys/
22242
22242
 
22243
22243
  > `protected` **\_checkXInput**(`input`, `rule`, `rtn`): `boolean`
22244
22244
 
22245
- Defined in: [sys/ctr.ts:746](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L746)
22245
+ Defined in: [sys/ctr.ts:749](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L749)
22246
22246
 
22247
22247
  检测提交的数据类型(会检测 XSRF)
22248
22248
 
@@ -22276,7 +22276,7 @@ Defined in: [sys/ctr.ts:746](https://github.com/maiyunnet/kebab/blob/master/sys/
22276
22276
 
22277
22277
  > `protected` **\_cross**(`opt?`): `boolean`
22278
22278
 
22279
- Defined in: [sys/ctr.ts:975](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L975)
22279
+ Defined in: [sys/ctr.ts:978](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L978)
22280
22280
 
22281
22281
  开启跨域请求
22282
22282
 
@@ -22321,7 +22321,7 @@ Defined in: [sys/ctr.ts:975](https://github.com/maiyunnet/kebab/blob/master/sys/
22321
22321
 
22322
22322
  > `protected` **\_device**(): `"unknown"` \| `"android"` \| `"linux"` \| `"windows"` \| `"macintosh"` \| `"ipad"`
22323
22323
 
22324
- Defined in: [sys/ctr.ts:788](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L788)
22324
+ Defined in: [sys/ctr.ts:791](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L791)
22325
22325
 
22326
22326
  根据用户 ua 获取当前用户的设备类型
22327
22327
 
@@ -22335,7 +22335,7 @@ Defined in: [sys/ctr.ts:788](https://github.com/maiyunnet/kebab/blob/master/sys/
22335
22335
 
22336
22336
  > `protected` **\_enabledXsrf**(`opt?`): `void`
22337
22337
 
22338
- Defined in: [sys/ctr.ts:757](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L757)
22338
+ Defined in: [sys/ctr.ts:760](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L760)
22339
22339
 
22340
22340
  当前页面开启 XSRF 支持(主要检测 cookie 是否存在)
22341
22341
  如果当前页面有 CDN,请不要使用
@@ -22358,7 +22358,7 @@ Defined in: [sys/ctr.ts:757](https://github.com/maiyunnet/kebab/blob/master/sys/
22358
22358
 
22359
22359
  > `protected` **\_end**(): `void`
22360
22360
 
22361
- Defined in: [sys/ctr.ts:1083](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1083)
22361
+ Defined in: [sys/ctr.ts:1086](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1086)
22362
22362
 
22363
22363
  主动关闭当前 socket 连接
22364
22364
 
@@ -22372,7 +22372,7 @@ Defined in: [sys/ctr.ts:1083](https://github.com/maiyunnet/kebab/blob/master/sys
22372
22372
 
22373
22373
  > `protected` **\_getBasicAuth**(`user`, `pwd`): `string`
22374
22374
 
22375
- Defined in: [sys/ctr.ts:781](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L781)
22375
+ Defined in: [sys/ctr.ts:784](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L784)
22376
22376
 
22377
22377
  获取 Auth 字符串,用于客户端提交
22378
22378
 
@@ -22400,7 +22400,7 @@ Defined in: [sys/ctr.ts:781](https://github.com/maiyunnet/kebab/blob/master/sys/
22400
22400
 
22401
22401
  > `protected` **\_getLocale**(): `string`
22402
22402
 
22403
- Defined in: [sys/ctr.ts:966](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L966)
22403
+ Defined in: [sys/ctr.ts:969](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L969)
22404
22404
 
22405
22405
  获取当前语言名
22406
22406
 
@@ -22414,7 +22414,7 @@ Defined in: [sys/ctr.ts:966](https://github.com/maiyunnet/kebab/blob/master/sys/
22414
22414
 
22415
22415
  > `protected` **\_getLocaleJsonString**(): `string`
22416
22416
 
22417
- Defined in: [sys/ctr.ts:954](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L954)
22417
+ Defined in: [sys/ctr.ts:957](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L957)
22418
22418
 
22419
22419
  根据当前后台语言包设置情况获取 JSON 字符串传输到前台
22420
22420
 
@@ -22466,7 +22466,7 @@ Defined in: [sys/ctr.ts:315](https://github.com/maiyunnet/kebab/blob/master/sys/
22466
22466
 
22467
22467
  > `protected` **\_handleFormData**(`events?`, `limits?`): `Promise`\<`boolean`\>
22468
22468
 
22469
- Defined in: [sys/ctr.ts:1092](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1092)
22469
+ Defined in: [sys/ctr.ts:1095](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1095)
22470
22470
 
22471
22471
  获取 formdata 的信息
22472
22472
 
@@ -22514,7 +22514,7 @@ Defined in: [sys/ctr.ts:1092](https://github.com/maiyunnet/kebab/blob/master/sys
22514
22514
 
22515
22515
  > **\_l**(`key`, `data?`): `string`
22516
22516
 
22517
- Defined in: [sys/ctr.ts:1018](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1018)
22517
+ Defined in: [sys/ctr.ts:1021](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1021)
22518
22518
 
22519
22519
  获取语言包值
22520
22520
 
@@ -22540,7 +22540,7 @@ Defined in: [sys/ctr.ts:1018](https://github.com/maiyunnet/kebab/blob/master/sys
22540
22540
 
22541
22541
  > `protected` **\_loadData**(`path`): `Promise`\<`Record`\<`string`, `string`\> \| `null`\>
22542
22542
 
22543
- Defined in: [sys/ctr.ts:857](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L857)
22543
+ Defined in: [sys/ctr.ts:860](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L860)
22544
22544
 
22545
22545
  获取 data 数据
22546
22546
 
@@ -22562,7 +22562,7 @@ Defined in: [sys/ctr.ts:857](https://github.com/maiyunnet/kebab/blob/master/sys/
22562
22562
 
22563
22563
  > `protected` **\_loadLocale**(`loc`, `pkg?`): `Promise`\<`boolean`\>
22564
22564
 
22565
- Defined in: [sys/ctr.ts:905](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L905)
22565
+ Defined in: [sys/ctr.ts:908](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L908)
22566
22566
 
22567
22567
  设定语言并加载语言包
22568
22568
 
@@ -22683,7 +22683,7 @@ Defined in: [sys/ctr.ts:332](https://github.com/maiyunnet/kebab/blob/master/sys/
22683
22683
 
22684
22684
  > `protected` **\_location**(`location`): `false`
22685
22685
 
22686
- Defined in: [sys/ctr.ts:875](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L875)
22686
+ Defined in: [sys/ctr.ts:878](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L878)
22687
22687
 
22688
22688
  跳转(302临时跳转),支持相对本项目根路径的路径或绝对路径
22689
22689
 
@@ -22705,7 +22705,7 @@ Defined in: [sys/ctr.ts:875](https://github.com/maiyunnet/kebab/blob/master/sys/
22705
22705
 
22706
22706
  > `protected` **\_ping**(`data?`): `boolean`
22707
22707
 
22708
- Defined in: [sys/ctr.ts:1068](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1068)
22708
+ Defined in: [sys/ctr.ts:1071](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1071)
22709
22709
 
22710
22710
  发送 socket ping
22711
22711
 
@@ -22727,7 +22727,7 @@ Defined in: [sys/ctr.ts:1068](https://github.com/maiyunnet/kebab/blob/master/sys
22727
22727
 
22728
22728
  > `protected` **\_pong**(`data?`): `boolean`
22729
22729
 
22730
- Defined in: [sys/ctr.ts:1076](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1076)
22730
+ Defined in: [sys/ctr.ts:1079](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1079)
22731
22731
 
22732
22732
  发送 socket pong
22733
22733
 
@@ -22749,7 +22749,7 @@ Defined in: [sys/ctr.ts:1076](https://github.com/maiyunnet/kebab/blob/master/sys
22749
22749
 
22750
22750
  > `protected` **\_startSession**(`link`, `auth?`, `opt?`): `Promise`\<`boolean`\>
22751
22751
 
22752
- Defined in: [sys/ctr.ts:889](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L889)
22752
+ Defined in: [sys/ctr.ts:892](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L892)
22753
22753
 
22754
22754
  开启 Session
22755
22755
 
@@ -22783,7 +22783,7 @@ Kv 或 Db 实例
22783
22783
 
22784
22784
  > `protected` **\_writeBinary**(`data`): `boolean`
22785
22785
 
22786
- Defined in: [sys/ctr.ts:1060](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1060)
22786
+ Defined in: [sys/ctr.ts:1063](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1063)
22787
22787
 
22788
22788
  发送 socket 二进制
22789
22789
 
@@ -22805,7 +22805,7 @@ Defined in: [sys/ctr.ts:1060](https://github.com/maiyunnet/kebab/blob/master/sys
22805
22805
 
22806
22806
  > `protected` **\_writeResult**(`data`): `boolean`
22807
22807
 
22808
- Defined in: [sys/ctr.ts:1052](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1052)
22808
+ Defined in: [sys/ctr.ts:1055](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1055)
22809
22809
 
22810
22810
  发送结果对象文本
22811
22811
 
@@ -22827,7 +22827,7 @@ Defined in: [sys/ctr.ts:1052](https://github.com/maiyunnet/kebab/blob/master/sys
22827
22827
 
22828
22828
  > `protected` **\_writeText**(`data`): `boolean`
22829
22829
 
22830
- Defined in: [sys/ctr.ts:1044](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1044)
22830
+ Defined in: [sys/ctr.ts:1047](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L1047)
22831
22831
 
22832
22832
  发送 socket 文本
22833
22833
 
@@ -22849,7 +22849,7 @@ Defined in: [sys/ctr.ts:1044](https://github.com/maiyunnet/kebab/blob/master/sys
22849
22849
 
22850
22850
  > **getAuthorization**(): `false` \| \{ `pwd`: `string`; `type`: `"basic"`; `user`: `string`; \} \| \{ `token`: `string`; `type`: `"bearer"`; \}
22851
22851
 
22852
- Defined in: [sys/ctr.ts:809](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L809)
22852
+ Defined in: [sys/ctr.ts:812](https://github.com/maiyunnet/kebab/blob/master/sys/ctr.ts#L812)
22853
22853
 
22854
22854
  通过 header 或 _auth 获取鉴权信息,支持 Basic Auth 和 Bearer Token
22855
22855
 
package/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * --- 本文件用来定义每个目录实体地址的常量 ---
6
6
  */
7
7
  /** --- 当前系统版本号 --- */
8
- export declare const VER = "9.3.1";
8
+ export declare const VER = "9.3.3";
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 = '9.3.1';
9
+ export const VER = '9.3.3';
10
10
  // --- 服务端用的路径 ---
11
11
  const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
12
12
  /** --- /xxx/xxx --- */
@@ -31,7 +31,7 @@ export declare class Response {
31
31
  /**
32
32
  * --- 获取响应读取流对象 ---
33
33
  */
34
- getStream(): (import("undici/types/readable").default & undici.Dispatcher.BodyMixin) | zlib.Gunzip | zlib.Inflate | zlib.BrotliDecompress | null;
34
+ getStream(): zlib.BrotliDecompress | zlib.Gunzip | zlib.Inflate | (import("undici/types/readable").default & undici.Dispatcher.BodyMixin) | null;
35
35
  /**
36
36
  * --- 获取原生响应读取流对象 ---
37
37
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maiyunnet/kebab",
3
- "version": "9.3.1",
3
+ "version": "9.3.3",
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/child.js CHANGED
@@ -26,9 +26,12 @@ const hbTimer = setInterval(function () {
26
26
  pid: process.pid
27
27
  });
28
28
  }, 10_000);
29
- /** --- 加载的证书列表(path: { sc, cert }) --- */
30
- let certList = [];
31
- /** --- server: index --- */
29
+ /**
30
+ * --- 证书持久化 Map,key 为 keyPath|certPath ---
31
+ * --- 防止 reload 时证书文件处于更新空隙期(旧文件已删、新文件未写入)导致证书丢失 ---
32
+ */
33
+ const certList = new Map();
34
+ /** --- servername → certList mapKey 索引缓存 --- */
32
35
  let certHostIndex = {};
33
36
  /** --- 默认证书 --- */
34
37
  let defaultSc;
@@ -83,25 +86,26 @@ async function run() {
83
86
  http2Server = http2.createSecureServer({
84
87
  // eslint-disable-next-line @typescript-eslint/naming-convention
85
88
  'SNICallback': (servername, cb) => {
89
+ // --- 每 24 小时自动重新加载一次证书,确保证书更新后能被及时加载到内存中 ---
86
90
  if (Date.now() - certLastLoad > 60_000 * 60 * 24) {
87
91
  // --- 不能用异步,不要干扰 SNI 进程 ---
88
92
  reloadCert().catch(e => {
89
93
  lCore.display('[CHILD][run] reloadCert error', e);
90
94
  });
91
95
  }
92
- const i = certHostIndex[servername];
93
- if (i !== undefined) {
94
- cb(null, certList[i].sc);
96
+ const cachedKey = certHostIndex[servername];
97
+ if (cachedKey !== undefined) {
98
+ cb(null, certList.get(cachedKey).sc);
95
99
  return;
96
100
  }
97
101
  // --- 查找 servername ---
98
- for (let i = 0; i < certList.length; ++i) {
99
- if (!certList[i].cert.checkHost(servername)) {
102
+ for (const [mapKey, item] of certList) {
103
+ if (!item.cert.checkHost(servername)) {
100
104
  continue;
101
105
  }
102
106
  // --- 找到 ---
103
- cb(null, certList[i].sc);
104
- certHostIndex[servername] = i;
107
+ cb(null, item.sc);
108
+ certHostIndex[servername] = mapKey;
105
109
  return;
106
110
  }
107
111
  if (defaultSc) {
@@ -488,18 +492,28 @@ async function reload() {
488
492
  }
489
493
  /**
490
494
  * --- 重新加载证书对 ---
495
+ * --- 采用增量更新策略:新证书加载成功则覆盖旧值,加载失败(文件更新空隙期)则保留旧证书 ---
491
496
  */
492
497
  async function reloadCert() {
493
498
  certLastLoad = Date.now();
494
- const cl = [];
499
+ /** --- 本次配置中出现的 mapKey 集合,用于事后清理已下线的证书 --- */
500
+ const newKeys = new Set();
501
+ /** --- 配置文件是否成功加载,未成功则不清理 Map,防止误删全部证书 --- */
502
+ let configLoaded = false;
495
503
  try {
496
504
  const certConfig = await lFs.getContent(kebab.CONF_CWD + 'cert.json', 'utf8');
497
505
  if (certConfig) {
498
506
  const certs = lText.parseJson(certConfig);
507
+ configLoaded = true;
499
508
  for (const item of certs) {
500
- const key = await lFs.getContent(lText.isRealPath(item.key) ? item.key : kebab.CERT_CWD + item.key, 'utf8');
501
- const cert = await lFs.getContent(lText.isRealPath(item.cert) ? item.cert : kebab.CERT_CWD + item.cert, 'utf8');
509
+ const keyPath = lText.isRealPath(item.key) ? item.key : kebab.CERT_CWD + item.key;
510
+ const certPath = lText.isRealPath(item.cert) ? item.cert : kebab.CERT_CWD + item.cert;
511
+ const mapKey = keyPath + '|' + certPath;
512
+ newKeys.add(mapKey);
513
+ const key = await lFs.getContent(keyPath, 'utf8');
514
+ const cert = await lFs.getContent(certPath, 'utf8');
502
515
  if (!cert || !key) {
516
+ // --- 文件不存在(可能正在更新),保留旧证书(如果有) ---
503
517
  continue;
504
518
  }
505
519
  const certo = new crypto.X509Certificate(cert);
@@ -507,18 +521,22 @@ async function reloadCert() {
507
521
  'key': key,
508
522
  'cert': cert
509
523
  });
510
- cl.push({
511
- 'cert': certo,
512
- 'sc': sc
513
- });
524
+ certList.set(mapKey, { 'cert': certo, 'sc': sc });
514
525
  }
515
526
  }
516
527
  }
517
528
  catch {
518
529
  // --- NOTHING ---
519
530
  }
520
- certList = cl;
521
- defaultSc = cl.length > 0 ? cl[0].sc : undefined;
531
+ // --- 仅在配置文件加载成功时,移除已从配置中下线的证书 ---
532
+ if (configLoaded) {
533
+ for (const key of certList.keys()) {
534
+ if (!newKeys.has(key)) {
535
+ certList.delete(key);
536
+ }
537
+ }
538
+ }
539
+ defaultSc = certList.size > 0 ? certList.values().next().value.sc : undefined;
522
540
  certHostIndex = {};
523
541
  }
524
542
  // --- 接收主进程回传信号,主要用来 reload,restart ---
package/sys/ctr.js CHANGED
@@ -253,6 +253,8 @@ export class Ctr {
253
253
  // --- 组件 JS 从 stc 目录读取,浏览器同样通过 staticPath(支持 CDN)下载 ---
254
254
  const componentPath = this._config.const.rootPath + 'stc/' + path + '.page.js';
255
255
  if (!await lFs.isFile(componentPath)) {
256
+ lCore.debug(`[CTR][_loadReactPage] componentPath ${componentPath} is not a file`);
257
+ lCore.log(this, `[CTR][_loadReactPage] componentPath ${componentPath} is not a file`, '-error');
256
258
  return '';
257
259
  }
258
260
  try {
@@ -365,6 +367,7 @@ export class Ctr {
365
367
  }
366
368
  catch (e) {
367
369
  lCore.debug(`[CTR][_loadReactPage] ${e.message ?? ''}`);
370
+ lCore.log(this, '[CTR][_loadReactPage] ' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
368
371
  return '';
369
372
  }
370
373
  }