topbit 3.0.3 → 3.0.5

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,11 @@
1
+ 'use strict'
2
+
3
+ module.exports = [
4
+ {
5
+ middleware: async (ctx, next) => {
6
+ console.log(`global ${ctx.path} start`)
7
+ await next(ctx)
8
+ console.log(`global ${ctx.path} end`)
9
+ }
10
+ }
11
+ ]
@@ -0,0 +1,27 @@
1
+ 'use strict'
2
+
3
+ class Test {
4
+ constructor() {
5
+
6
+ }
7
+
8
+ async get(ctx) {
9
+ ctx.ok([
10
+ ctx.method, ctx.path, ctx.routepath, ctx.param
11
+ ])
12
+ }
13
+
14
+ __mid() {
15
+ return [
16
+ {
17
+ middleware: async (ctx, next) => {
18
+ console.log(`test ${ctx.method} start`)
19
+ await next(ctx)
20
+ console.log(`test ${ctx.method} end`)
21
+ }
22
+ }
23
+ ]
24
+ }
25
+ }
26
+
27
+ module.exports = Test
@@ -10,6 +10,18 @@ class Api {
10
10
  ctx.method, ctx.path, ctx.routepath, ctx.param
11
11
  ])
12
12
  }
13
+
14
+ __mid() {
15
+ return [
16
+ {
17
+ middleware: async (ctx, next) => {
18
+ console.log(`api ${ctx.method} start`)
19
+ await next(ctx)
20
+ console.log(`api ${ctx.method} end`)
21
+ }
22
+ }
23
+ ]
24
+ }
13
25
  }
14
26
 
15
27
  module.exports = Api
package/demo/loader.js CHANGED
@@ -7,7 +7,7 @@ let {Loader} = Topbit
7
7
 
8
8
  let app = new Topbit({
9
9
  debug: true,
10
- //loadInfoFile: '--mem',
10
+ loadInfoFile: '--mem',
11
11
  })
12
12
 
