topbit 2.0.0 → 3.0.1

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.
Files changed (72) hide show
  1. package/README.cn.md +132 -177
  2. package/README.md +801 -592
  3. package/bin/new-ctl.js +7 -3
  4. package/demo/allow.js +13 -13
  5. package/demo/controller/api.js +15 -0
  6. package/demo/extends.js +5 -0
  7. package/demo/http2.js +34 -0
  8. package/demo/http2_proxy_backend.js +45 -0
  9. package/demo/http2proxy.js +48 -0
  10. package/demo/http_proxy_backend.js +44 -0
  11. package/demo/httpproxy.js +47 -0
  12. package/demo/loader.js +27 -0
  13. package/demo/log.js +1 -1
  14. package/demo/memlimit.js +1 -1
  15. package/demo/min.js +1 -1
  16. package/demo/serv.js +1 -1
  17. package/images/topbit-middleware.webp +0 -0
  18. package/images/topbit.png +0 -0
  19. package/package.json +7 -6
  20. package/src/_loadExtends.js +21 -0
  21. package/src/bodyparser.js +1 -1
  22. package/src/context1.js +19 -19
  23. package/src/context2.js +11 -8
  24. package/src/ctxpool.js +1 -0
  25. package/src/extends/Http2Pool.js +365 -0
  26. package/src/extends/__randstring.js +24 -0
  27. package/src/extends/cookie.js +44 -0
  28. package/src/extends/cors.js +334 -0
  29. package/src/extends/errorlog.js +252 -0
  30. package/src/extends/http2limit.js +126 -0
  31. package/src/extends/http2proxy.js +691 -0
  32. package/src/extends/jwt.js +217 -0
  33. package/src/extends/mixlogger.js +63 -0
  34. package/src/extends/paramcheck.js +266 -0
  35. package/src/extends/proxy.js +662 -0
  36. package/src/extends/realip.js +34 -0
  37. package/src/extends/referer.js +68 -0
  38. package/src/extends/resource.js +398 -0
  39. package/src/extends/session.js +174 -0
  40. package/src/extends/setfinal.js +50 -0
  41. package/src/extends/sni.js +48 -0
  42. package/src/extends/sse.js +293 -0
  43. package/src/extends/timing.js +111 -0
  44. package/src/extends/tofile.js +123 -0
  45. package/src/http1.js +15 -16
  46. package/src/http2.js +5 -5
  47. package/src/httpc.js +3 -3
  48. package/src/lib/npargv.js +354 -0
  49. package/src/lib/zipdata.js +45 -0
  50. package/src/middleware1.js +15 -16
  51. package/src/middleware2.js +4 -9
  52. package/src/token/token.js +4 -5
  53. package/src/topbit.js +13 -11
  54. package/test/{test-helper.js → test-ext.js} +1 -1
  55. package/test/test-route.js +1 -1
  56. package/cache/allow.js +0 -130
  57. package/cache/errserv.js +0 -45
  58. package/cache/minserv.js +0 -167
  59. package/cache/router.js +0 -84
  60. package/cache/servsock.js +0 -286
  61. package/cache/sni.js +0 -66
  62. package/images/titbit-middleware.png +0 -0
  63. package/images/titbit.png +0 -0
  64. package/tmp/buff-code +0 -134
  65. package/tmp/devplan +0 -9
  66. package/tmp/evt-test.js +0 -34
  67. package/tmp/fastParseUrl.js +0 -302
  68. package/tmp/router-rule.js +0 -559
  69. package/tmp/test-cdps.js +0 -122
  70. package/tmp/titbit.js +0 -1286
  71. /package/{cache/rsa → demo/cert}/localhost-cert.pem +0 -0
  72. /package/{cache/rsa → demo/cert}/localhost-privkey.pem +0 -0