13
13
  if (app.isWorker) {
@@ -22,6 +22,8 @@ if (app.isWorker) {
22
22
 
23
23
  app.sched('none')
24
24
 
25
- app.autoWorker(3)
25
+ app.autoWorker(12)
26
26
 
27
- app.daemon(1234, 1)
27
+ app.daemon(1234, 5)
28
+
29
+ //console.log(app.midware.midGroup)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "topbit",
3
- "version": "3.0.3",
3
+ "version": "3.0.5",
4
4
  "description": "A Server-side web framework support http/1.1 and http/2",
5
5
  "main": "src/topbit.js",
6
6
  "directories": {
@@ -3,12 +3,6 @@
3
3
  const fs = require('node:fs');
4
4
  const process = require('node:process');
5
5
 
6
- /**
7
- * 全局中间件容易因为group选项引发问题,若要把加载的controller目录隔离出来,需要针对每个分组加载中间件。
8
- * 就是在全局中间件不指定group的情况下,默认是所有group而不是全局。
9
- * 这样对前缀支持也可以完全兼容。
10
- */
11
-
12
6
  let outWarning = (text, errname = 'Warning', color = '\x1b[2;31;47m') => {
13
7
  setTimeout(() => {
14
8
  console.error(`${color} ${errname}: ${text} \x1b[0m\n`);
@@ -16,32 +10,10 @@ let outWarning = (text, errname = 'Warning', color = '\x1b[2;31;47m') => {
16
10
  };
17
11
 
18
12
  let nameErrorInfo = '名称不能有空格换行特殊字符等,仅支持 字母 数字 减号 下划线,字母开头。';
19
-
20
- //获取模型文件列表
21
- function getModelFiles(filepath) {
22
- let mlist = fs.readdirSync(filepath, { withFileTypes: true });
23
-
24
- let rlist = [];
25
-
26
- for (let i=0; i < mlist.length; i++) {
27
- if (!mlist[i].isFile()) continue;
28
-
29
- if (mlist[i].name.substring(mlist[i].name.length-3) !== '.js')
30
- continue;
31
-
32
- if (mlist[i].name[0] === '!' || mlist[i].name[0] === '_')
33
- continue;
34
-
35
- rlist.push(mlist[i].name);
36
- }
37
-
38
- return rlist;
39
- }
40
13
 
41
14
  class TopbitLoader {
42
15
 
43
16
  constructor(options = {}) {
44
- //let appDir = __dirname + '.';
45
17
  let appDir = '.';
46
18
 
47
19
  this.globalMidTable = [];
@@ -63,73 +35,49 @@ class TopbitLoader {
63
35
  this.optionsCacheLog = null;
64
36
 
65
37
  this.methodNumber = {
66
- get: 1,
67
- post: 2,
68
- put: 3,
69
- delete: 4,
70
- _delete: 4,
71
- options: 5,
72
- head: 6,
73
- trace: 7,
74
- patch: 8,
75
- list: 9
38
+ get: 1, post: 2, put: 3, delete: 4, _delete: 4,
39
+ options: 5, head: 6, trace: 7, patch: 8, list: 9
76
40
  }
77
41
 
78
42
  this.config = {
79
- //当作为模块引入时,根据路径关系,
80
- //可能的位置是node_modules/titbit-loader/loader.js,
81
- //所以默认在父级目录两层和node_modules同级。
82
43
  appPath : appDir,
83
- controllerPath : appDir+'/controller',
84
- modelPath : appDir+'/model',
85
- midwarePath : appDir+'/middleware',
86
- loadModel : true,
44
+ controllerPath : appDir + '/controller',
45
+ midwarePath : appDir + '/middleware',
87
46
 
88
47
  deep : 1,
89
- mname : null,
90
-
91
- modelNamePre: '',
92
-
93
- //如果作为数组则会去加载指定的子目录
48
+ // 如果作为数组则会去加载指定的子目录
94
49
  subgroup : null,
95
-
96
50
  prePath: '',
97
-
98
51
  homeFile: '',
99
-
52
+
53
+ // 控制器初始化参数,默认为 app.service
100
54
  initArgs: null,
101
55
 
102
56
  multi: false,
103
-
104
57
  optionsRoute: true,
105
-
106
58
  fileAsGroup: true,
107
59
 
108
60
  beforeController: null,
109
- afterController: null
61
+ afterController: null,
62
+
63
+ // 新的核心:模型加载钩子函数
64
+ modelLoader: null
110
65
  };
111
66
 
112
- //用于在fileAsGroup模式,为options添加的分组避免和文件的分组冲突。
113
- //考虑这样的情况:controller目录中存在 xyz.js文件和xyz目录。
67
+ // 用于在fileAsGroup模式,为options添加的分组避免和文件的分组冲突。
114
68
  this.groupTag = '@';
115
69
 
116
- //组中间件的缓存,用于fileAsGroup的操作。
70
+ // 组中间件的缓存
117
71
  this.groupCache = {};
118
72
  this.globalCache = [];
119
73
 
120
- //在加载Model时可能需要传递参数
121
- this.mdb = null;
122
- this.mdbMap = null;
123
-
124
74
  this.routepreg = /^[a-z\d\-\_]+$/i;
125
75
 
126
76
  for (let k in options) {
127
-
128
77
  if (k == 'appPath') continue;
129
78
 
130
79
  if (k === 'subgroup') {
131
80
  if (typeof options[k] === 'string') options[k] = [ options[k] ];
132
-
133
81
  if (options[k] instanceof Array) {
134
82
  this.config.subgroup = options[k];
135
83
  }
@@ -144,6 +92,7 @@ class TopbitLoader {
144
92
  switch (k) {
145
93
  case 'beforeController':
146
94
  case 'afterController':
95
+ case 'modelLoader': // 仅保留这个与 Model 相关的配置
147
96
  if (typeof options[k] === 'function') this.config[k] = options[k];
148
97
  break;
149
98
 
@@ -152,15 +101,9 @@ class TopbitLoader {
152
101
  break;
153
102
 
154
103
  case 'homeFile':
155
- case 'modelNamePre':
156
104
  ;(typeof options[k] === 'string') && (this.config[k] = options[k]);
157
105
  break;
158
106
 
159
- case 'mname':
160
- ;(typeof options[k] === 'string' || typeof options[k] === 'symbol') && (this.config[k] = options[k]);
161
- break;
162
-
163
- case 'loadModel':
164
107
  case 'multi':
165
108
  case 'optionsRoute':
166
109
  case 'fileAsGroup':
@@ -168,7 +111,6 @@ class TopbitLoader {
168
111
  break;
169
112
 
170
113
  case 'controllerPath':
171
- case 'modelPath':
172
114
  case 'midwarePath':
173
115
  if (options[k][0] !== '/') {
174
116
  this.config[k] = `${this.config.appPath}/${options[k]}`;
@@ -179,6 +121,7 @@ class TopbitLoader {
179
121
  }
180
122
  }
181
123
 
124
+ // 仅检查 controller 和 middleware 目录
182
125
  try {
183
126
  fs.accessSync(this.config.controllerPath, fs.constants.F_OK);
184
127
  } catch (err) {
@@ -194,42 +137,20 @@ class TopbitLoader {
194
137
  fs.mkdirSync(this.config.midwarePath);
195
138
  }
196
139
  }
197
-
198
- try {
199
- fs.accessSync(this.config.modelPath, fs.constants.F_OK);
200
- } catch (err) {
201
- if (this.config.modelPath.length > 0) {
202
- fs.mkdirSync(this.config.modelPath);
203
- }
204
- }
205
-
206
- if (options.mdb !== undefined && this.config.loadModel) {
207
- this.mdb = options.mdb;
208
- }
209
-
210
- options.mdbMap && (this.mdbMap = options.mdbMap);
211
140
  }
212
141
 
213
142
  fmtPrePath() {
214
143
  let prepath = this.config.prePath.trim().replace(/\/+/g, '/');
215
- if (prepath === '/')
216
- prepath = '';
144
+ if (prepath === '/') prepath = '';
217
145
  else if (prepath.length > 0) {
218
- if (prepath[0] !== '/') {
219
- prepath = `/${prepath}`;
220
- }
221
- if (prepath[ prepath.length - 1 ] === '/') {
222
- prepath = prepath.substring(0, prepath.length - 1);
223
- }
146
+ if (prepath[0] !== '/') prepath = `/${prepath}`;
147
+ if (prepath[ prepath.length - 1 ] === '/') prepath = prepath.substring(0, prepath.length - 1);
224
148
  }
225
-
226
149
  this.config.prePath = prepath;
227
150
  }
228
151
 
229
152
  _fmtSubGroup() {
230
- if (!(this.config.subgroup instanceof Array)) {
231
- return;
232
- }
153
+ if (!(this.config.subgroup instanceof Array)) return;
233
154
  let a;
234
155
  for (let i = 0; i < this.config.subgroup.length; i++) {
235
156
  a = this.config.subgroup[i];
@@ -238,19 +159,39 @@ class TopbitLoader {
238
159
  }
239
160
  }
240
161
 
241
- init(app) {
242
- this.config.loadModel && this.loadModel(app);
243
- this.mdbMap && this.loadModelMap(app);
244
- this.defineServiceFunction(app);
162
+ /**
163
+ * 初始化入口 (Async)
164
+ */
165
+ async init(app) {
166
+ // 注入应用基础信息到 service,供 Controller 或 Model 使用
167
+ Object.defineProperties(app.service, {
168
+ __prepath__: {
169
+ value: this.config.prePath,
170
+ configurable: false, writable: false, enumerable: false
171
+ },
172
+ __appdir__: {
173
+ value: this.config.appPath,
174
+ configurable: false, writable: false, enumerable: false
175
+ }
176
+ });
177
+
178
+ // 1. 执行模型加载钩子 (如果存在)
179
+ if (this.config.modelLoader) {
180
+ await this.config.modelLoader(app.service);
181
+ }
245
182
 
183
+ // 2. 加载控制器 (路由)
246
184
  this.loadController(app);
185
+
186
+ // 3. 加载中间件
247
187
  this.loadMidware(app);
248
- app.service.__titbit_loader__ = true;
188
+
189
+ app.service.__topbit_loader__ = true;
249
190
  }
250
191
 
251
192
  loadController(app) {
252
- if (app.service.__titbit_loader__ && !this.config.multi) {
253
- outWarning('您已经使用titbit-loader加载过路由,多次加载容易导致路由冲突,重复操作将会被终止。');
193
+ if (app.service.__topbit_loader__ && !this.config.multi) {
194
+ outWarning('您已经使用topbit-loader加载过路由,多次加载容易导致路由冲突,重复操作将会被终止。');
254
195
  outWarning('若有需要,可设置选项multi为true允许多次加载。', ' 提示');
255
196
  return false;
256
197
  }
@@ -261,6 +202,10 @@ class TopbitLoader {
261
202
  this.readControllers(this.config.controllerPath, cfiles);
262
203
  let cob = null;
263
204
  let Ctlr;
205
+
206
+ // 默认注入 app.service
207
+ const initArg = this.config.initArgs || app.service;
208
+
264
209
  for (let k in cfiles) {
265
210
  try {
266
211
  Ctlr = require(k);
@@ -272,7 +217,7 @@ class TopbitLoader {
272
217
  cob = new Ctlr();
273
218
 
274
219
  if (cob.init && typeof cob.init === 'function') {
275
- cob.init(this.config.initArgs || app.service);
220
+ cob.init(initArg);
276
221
  }
277
222
 
278
223
  if (this.config.beforeController) {
@@ -333,112 +278,69 @@ class TopbitLoader {
333
278
  let routeParam = '/:id';
334
279
 
335
280
  if (cob.param !== undefined && cob.param !== null && typeof cob.param === 'string') {
336
- routeParam = cob.param.trim()
337
- .replace(/\s+/g, '')
338
- .replace(/\/{2,}/g, '/');
281
+ routeParam = cob.param.trim().replace(/\s+/g, '').replace(/\/{2,}/g, '/');
339
282
  if (routeParam.length > 0 && routeParam[0] !== '/') {
340
283
  routeParam = `/${routeParam}`;
341
284
  }
342
285
  }
343
286
 
344
287
  Object.defineProperty(cob, '__route__', {
345
- configurable: false,
346
- writable: false,
347
- enumerable: false,
288
+ configurable: false, writable: false, enumerable: false,
348
289
  value: route_path
349
290
  });
350
291
 
351
- if (cob.post !== undefined && typeof cob.post === 'function') {
292
+ // 辅助函数:简化路由注册
293
+ const bindRoute = (method, suffix, fnName, typeName) => {
294
+ app.router[method](`${route_path}${suffix}`, cob[fnName].bind(cob), {
295
+ name: `${npre}/${typeName}`,
296
+ group: group
297
+ });
298
+ };
299
+
300
+ if (cob.post && typeof cob.post === 'function') {
352
301
  let postParam = (cob.postParam && typeof cob.postParam === 'string') ? cob.postParam : '';
353
-
354
302
  postParam = postParam.replace(/\/+/g, '/');
355
-
356
303
  if (postParam === '/') postParam = '';
357
-
358
- if (postParam.length > 0 && postParam[0] !== '/') {
359
- postParam = `/${postParam}`;
360
- }
361
-
362
- app.router.post(`${route_path}${postParam}`, cob.post.bind(cob),
363
- {
364
- name: `${npre}/${this.methodNumber.post}`,
365
- group: group
366
- }
367
- );
368
-
304
+ if (postParam.length > 0 && postParam[0] !== '/') postParam = `/${postParam}`;
305
+
306
+ bindRoute('post', postParam, 'post', this.methodNumber.post);
369
307
  }
370
308
 
371
309
  let real_delete_method = '';
372
- if (cob.delete && typeof cob.delete === 'function') {
373
- real_delete_method = 'delete';
374
- } else if (cob._delete && typeof cob._delete === 'function') {
375
- real_delete_method = '_delete';
376
- }
310
+ if (cob.delete && typeof cob.delete === 'function') real_delete_method = 'delete';
311
+ else if (cob._delete && typeof cob._delete === 'function') real_delete_method = '_delete';
377
312
 
378
313
  if (real_delete_method) {
379
- app.router.delete(`${route_path}${routeParam}`,
380
- cob[real_delete_method].bind(cob),
381
- {
382
- name: `${npre}/${this.methodNumber.delete}`,
383
- group: group
384
- }
385
- );
314
+ bindRoute('delete', routeParam, real_delete_method, this.methodNumber.delete);
386
315
  }
387
316
 
388
- if (cob.put !== undefined && typeof cob.put === 'function') {
389
- app.router.put(`${route_path}${routeParam}`, cob.put.bind(cob),
390
- {
391
- name: `${npre}/${this.methodNumber.put}`,
392
- group: group
393
- }
394
- );
317
+ if (cob.put && typeof cob.put === 'function') {
318
+ bindRoute('put', routeParam, 'put', this.methodNumber.put);
395
319
  }
396
320
 
397
- if (cob.get !== undefined && typeof cob.get === 'function') {
398
- app.router.get(`${route_path}${routeParam}`, cob.get.bind(cob),
399
- {
400
- name: `${npre}/${this.methodNumber.get}`,
401
- group: group
321
+ if (cob.get && typeof cob.get === 'function') {
322
+ bindRoute('get', routeParam, 'get', this.methodNumber.get);
323
+ // 主页路由
324
+ if (this.config.homeFile === cf.pathname) {
325
+ app.router.get('/', cob.get.bind(cob), { name: 'home', group: group });
402
326
  }
403
- );
404
- //主页只支持GET请求
405
- if (this.config.homeFile === cf.pathname) {
406
- app.router.get('/', cob.get.bind(cob), {
407
- name: 'home',
408
- group: group
409
- });
410
- }
411
327
  }
412
328
 
413
- if (cob.list !== undefined && typeof cob.list === 'function') {
329
+ if (cob.list && typeof cob.list === 'function') {
414
330
  let listParam = (cob.listParam && typeof cob.listParam === 'string') ? cob.listParam : '';
415
-
416
331
  listParam = listParam.replace(/\/+/g, '/');
417
-
418
332
  if (listParam === '/') listParam = '';
419
-
420
- if (listParam.length > 0 && listParam[0] !== '/') {
421
- listParam = `/${listParam}`;
422
- }
423
-
424
- app.router.get(`${route_path}${listParam}`, cob.list.bind(cob),{
425
- name: `${npre}/${this.methodNumber.list}`,
426
- group: group
427
- });
333
+ if (listParam.length > 0 && listParam[0] !== '/') listParam = `/${listParam}`;
334
+
335
+ bindRoute('get', listParam, 'list', this.methodNumber.list);
428
336
  }
429
337
 
430
- if (cob.patch !== undefined && typeof cob.patch === 'function') {
431
- app.router.patch(`${route_path}${routeParam}`, cob.patch.bind(cob),{
432
- name: `${npre}/${this.methodNumber.patch}`,
433
- group: group
434
- });
338
+ if (cob.patch && typeof cob.patch === 'function') {
339
+ bindRoute('patch', routeParam, 'patch', this.methodNumber.patch);
435
340
  }
436
341
 
437
- if (cob.options !== undefined && typeof cob.options === 'function') {
438
- app.router.options(`${route_path}${routeParam}`, cob.options.bind(cob),{
439
- name: `${npre}/${this.methodNumber.options}`,
440
- group: group
441
- });
342
+ if (cob.options && typeof cob.options === 'function') {
343
+ bindRoute('options', routeParam, 'options', this.methodNumber.options);
442
344
  } else if (this.config.optionsRoute) {
443
345
  let real_group = this.config.fileAsGroup ? dirgroup : group;
444
346
  let tag = this.config.fileAsGroup ? this.groupTag : '';
@@ -451,11 +353,8 @@ class TopbitLoader {
451
353
  }
452
354
  }
453
355
 
454
- if (cob.head !== undefined && typeof cob.head === 'function') {
455
- app.router.head(`${route_path}${routeParam}`, cob.head.bind(cob),{
456
- name: `${npre}/${this.methodNumber.head}`,
457
- group: group
458
- });
356
+ if (cob.head && typeof cob.head === 'function') {
357
+ bindRoute('head', routeParam, 'head', this.methodNumber.head);
459
358
  }
460
359
 
461
360
  this.fileMidTable[cf.filegroup] = {
@@ -496,15 +395,10 @@ class TopbitLoader {
496
395
  }
497
396
 
498
397
  /**
499
- * 加载中间件,仅仅是通过一个js文件,
500
- * 中间件不宜过度使用,否则容易混乱。
398
+ * 加载中间件
501
399
  */
502
400
  loadMidware(app) {
503
- if (app.service.__titbit_loader__ && !this.config.multi) {
504
- outWarning('您已经使用titbit-loader加载过中间件,多个实例容易会导致中间件多次加载或冲突,重复操作将会被终止。');
505
- outWarning('若有需要,可设置选项multi为true允许多次加载。', ' 提示');
506
- return false;
507
- }
401
+ if (app.service.__topbit_loader__ && !this.config.multi) return;
508
402
 
509
403
  this._getGroupList();
510
404
 
@@ -564,19 +458,9 @@ class TopbitLoader {
564
458
 
565
459
  checkMiddleware(m) {
566
460
  if (m.middleware === undefined) return false;
567
-
568
- if (typeof m.middleware === 'function' && m.middleware.constructor.name === 'AsyncFunction') {
569
- return true;
570
- }
571
-
572
- if (m.middleware.mid && typeof m.middleware.mid === 'function') {
573
- return true;
574
- }
575
-
576
- if (m.middleware.middleware && typeof m.middleware.middleware === 'function') {
577
- return true;
578
- }
579
-
461
+ if (typeof m.middleware === 'function' && m.middleware.constructor.name === 'AsyncFunction') return true;
462
+ if (m.middleware.mid && typeof m.middleware.mid === 'function') return true;
463
+ if (m.middleware.middleware && typeof m.middleware.middleware === 'function') return true;
580
464
  return false;
581
465
  }
582
466
 
@@ -619,43 +503,27 @@ class TopbitLoader {
619
503
  }
620
504
  return false;
621
505
  } else if (m.mode === 'online' || m.mode === 'product') {
622
- //只在正式环境加载
623
506
  if (app.service.TEST || app.service.DEV) {
624
- //console.log(`测试环境不加载中间件`, m);
625
507
  return false;
626
508
  }
627
509
  return true;
628
510
  }
629
511
  }
630
- //console.log('加载···', m);
631
512
  return true;
632
513
  }
633
514
 
634
515
  loadGlobalMidware(app, m) {
635
- //检测是否是开发环境,并确定是否加载中间件。
636
- if (this._checkMidwareMode(app, m) === false) {
637
- return;
638
- }
516
+ if (this._checkMidwareMode(app, m) === false) return;
639
517
 
640
- let opts = null;
641
-
642
518
  let makeOpts = (groupname = null) => {
643
519
  let op = {};
644
- if (m.method !== undefined) {
645
- op.method = m.method;
646
- }
647
- if (groupname) {
648
- op.group = groupname[0] === '/' ? groupname : `/${groupname}`;
649
- }
650
-
651
- if (m.pre) {
652
- op.pre = true;
653
- }
520
+ if (m.method !== undefined) op.method = m.method;
521
+ if (groupname) op.group = groupname[0] === '/' ? groupname : `/${groupname}`;
522
+ if (m.pre) op.pre = true;
654
523
  return op;
655
524
  };
656
525
 
657
526
  let mobj;
658
-
659
527
  let group = this.groupList;
660
528
 
661
529
  if (group) {
@@ -668,30 +536,18 @@ class TopbitLoader {
668
536
  for (let g of group) {
669
537
  mobj && app.use(mobj, makeOpts(g));
670
538
  }
671
-
672
539
  return;
673
540
  }
674
-
675
541
  }
676
542
 
677
543
  loadGroupMidware(app, m, group) {
678
-
679
- if (this._checkMidwareMode(app, m) === false) {
680
- return;
681
- }
682
-
683
- if ((!m.name || m.name === '') && !m.middleware) {
684
- return;
685
- }
544
+ if (this._checkMidwareMode(app, m) === false) return;
545
+ if ((!m.name || m.name === '') && !m.middleware) return;
686
546
  let opts = {
687
547
  group: `${this.config.prePath}${group}`,
688
548
  };
689
- if (m.method !== undefined) {
690
- opts.method = m.method;
691
- }
692
- if (m.pre) {
693
- opts.pre = true;
694
- }
549
+ if (m.method !== undefined) opts.method = m.method;
550
+ if (m.pre) opts.pre = true;
695
551
 
696
552
  let mobj = this.getMidwareInstance(m);
697
553
  if (mobj) {
@@ -704,23 +560,10 @@ class TopbitLoader {
704
560
  }
705
561
  }
706
562
 
707
- /**
708
- *
709
- * @param {object} app
710
- * @param {object} m
711
- * @param {string} f
712
- * @param {string} group 包括前缀的分组,若开启fileAsGroup则为filegroup
713
- * @param {string} dirgroup 文件名,不包括前缀
714
- * @returns
715
- */
716
563
  loadFileMidware(app, m, f, group, dirgroup) {
717
- if (this._checkMidwareMode(app, m) === false) {
718
- return;
719
- }
564
+ if (this._checkMidwareMode(app, m) === false) return;
720
565
 
721
- //group已经带有prepath前缀。
722
566
  let opts = { group };
723
-
724
567
  f = `${this.config.prePath}${f}`;
725
568
 
726
569
  if (!this.fileAsGroup && m.path === undefined) {
@@ -730,9 +573,7 @@ class TopbitLoader {
730
573
  ];
731
574
  }
732
575
 
733
- if (m.path && typeof m.path === 'string') {
734
- m.path = [ m.path ];
735
- }
576
+ if (m.path && typeof m.path === 'string') m.path = [ m.path ];
736
577
 
737
578
  if (m.path && Array.isArray(m.path)) {
738
579
  opts.name = [];
@@ -740,168 +581,13 @@ class TopbitLoader {
740
581
  for (let p of m.path) {
741
582
  path_num = this.methodNumber[p.toLowerCase()];
742
583
  if (path_num === undefined) continue;
743
-
744
584
  opts.name.push(`${f}/${path_num}`);
745
585
  }
746
586
  }
747
587
 
748
- if (m.pre) {
749
- opts.pre = true;
750
- }
751
-
588
+ if (m.pre) opts.pre = true;
752
589
  let mobj = this.getMidwareInstance(m);
753
- if (mobj) {
754
- app.use(mobj, opts);
755
- }
756
- }
757
-
758
- loadModelMap(app) {
759
- if (typeof this.mdbMap !== 'object')
760
- throw new Error('mdbMap必须是object类型。');
761
-
762
- let defpath = this.config.modelPath;
763
- let sk;
764
- let curpath;
765
- let obj;
766
-
767
- let loadObj = (serv, odb, fpath) => {
768
- let mlist = getModelFiles(fpath);
769
- let mname;
770
- mlist.forEach(m => {
771
- mname = m.substring(0, m.length - 3);
772
- serv[mname] = this.getModelInstance(fpath + '/' + m, odb);
773
- });
774
- };
775
- for (let k in this.mdbMap) {
776
- obj = this.mdbMap[k];
777
- if (!obj || typeof obj !== 'object') continue;
778
-
779
- sk = '@' + k;
780
- if (!app.service[sk]) app.service[sk] = {};
781
- curpath = obj.path || defpath;
782
-
783
- loadObj(app.service[sk], obj.mdb || null, curpath);
784
- }
785
-
786
- }
787
-
788
- defineServiceFunction(app) {
789
- if (app.service.getModel) return;
790
-
791
- let sfe = function (mk, mpre, name, key = '') {
792
- let m;
793
- if (!key) {
794
- m = mk ? this[mk] : this;
795
- let oo = m[mpre + name];
796
- if (!oo) throw new Error(`无法获取模型实例${name}`);
797
- return oo;
798
- }
799
-
800
- let k = '@' + key;
801
- if (!this[k] || !this[k][name]) throw new Error(`无法获取模型实例${name}`);
802
- return this[k][name];
803
- };
804
-
805
- app.service.getModel = sfe.bind(app.service, this.config.mname, this.config.modelNamePre);
806
-
807
- let fm = function (key) {
808
- let k = '@' + key;
809
- if (!this[k]) throw new Error('无法获取服务容器 ' + key);
810
- return this[k];
811
- };
812
-
813
- app.service.modelMap = fm.bind(app.service);
814
-
815
- Object.defineProperties(app.service, {
816
- __prepath__: {
817
- value: this.config.prePath,
818
- configurable: false,
819
- writable: false,
820
- enumerable: false
821
- },
822
-
823
- __appdir__: {
824
- value: this.config.appPath,
825
- configurable: false,
826
- writable: false,
827
- enumerable: false
828
- }
829
- });
830
-
831
- }
832
-
833
- bindModelAttr(app) {
834
- if (this.config.mname) {
835
- if (app.service[this.config.mname] === undefined) app.service[this.config.mname] = {};
836
- app.service.__model__ = app.service[this.config.mname];
837
- }
838
- }
839
-
840
- /**
841
- * 加载数据库操作接口,一个表要对应一个js文件,
842
- */
843
- loadModel(app) {
844
- if (this.config.mname && app.service[this.config.mname] === undefined) {
845
- app.service[this.config.mname] = {};
846
- }
847
-
848
- this.bindModelAttr(app);
849
-
850
- try {
851
-
852
- let mlist = getModelFiles(this.config.modelPath);
853
-
854
- mlist.forEach( m => {
855
- this.requireModel(app, m);
856
- });
857
-
858
- } catch (err) {
859
- console.error(err);
860
- }
861
- }
862
-
863
- getModelInstance(mfile, db) {
864
- let m = require(mfile);
865
-
866
- // Arrow Function has no prototype
867
- if (typeof m !== 'function' || m.prototype === undefined) {
868
- if (m.init && typeof m.init === 'function') {
869
- m.init(db);
870
- }
871
-
872
- return m;
873
- }
874
-
875
- return db ? new m(db) : new m();
876
- }
877
-
878
- requireModel(app, mfile) {
879
- try {
880
- let mobj = this.getModelInstance(this.config.modelPath + '/' + mfile, this.mdb);
881
-
882
- let mname = mfile.substring(0, mfile.length-3);
883
-
884
- mname = `${this.config.modelNamePre}${mname}`;
885
-
886
- if (!this.config.mname) {
887
- if (app.service[mname] !== undefined) {
888
- outWarning(`model 冲突 ---- ${mfile}{${mname}} 已经设置。`);
889
- return false;
890
- }
891
- app.service[mname] = mobj;
892
- } else {
893
- if (app.service[this.config.mname][mname] !== undefined) {
894
- outWarning(`model 冲突 ---- ${mfile}{${mname}} 已经设置。`);
895
- return false;
896
- }
897
- app.service[this.config.mname][mname] = mobj;
898
- }
899
- } catch (err) {
900
- console.error(err.message, ' -- ', mfile);
901
- return false;
902
- }
903
-
904
- return true;
590
+ if (mobj) app.use(mobj, opts);
905
591
  }
906
592
 
907
593
  stripExtName(filename) {
@@ -911,10 +597,6 @@ class TopbitLoader {
911
597
 
912
598
  /**
913
599
  * 读取控制器目录中的文件
914
- * @param {string} cdir
915
- * @param {object} cfiles
916
- * @param {number} deep
917
- * @param {string} dirgroup
918
600
  */
919
601
  readControllers(cdir, cfiles, deep = 0, dirgroup = '') {
920
602
  let files = fs.readdirSync(cdir, {withFileTypes:true});
@@ -924,16 +606,10 @@ class TopbitLoader {
924
606
 
925
607
  if (files[i].isDirectory() && deep < 1) {
926
608
 
927
- if (files[i].name[0] == '!') {
928
- continue;
929
- }
609
+ if (files[i].name[0] == '!') continue;
930
610
 
931
- //检测是否启用了分组控制
932
- //这时候,只有在subgroup之内的才会去加载
933
611
  if (this.config.subgroup instanceof Array) {
934
- if (this.config.subgroup.indexOf(files[i].name) < 0) {
935
- continue;
936
- }
612
+ if (this.config.subgroup.indexOf(files[i].name) < 0) continue;
937
613
  }
938
614
 
939
615
  if (this.routepreg.test(files[i].name) === false) {
@@ -947,17 +623,9 @@ class TopbitLoader {
947
623
  );
948
624
 
949
625
  } else if (files[i].isFile()) {
950
- if (files[i].name[0] === '!') {
951
- continue;
952
- }
953
-
954
- if (files[i].name.length < 4) {
955
- continue;
956
- }
957
-
958
- if (files[i].name.substring(files[i].name.length-3) !== '.js') {
959
- continue;
960
- }
626
+ if (files[i].name[0] === '!') continue;
627
+ if (files[i].name.length < 4) continue;
628
+ if (files[i].name.substring(files[i].name.length-3) !== '.js') continue;
961
629
 
962
630
  if (this.config.subgroup instanceof Array && deep < 1) {
963
631
  if (this.config.subgroup.indexOf('') < 0 && this.config.subgroup.indexOf('/') < 0) {
@@ -966,7 +634,6 @@ class TopbitLoader {
966
634
  }
967
635
 
968
636
  if (files[i].name == '__mid.js') {
969
- //顶层并且忽略全局中间件选项为false则加载全局中间件。
970
637
  if (deep == 0) {
971
638
  this.globalMidTable = require(cdir+'/'+files[i].name);
972
639
  } else {
@@ -991,9 +658,8 @@ class TopbitLoader {
991
658
  };
992
659
  }
993
660
  }
994
-
995
661
  }
996
662
 
997
663
  }
998
664
 
999
- module.exports = TopbitLoader;
665
+ module.exports = TopbitLoader;
package/src/midcore.js CHANGED
@@ -16,7 +16,7 @@ class MidCore {
16
16
  };
17
17
  }
18
18
 
19
- this.globalKey = `_GLOBAL_0129_${Math.random().toString(16).substring(2)}_`;
19
+ this.globalKey = `_GLOBAL_0129_${Math.random().toString(16).substring(2).substring(0,6)}_`;
20
20
 
21
21
  this.midGroup = Object.create(null);
22
22
 
@@ -328,14 +328,14 @@ class TopbitToken {
328
328
  return opts
329
329
  }
330
330
 
331
- makeAccessToken(info, id=null, key=null) {
331
+ makeToken(info, id=null, key=null) {
332
332
  let riv = randstring(this.ivLength)
333
333
  let tid = id || this.randId()
334
334
  let token = this.makeikv(info, {id: tid, iv: riv, key: key||this.key})
335
335
  return `${riv}.${token}`
336
336
  }
337
337
 
338
- verifyAccessToken(edata) {
338
+ verifyToken(edata) {
339
339
  let tarr = edata.split('.')
340
340
 
341
341
  if (tarr.length != 2 || !tarr[0] || !tarr[1]) {
@@ -420,7 +420,7 @@ class TopbitToken {
420
420
  return c.status(self.failedCode).to('!token')
421
421
  }
422
422
 
423
- let uinfo = self.verifyAccessToken(token)
423
+ let uinfo = self.verifyToken(token)
424
424
 
425
425
  if (!uinfo.ok) {
426
426
  return c.status(self.failedCode).to(uinfo.errcode)