@@ -0,0 +1,354 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * {
5
+ * '-a' : {
6
+ * name: 'a',
7
+ * type: 'number|string|int|float|bool',
8
+ * min: 0,
9
+ * max: 100,
10
+ * match: RegExp,
11
+ * default : any
12
+ * },
13
+ *
14
+ * '$2': {
15
+ *
16
+ * },
17
+ * {
18
+ * '--port=' : {
19
+ * name : 'port',
20
+ * type : 'int',
21
+ * min: 2000,
22
+ * max: 5000,
23
+ * default: 3456
24
+ * }
25
+ * }
26
+ * }
27
+ *
28
+ */
29
+
30
+ function setVal (a, ainfo, obj, next) {
31
+
32
+ if (ainfo.type && ['int', 'float', 'number'].indexOf(ainfo.type) >= 0) {
33
+ if (isNaN(next)) {
34
+ return {
35
+ ok: false,
36
+ message: `${a} 类型错误,要求参数必须是数字类型:${next}`
37
+ }
38
+ }
39
+
40
+ if (ainfo.type === 'int' || ainfo.type === 'number') {
41
+ next = parseInt(next)
42
+ } else {
43
+ next = parseFloat(next)
44
+ }
45
+ }
46
+
47
+ if (ainfo.min !== undefined) {
48
+ if (next < ainfo.min) {
49
+ return {
50
+ ok: false,
51
+ message: `${a} 数值不能低于 ${ainfo.min}`
52
+ }
53
+ }
54
+ }
55
+
56
+ if (ainfo.max !== undefined) {
57
+ if (next > ainfo.max) {
58
+ return {
59
+ ok: false,
60
+ message: `${a} 数值不能大于 ${ainfo.max}`
61
+ }
62
+ }
63
+ }
64
+
65
+ if (ainfo.match && ainfo.match instanceof RegExp) {
66
+ if (!ainfo.match.test(next)) {
67
+ return {
68
+ ok: false,
69
+ message: `${a} 数值无法匹配 ${next}`
70
+ }
71
+ }
72
+ }
73
+
74
+ let val = next
75
+
76
+ if (ainfo.callback && typeof ainfo.callback === 'function') {
77
+ val = ainfo.callback(next)
78
+ if (val === undefined) val = next
79
+ }
80
+
81
+ obj[ ainfo.name || a ] = val
82
+
83
+ return {
84
+ ok: true,
85
+ message: ''
86
+ }
87
+
88
+ }
89
+
90
+ function checkAndSet (a, ainfo, obj, next) {
91
+
92
+ if (typeof ainfo === 'boolean') {
93
+ obj[a] = true
94
+ return {
95
+ ok: true,
96
+ message: '',
97
+ op: 'none'
98
+ }
99
+ }
100
+
101
+ if (ainfo.type === 'bool' || ainfo.type === 'boolean') {
102
+ obj[ ainfo.name || a ] = true
103
+
104
+ return {
105
+ ok: true,
106
+ message: '',
107
+ op: 'none'
108
+ }
109
+ }
110
+
111
+ if (next === null) {
112
+ return {
113
+ ok: false,
114
+ message: `${a} 必须携带参数。`
115
+ }
116
+ }
117
+
118
+ let r = setVal(a, ainfo, obj, next)
119
+
120
+ if (!r.ok && ainfo.default !== undefined) {
121
+ r.ok = true
122
+ }
123
+
124
+ if (r.ok) {
125
+ r.op = 'next'
126
+
127
+ if (a[a.length - 1] === '=') {
128
+ r.op = 'none'
129
+ }
130
+ }
131
+
132
+ return r
133
+ }
134
+
135
+ function setAutoDefault (opts, k) {
136
+ switch (opts[k].type) {
137
+ case 'number':
138
+ case 'int':
139
+ case 'float':
140
+ opts[k].default = 0
141
+ if (opts[k].min)
142
+ opts[k].default = opts[k].min;
143
+ break
144
+
145
+ case 'string':
146
+ opts[k].default = ''
147
+ break
148
+
149
+ case 'bool':
150
+ case 'boolean':
151
+ opts[k].default = false
152
+ break
153
+ }
154
+ }
155
+
156
+ /*
157
+ * opts['@autoDefault'] = true 表示自动设定默认值
158
+ *
159
+ * */
160
+
161
+ function parseArgv (options = null, obj = null) {
162
+ if (!options) options = {}
163
+
164
+ if (obj === null) obj = {}
165
+
166
+ let opts = {}
167
+
168
+ for (let k in options) {
169
+ opts[k] = options[k]
170
+ }
171
+
172
+ let autoDefault = false
173
+
174
+ if (opts['@autoDefault'] === undefined) opts['@autoDefault'] = true;
175
+
176
+ if (opts['@autoDefault'] !== undefined) {
177
+ autoDefault = !!opts['@autoDefault']
178
+ delete opts['@autoDefault']
179
+ }
180
+
181
+ let commands = []
182
+ if (opts['@command'] !== undefined) {
183
+ if (typeof opts['@command'] === 'string') {
184
+ opts['@command'].split(' ').filter(p => p.length > 0).forEach(a => {
185
+ commands.push(a.trim())
186
+ })
187
+ } else if (Array.isArray(opts['@command'])) {
188
+ commands = opts['@command'];
189
+ }
190
+ delete opts['@command'];
191
+ }
192
+
193
+ let defaultCommand = ''
194
+ if (opts['@defaultCommand'] !== undefined && commands.indexOf(opts['@defaultCommand']) >= 0) {
195
+ defaultCommand = opts['@defaultCommand'];
196
+ delete opts['@defaultCommand'];
197
+ }
198
+
199
+ let userCommand = null
200
+ let commandFromInput = false
201
+ if (commands.length > 0) {
202
+ if (process.argv.length < 3) {
203
+ if (defaultCommand) userCommand = defaultCommand;
204
+ else {
205
+ return {
206
+ ok: false,
207
+ message: '请使用子命令:' + commands.join('|'),
208
+ args: obj
209
+ }
210
+ }
211
+ } else if (commands.indexOf(process.argv[2]) < 0) {
212
+ if (defaultCommand) userCommand = defaultCommand;
213
+ else {
214
+ return {
215
+ ok: false,
216
+ message: '不支持的子命令',
217
+ args: obj
218
+ }
219
+ }
220
+ } else {
221
+ commandFromInput = true
222
+ userCommand = process.argv[2]
223
+ }
224
+ }
225
+
226
+ let tmp_val
227
+
228
+ for (let k in opts) {
229
+ if (typeof opts[k] === 'string' && opts[k].trim().length > 0) {
230
+ opts[k] = {
231
+ name: opts[k].trim(),
232
+ type: 'boolean',
233
+ default: false
234
+ }
235
+ }
236
+
237
+ if (typeof opts[k] !== 'object' || opts[k].toString() !== '[object Object]') {
238
+
239
+ opts[k] = {
240
+ type : 'boolean',
241
+ name : k,
242
+ default: false
243
+ }
244
+
245
+ } else if (opts[k].type === undefined) {
246
+
247
+ if (k.indexOf('=') > 0) {
248
+ opts[k].type = 'string'
249
+ } else if (opts[k].match || opts[k].callback) {
250
+ opts[k].type = 'string'
251
+ } else {
252
+ if (opts[k].min !== undefined || opts[k].max !== undefined) {
253
+ opts[k].type = 'int'
254
+ } else if (opts[k].default !== undefined) {
255
+ tmp_val = typeof opts[k].default
256
+ if (tmp_val === 'number' || tmp_val === 'boolean' || tmp_val === 'string') {
257
+ opts[k].type = tmp_val
258
+ } else {
259
+ opts[k].type = 'string'
260
+ }
261
+ } else {
262
+ opts[k].type = 'bool'
263
+ }
264
+ }
265
+
266
+ }
267
+
268
+ autoDefault && opts[k].default === undefined && setAutoDefault(opts, k)
269
+
270
+ if (opts[k].type === 'bool' || opts[k].type === 'boolean') {
271
+ obj[ opts[k].name || k ] = false
272
+ } else if (opts[k].default !== undefined) {
273
+ obj[ opts[k].name || k ] = opts[k].default
274
+ }
275
+
276
+ }
277
+
278
+ for (let k in opts) {
279
+ if (opts[k].alias && typeof opts[k].alias === 'string' && opts[k].alias !== k) {
280
+ opts[opts[k].alias] = opts[k]
281
+ }
282
+ }
283
+
284
+ let a
285
+ let next
286
+ let next_end = process.argv.length - 1
287
+ let r = ''
288
+ let i = 2
289
+ let offset = 1
290
+ if (commands.length > 0 && commandFromInput) {
291
+ i++
292
+ offset = 2
293
+ }
294
+
295
+ let ind = 0
296
+ let pos_key = ''
297
+ let aList = []
298
+
299
+ while (i < process.argv.length) {
300
+
301
+ //先检测是否存在对位置的引用
302
+ pos_key = '$' + `${i-offset}`
303
+ if (opts[pos_key]) {
304
+ r = checkAndSet(pos_key, opts[pos_key], obj, process.argv[i])
305
+ if (!r.ok) {
306
+ r.args = obj
307
+ return r
308
+ }
309
+ i++
310
+ continue
311
+ }
312
+
313
+ a = process.argv[i]
314
+
315
+ next = i < next_end ? process.argv[i+1] : null
316
+
317
+ ind = a.indexOf('=')
318
+
319
+ if (ind > 0) {
320
+ a = a.substring(0, ind+1)
321
+ next = process.argv[i].substring(ind+1)
322
+ }
323
+
324
+ if (opts[a]) {
325
+ r = checkAndSet(a, opts[a], obj, next)
326
+ if (!r.ok) {
327
+ r.args = obj
328
+ return r
329
+ }
330
+
331
+ if (r.op === 'next') {
332
+ i += 2
333
+ continue
334
+ }
335
+
336
+ } else {
337
+ if (a[0] !== '-') {
338
+ a[0] !== '\\' ? aList.push(a) : aList.push(a.substring(1))
339
+ }
340
+ }
341
+
342
+ i++
343
+ }
344
+
345
+ return {
346
+ ok: true,
347
+ message: '',
348
+ args: obj,
349
+ list: aList,
350
+ command: userCommand
351
+ }
352
+ }
353
+
354
+ module.exports = parseArgv
@@ -0,0 +1,45 @@
1
+ 'use strict'
2
+
3
+ const zlib = require('zlib')
4
+ const fs = require('fs')
5
+
6
+ const fsp = fs.promises
7
+
8
+ let zipdata = async (pathfile, isData=false) => {
9
+ let d
10
+
11
+ if (isData) {
12
+ d = pathfile
13
+ } else {
14
+ d = await fsp.readFile(pathfile)
15
+ }
16
+
17
+ return await new Promise((rv, rj) => {
18
+ zlib.gzip(d, (err, zipdata) => {
19
+ if (err) {
20
+ rj (err)
21
+ }
22
+
23
+ rv(zipdata)
24
+ })
25
+ })
26
+ }
27
+
28
+ zipdata.unzip = async (pathfile, isData = false) => {
29
+ let d
30
+ if (isData) {
31
+ d = pathfile
32
+ } else {
33
+ d = await fsp.readFile(pathfile)
34
+ }
35
+
36
+ return new Promise((rv, rj) => {
37
+ zlib.unzip(d, (err, data) => {
38
+ if (err) rj(err)
39
+
40
+ rv(data)
41
+ })
42
+ })
43
+ }
44
+
45
+ module.exports = zipdata
@@ -16,18 +16,18 @@ class Middleware extends MidCore {
16
16
  await this.exec(ctx, ctx.group);
17
17
  } catch (err) {
18
18
 
19
- this.errorHandle(err, '--ERR-RESPONSE--');
19
+ this.errorHandle(err, '--ERR-res--');
20
20
 
21
21
  try {
22
- if (ctx.response && !ctx.response.writableEnded) {
23
- ctx.response.statusCode = 500;
24
- ctx.response.end();
22
+ if (ctx.res && !ctx.res.writableEnded) {
23
+ ctx.res.statusCode = 500;
24
+ ctx.res.end();
25
25
  }
26
26
  } catch (err) {}
27
27
 
28
28
  } finally {
29
- ctx.request = null;
30
- ctx.response = null;
29
+ ctx.req = null;
30
+ ctx.res = null;
31
31
  ctx.data = null;
32
32
  ctx.box = null;
33
33
  ctx.service = null;
@@ -37,7 +37,6 @@ class Middleware extends MidCore {
37
37
  ctx.rawBody = null;
38
38
  ctx.files = null;
39
39
  ctx.param = null;
40
- ctx.reply = null;
41
40
  ctx.user = null;
42
41
  ctx = null;
43
42
  }
@@ -51,9 +50,9 @@ class Middleware extends MidCore {
51
50
  */
52
51
  addFinal() {
53
52
  let fr = async (ctx, next) => {
54
- await next();
53
+ await next(ctx);
55
54
 
56
- if (!ctx.response || ctx.response.writableEnded || !ctx.response.writable || ctx.response.destroyed) {
55
+ if (!ctx.res || ctx.res.writableEnded || !ctx.res.writable || ctx.res.destroyed) {
57
56
  return;
58
57
  }
59
58
 
@@ -63,10 +62,10 @@ class Middleware extends MidCore {
63
62
  let content_type = 'text/plain;charset=utf-8';
64
63
  let datatype = typeof ctx.data;
65
64
 
66
- if (!(ctx.response.headersSent || ctx.response.hasHeader('content-type')) )
65
+ if (!(ctx.res.headersSent || ctx.res.hasHeader('content-type')) )
67
66
  {
68
67
  if (datatype === 'object') {
69
- ctx.response.setHeader('content-type','application/json;charset=utf-8');
68
+ ctx.res.setHeader('content-type','application/json;charset=utf-8');
70
69
  }
71
70
  else if (datatype === 'string' && ctx.data.length > 1) {
72
71
  switch (ctx.data[0]) {
@@ -80,18 +79,18 @@ class Middleware extends MidCore {
80
79
  break;
81
80
  default:;
82
81
  }
83
- ctx.response.setHeader('content-type', content_type);
82
+ ctx.res.setHeader('content-type', content_type);
84
83
  }
85
84
  }
86
85
 
87
86
  if (!ctx.data) {
88
- ctx.response.end()
87
+ ctx.res.end()
89
88
  } else if (ctx.data instanceof Buffer || datatype === 'string') {
90
- ctx.response.end(ctx.data, ctx.dataEncoding)
89
+ ctx.res.end(ctx.data, ctx.dataEncoding)
91
90
  } else if (datatype === 'number') {
92
- ctx.response.end(`${ctx.data}`)
91
+ ctx.res.end(`${ctx.data}`)
93
92
  } else {
94
- ctx.response.end(JSON.stringify(ctx.data))
93
+ ctx.res.end(JSON.stringify(ctx.data))
95
94
  }
96
95
 
97
96
  }
@@ -34,7 +34,8 @@ class Middleware extends MidCore {
34
34
  ctx.data = null;
35
35
  ctx.dataHeaders = null;
36
36
  ctx.stream = null;
37
- ctx.request = null;
37
+ ctx.req = null;
38
+ ctx.res = null;
38
39
  ctx.service = null;
39
40
  ctx.box = null;
40
41
  ctx.requestCall = null;
@@ -43,7 +44,6 @@ class Middleware extends MidCore {
43
44
  ctx.rawBody = null;
44
45
  ctx.files = null;
45
46
  ctx.param = null;
46
- ctx.reply = null;
47
47
  ctx.user = null;
48
48
  ctx = null;
49
49
  }
@@ -53,14 +53,9 @@ class Middleware extends MidCore {
53
53
  /** 这是最终添加的请求中间件。基于洋葱模型,这个中间件最先执行,所以最后会返回响应结果。 */
54
54
  addFinal() {
55
55
  let fr = async (ctx, next) => {
56
-
57
- await next();
56
+ await next(ctx);
58
57
 
59
- if(!ctx.stream
60
- || ctx.stream.closed
61
- || ctx.stream.destroyed
62
- || !ctx.stream.writable)
63
- {
58
+ if(!ctx.stream || ctx.stream.closed || ctx.stream.destroyed || !ctx.stream.writable) {
64
59
  return ;
65
60
  }
66
61
 
@@ -436,13 +436,13 @@ class TopbitToken {
436
436
  let token = c.headers.authorization
437
437
 
438
438
  if (!token) {
439
- return c.status(self.failedCode).send('!token')
439
+ return c.status(self.failedCode).to('!token')
440
440
  }
441
441
 
442
- let uinfo = self.verify(token)
442
+ let uinfo = self.verifyAccessToken(token)
443
443
 
444
444
  if (!uinfo.ok) {
445
- return c.status(self.failedCode).send(uinfo.errcode)
445
+ return c.status(self.failedCode).to(uinfo.errcode)
446
446
  }
447
447
 
448
448
  c.box.user = uinfo
@@ -452,11 +452,10 @@ class TopbitToken {
452
452
  c.setHeader('x-refresh-token', new_token)
453
453
  }
454
454
 
455
- await next()
455
+ await next(c)
456
456
  }
457
457
  }
458
458
 
459
459
  }
460
460
 
461
461
  module.exports = TopbitToken
462
-
package/src/topbit.js CHANGED
@@ -31,6 +31,9 @@ const Context2 = require('./context2.js');
31
31
  const ext = require('./ext.js');
32
32
  const TopbitLoader = require('./loader/loader.js')
33
33
  const TopbitToken = require('./token/token.js')
34
+ const TopbitExtends = require('./_loadExtends.js')
35
+ const npargv = require('./lib/npargv.js')
36
+ const zipdata = require('./lib/zipdata.js')
34
37
 
35
38
  let __instance__ = 0;
36
39
 
@@ -47,7 +50,7 @@ let _topbit_home_page = `<!DOCTYPE html><html>
47
50
  <br>
48
51
  <p>功能强大、简洁高效的Web开发框架。</p>
49
52
  <p>文档 & 仓库:
50
- <a style="text-decoration:none;color:#345689;" href="https://gitee.com/daoio/topbit" target=_blank>
53
+ <a style="text-decoration:none;color:#345689;" href="https://github.com/master-genius/topbit" target=_blank>
51
54
  topbit</a></p>
52
55
  </div>
53
56
  </div>
@@ -213,7 +216,7 @@ class Topbit {
213
216
  notFound : 'not found',
214
217
  badRequest : 'bad request',
215
218
  //展示负载信息,必须使用daemon接口
216
- showLoadInfo : true,
219
+ loadMonitor : true,
217
220
  loadInfoType : 'text', // text | json | orgjson | --null
218
221
  loadInfoFile : '',
219
222
 
@@ -234,7 +237,7 @@ class Topbit {
234
237
 
235
238
  maxUrlLength: 1152,
236
239
 
237
- maxpool : 4096,
240
+ maxpool : 8192,
238
241
 
239
242
  //子进程汇报资源信息的定时器毫秒数。
240
243
  monitorTimeSlice: 500,
@@ -266,7 +269,7 @@ class Topbit {
266
269
  //-1表示使用timeout的设置。
267
270
  streamTimeout: -1,
268
271
 
269
- requestTimeout: 100000,
272
+ requestTimeout: 65_000,
270
273
 
271
274
  maxLoadRate: 75
272
275
  };
@@ -279,7 +282,7 @@ class Topbit {
279
282
  deny_type : 's',
280
283
  //每秒单个IP可以进行请求次数的上限,0表示不限制。
281
284
  maxIPRequest : 0,
282
- unitTime : 60_000,
285
+ unitTime : 30_000,
283
286
  maxIPCache : 10_0000,
284
287
  allow : null,
285
288
  allow_type : 's',
@@ -370,10 +373,6 @@ class Topbit {
370
373
  break;
371
374
 
372
375
  case 'loadMonitor':
373
- this.config.showLoadInfo = !!options[k];
374
- break;
375
-
376
- case 'showLoadInfo':
377
376
  case 'daemon':
378
377
  case 'debug':
379
378
  case 'globalLog':
@@ -580,7 +579,7 @@ class Topbit {
580
579
  }
581
580
  }
582
581
 
583
- if (this.config.showLoadInfo) {
582
+ if (this.config.loadMonitor) {
584
583
  this.monitor = new Monitor({
585
584
  config : this.config,
586
585
  secure : this.secure,
@@ -1262,7 +1261,7 @@ class Topbit {
1262
1261
 
1263
1262
  } else if (cluster.isWorker) {
1264
1263
 
1265
- if (this.config.showLoadInfo) {
1264
+ if (this.config.loadMonitor) {
1266
1265
  this.monitor.workerSend();
1267
1266
  }
1268
1267
 
@@ -1287,5 +1286,8 @@ class Topbit {
1287
1286
 
1288
1287
  Topbit.Loader = TopbitLoader;
1289
1288
  Topbit.Token = TopbitToken;
1289
+ Topbit.npargv = npargv;
1290
+ Topbit.zipdata = zipdata;
1291
+ Topbit.extensions = TopbitExtends;
1290
1292
 
1291
1293
  module.exports = Topbit;
@@ -1,6 +1,6 @@
1
1
  'use strict'
2
2
 
3
- const helper = require('../lib/helper.js')
3
+ const helper = require('../src/ext.js')
4
4
 
5
5
  let key = '123456789012345678900987654321qw'
6
6
 
@@ -1,4 +1,4 @@
1
- const titbit = require('../lib/titbit.js');
1
+ const titbit = require('../src/topbit.js');
2
2
 
3
3
  var app = new titbit();
4
4