k99 0.2.0 → 0.3.0-beta.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 (154) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +8 -0
  3. package/README.zh.md +8 -0
  4. package/browser/package.json +8 -0
  5. package/browser/types.d.ts +20 -0
  6. package/cli/command/create.js +1 -2
  7. package/cli/command/index.js +1 -2
  8. package/cli/command/init.js +3 -5
  9. package/cli/command/start.js +9 -10
  10. package/cli/index.js +3 -4
  11. package/cli/opt/bind.js +1 -2
  12. package/cli/opt/index.js +1 -2
  13. package/cli/opt/listen.js +1 -2
  14. package/cli/opt/path.js +1 -2
  15. package/cli/opt/port.js +1 -2
  16. package/cli/opt/show-router.js +1 -2
  17. package/dist/k99.browser.js +3110 -0
  18. package/dist/k99.browser.min.js +6 -0
  19. package/dist/k99.esm.js +3082 -0
  20. package/dist/k99.esm.min.js +6 -0
  21. package/dist/k99.js +3104 -0
  22. package/dist/k99.mjs +3082 -0
  23. package/dist/k99Browser.browser.js +490 -0
  24. package/dist/k99Browser.browser.min.js +6 -0
  25. package/dist/k99Browser.esm.js +475 -0
  26. package/dist/k99Browser.esm.min.js +6 -0
  27. package/dist/k99Browser.js +484 -0
  28. package/dist/k99Browser.mjs +475 -0
  29. package/dist/k99Services.browser.js +145 -0
  30. package/dist/k99Services.browser.min.js +6 -0
  31. package/dist/k99Services.esm.js +136 -0
  32. package/dist/k99Services.esm.min.js +6 -0
  33. package/dist/k99Services.js +141 -0
  34. package/dist/k99Services.mjs +136 -0
  35. package/node/index.js +1386 -0
  36. package/node/index.mjs +1350 -0
  37. package/node/package.json +5 -0
  38. package/node/types.d.ts +166 -0
  39. package/package.json +77 -11
  40. package/services/package.json +8 -0
  41. package/services/types.d.ts +22 -0
  42. package/starter.js +0 -1
  43. package/types.d.ts +748 -0
  44. package/Container.d.ts +0 -92
  45. package/Container.js +0 -242
  46. package/Container.js.map +0 -1
  47. package/Controller/index.d.ts +0 -178
  48. package/Controller/index.js +0 -576
  49. package/Controller/index.js.map +0 -1
  50. package/Controller/patch/cookie.d.ts +0 -33
  51. package/Controller/patch/cookie.js +0 -168
  52. package/Controller/patch/cookie.js.map +0 -1
  53. package/Controller/patch/index.d.ts +0 -7
  54. package/Controller/patch/index.js +0 -26
  55. package/Controller/patch/index.js.map +0 -1
  56. package/Controller/patch/render.d.ts +0 -5
  57. package/Controller/patch/render.js +0 -24
  58. package/Controller/patch/render.js.map +0 -1
  59. package/ExitSignal.d.ts +0 -14
  60. package/ExitSignal.js +0 -29
  61. package/ExitSignal.js.map +0 -1
  62. package/Extension.d.ts +0 -56
  63. package/Extension.js +0 -93
  64. package/Extension.js.map +0 -1
  65. package/ExtensionContainer.d.ts +0 -55
  66. package/ExtensionContainer.js +0 -105
  67. package/ExtensionContainer.js.map +0 -1
  68. package/Plugin.d.ts +0 -52
  69. package/Plugin.js +0 -278
  70. package/Plugin.js.map +0 -1
  71. package/Preprocessor.d.ts +0 -86
  72. package/Preprocessor.js +0 -135
  73. package/Preprocessor.js.map +0 -1
  74. package/Router/assets.d.ts +0 -33
  75. package/Router/assets.js +0 -106
  76. package/Router/assets.js.map +0 -1
  77. package/Router/callback.d.ts +0 -9
  78. package/Router/callback.js +0 -152
  79. package/Router/callback.js.map +0 -1
  80. package/Router/extendsInterface.d.ts +0 -8
  81. package/Router/extendsInterface.js +0 -43
  82. package/Router/extendsInterface.js.map +0 -1
  83. package/Router/index.d.ts +0 -184
  84. package/Router/index.js +0 -615
  85. package/Router/index.js.map +0 -1
  86. package/Router/log.d.ts +0 -23
  87. package/Router/log.js +0 -120
  88. package/Router/log.js.map +0 -1
  89. package/Router/order.d.ts +0 -14
  90. package/Router/order.js +0 -71
  91. package/Router/order.js.map +0 -1
  92. package/Router/register.d.ts +0 -9
  93. package/Router/register.js +0 -252
  94. package/Router/register.js.map +0 -1
  95. package/Router/registerManager.d.ts +0 -22
  96. package/Router/registerManager.js +0 -102
  97. package/Router/registerManager.js.map +0 -1
  98. package/Router/scan.d.ts +0 -2
  99. package/Router/scan.js +0 -72
  100. package/Router/scan.js.map +0 -1
  101. package/Router/setHandleItem.d.ts +0 -3
  102. package/Router/setHandleItem.js +0 -94
  103. package/Router/setHandleItem.js.map +0 -1
  104. package/Router/settings.d.ts +0 -12
  105. package/Router/settings.js +0 -74
  106. package/Router/settings.js.map +0 -1
  107. package/Router/start.d.ts +0 -3
  108. package/Router/start.js +0 -270
  109. package/Router/start.js.map +0 -1
  110. package/Router/vars.d.ts +0 -10
  111. package/Router/vars.js +0 -40
  112. package/Router/vars.js.map +0 -1
  113. package/Service.d.ts +0 -12
  114. package/Service.js +0 -20
  115. package/Service.js.map +0 -1
  116. package/cli/command/create.d.ts +0 -7
  117. package/cli/command/create.js.map +0 -1
  118. package/cli/command/index.d.ts +0 -7
  119. package/cli/command/index.js.map +0 -1
  120. package/cli/command/init.d.ts +0 -6
  121. package/cli/command/init.js.map +0 -1
  122. package/cli/command/start.d.ts +0 -6
  123. package/cli/command/start.js.map +0 -1
  124. package/cli/index.d.ts +0 -2
  125. package/cli/index.js.map +0 -1
  126. package/cli/opt/bind.d.ts +0 -3
  127. package/cli/opt/bind.js.map +0 -1
  128. package/cli/opt/index.d.ts +0 -16
  129. package/cli/opt/index.js.map +0 -1
  130. package/cli/opt/listen.d.ts +0 -3
  131. package/cli/opt/listen.js.map +0 -1
  132. package/cli/opt/path.d.ts +0 -3
  133. package/cli/opt/path.js.map +0 -1
  134. package/cli/opt/port.d.ts +0 -3
  135. package/cli/opt/port.js.map +0 -1
  136. package/cli/opt/show-router.d.ts +0 -3
  137. package/cli/opt/show-router.js.map +0 -1
  138. package/index.d.ts +0 -354
  139. package/index.js +0 -155
  140. package/index.js.map +0 -1
  141. package/setOptions.d.ts +0 -12
  142. package/setOptions.js +0 -60
  143. package/setOptions.js.map +0 -1
  144. package/starter.d.ts +0 -2
  145. package/starter.js.map +0 -1
  146. package/symbols.d.ts +0 -13
  147. package/symbols.js +0 -31
  148. package/symbols.js.map +0 -1
  149. package/util/index.d.ts +0 -5
  150. package/util/index.js +0 -92
  151. package/util/index.js.map +0 -1
  152. package/util/stream.d.ts +0 -19
  153. package/util/stream.js +0 -66
  154. package/util/stream.js.map +0 -1
package/node/index.mjs ADDED
@@ -0,0 +1,1350 @@
1
+ /*!
2
+ * k99 v0.3.0-beta.1
3
+ * (c) 2019-2022 Fierflame
4
+ * @license MIT
5
+ */
6
+ import * as fsFn from 'fs';
7
+ import * as pathFn from 'path';
8
+ import { Controller, Guard, Router, Plugin, App } from 'k99';
9
+ import { Http2ServerResponse } from 'http2';
10
+ import * as urlFn from 'url';
11
+
12
+ function _defineProperty(obj, key, value) {
13
+ if (key in obj) {
14
+ Object.defineProperty(obj, key, {
15
+ value: value,
16
+ enumerable: true,
17
+ configurable: true,
18
+ writable: true
19
+ });
20
+ } else {
21
+ obj[key] = value;
22
+ }
23
+
24
+ return obj;
25
+ }
26
+
27
+ const registers = Object.create(null);
28
+ function setRegister({
29
+ extname,
30
+ type,
31
+ register
32
+ }, list = registers) {
33
+ const key = `${type || ''}.${extname}`;
34
+
35
+ if (!/^(?:[a-z]+)?\.[a-z]+$/.test(key)) {
36
+ return false;
37
+ }
38
+
39
+ if (key in list) {
40
+ return false;
41
+ }
42
+
43
+ if (typeof register !== 'function') {
44
+ return false;
45
+ }
46
+
47
+ list[key] = {
48
+ extname,
49
+ type,
50
+ register
51
+ };
52
+ return true;
53
+ }
54
+ /** 注册文件 */
55
+
56
+ async function register(file, router, list) {
57
+ const {
58
+ extname,
59
+ type
60
+ } = file;
61
+ const key = `${type || ''}.${extname}`;
62
+ const register = (list === null || list === void 0 ? void 0 : list[key]) || registers[key];
63
+
64
+ if (!register) {
65
+ return false;
66
+ }
67
+
68
+ return register.register({ ...file
69
+ }, router);
70
+ }
71
+ setRegister({
72
+ extname: 'js',
73
+
74
+ async register({
75
+ root,
76
+ path,
77
+ plugin
78
+ }, router) {
79
+ const item = require(pathFn.join(root, path));
80
+
81
+ if (!item) {
82
+ return false;
83
+ }
84
+
85
+ router.register(item, {
86
+ root,
87
+ filePath: path,
88
+ plugin
89
+ });
90
+ return true;
91
+ }
92
+
93
+ });
94
+ setRegister({
95
+ extname: 'js',
96
+ type: 'resource',
97
+
98
+ async register({
99
+ root,
100
+ path,
101
+ plugin
102
+ }, router) {
103
+ const item = require(pathFn.join(root, path));
104
+
105
+ if (!item) {
106
+ return false;
107
+ }
108
+
109
+ router.resource(item, {
110
+ root,
111
+ filePath: path,
112
+ plugin
113
+ });
114
+ return true;
115
+ }
116
+
117
+ });
118
+ setRegister({
119
+ extname: 'js',
120
+ type: 'collection',
121
+
122
+ async register({
123
+ root,
124
+ path,
125
+ plugin
126
+ }, router) {
127
+ const item = require(pathFn.join(root, path));
128
+
129
+ if (!item) {
130
+ return false;
131
+ }
132
+
133
+ router.collection(item, {
134
+ root,
135
+ filePath: path,
136
+ plugin
137
+ });
138
+ return true;
139
+ }
140
+
141
+ });
142
+ setRegister({
143
+ extname: 'js',
144
+ type: 'members',
145
+
146
+ async register({
147
+ root,
148
+ path,
149
+ plugin
150
+ }, router) {
151
+ const item = require(pathFn.join(root, path));
152
+
153
+ if (!item) {
154
+ return false;
155
+ }
156
+
157
+ router.member(item, {
158
+ root,
159
+ filePath: path,
160
+ plugin
161
+ });
162
+ return true;
163
+ }
164
+
165
+ });
166
+ setRegister({
167
+ extname: 'js',
168
+ type: 'static',
169
+
170
+ async register({
171
+ root,
172
+ path,
173
+ plugin
174
+ }, router) {
175
+ const item = require(pathFn.join(root, path));
176
+
177
+ if (!item) {
178
+ return false;
179
+ }
180
+
181
+ router.collection(item, {
182
+ root,
183
+ filePath: path,
184
+ plugin
185
+ });
186
+ return true;
187
+ }
188
+
189
+ });
190
+ setRegister({
191
+ extname: 'js',
192
+ type: 'controller',
193
+
194
+ async register({
195
+ root,
196
+ path
197
+ }, router) {
198
+ const item = require(pathFn.join(root, path));
199
+
200
+ if (!item) {
201
+ return false;
202
+ }
203
+
204
+ if (typeof item.default !== 'function') {
205
+ return false;
206
+ }
207
+
208
+ if (!Controller.isPrototypeOf(item.default)) {
209
+ return false;
210
+ }
211
+
212
+ router.controller = item.default;
213
+ return true;
214
+ }
215
+
216
+ });
217
+ setRegister({
218
+ extname: 'js',
219
+ type: 'guard',
220
+
221
+ async register({
222
+ root,
223
+ path
224
+ }, router) {
225
+ const item = require(pathFn.join(root, path));
226
+
227
+ if (!item) {
228
+ return false;
229
+ }
230
+
231
+ if (typeof item.default !== 'function') {
232
+ return false;
233
+ }
234
+
235
+ if (!Guard.isPrototypeOf(item.default)) {
236
+ return false;
237
+ }
238
+
239
+ router.guards.add(item.default);
240
+ return true;
241
+ }
242
+
243
+ });
244
+ setRegister({
245
+ extname: 'js',
246
+ type: 'router',
247
+
248
+ async register({
249
+ root,
250
+ path
251
+ }, router) {
252
+ const item = require(pathFn.join(root, path));
253
+
254
+ if (!item) {
255
+ return false;
256
+ }
257
+
258
+ if (typeof item.default !== 'function') {
259
+ return false;
260
+ }
261
+
262
+ if (!Router.isPrototypeOf(item.default)) {
263
+ return false;
264
+ }
265
+
266
+ router.route(item.default);
267
+ return true;
268
+ }
269
+
270
+ });
271
+ setRegister({
272
+ extname: 'mjs',
273
+
274
+ async register({
275
+ root,
276
+ path,
277
+ plugin
278
+ }, router) {
279
+ const item = await import(pathFn.join(root, path));
280
+
281
+ if (!item) {
282
+ return false;
283
+ }
284
+
285
+ router.register(item, {
286
+ root,
287
+ filePath: path,
288
+ plugin
289
+ });
290
+ return true;
291
+ }
292
+
293
+ });
294
+ setRegister({
295
+ extname: 'mjs',
296
+ type: 'resource',
297
+
298
+ async register({
299
+ root,
300
+ path,
301
+ plugin
302
+ }, router) {
303
+ const item = await import(pathFn.join(root, path));
304
+
305
+ if (!item) {
306
+ return false;
307
+ }
308
+
309
+ router.resource(item, {
310
+ root,
311
+ filePath: path,
312
+ plugin
313
+ });
314
+ return true;
315
+ }
316
+
317
+ });
318
+ setRegister({
319
+ extname: 'mjs',
320
+ type: 'collection',
321
+
322
+ async register({
323
+ root,
324
+ path,
325
+ plugin
326
+ }, router) {
327
+ const item = await import(pathFn.join(root, path));
328
+
329
+ if (!item) {
330
+ return false;
331
+ }
332
+
333
+ router.collection(item, {
334
+ root,
335
+ filePath: path,
336
+ plugin
337
+ });
338
+ return true;
339
+ }
340
+
341
+ });
342
+ setRegister({
343
+ extname: 'mjs',
344
+ type: 'members',
345
+
346
+ async register({
347
+ root,
348
+ path,
349
+ plugin
350
+ }, router) {
351
+ const item = await import(pathFn.join(root, path));
352
+
353
+ if (!item) {
354
+ return false;
355
+ }
356
+
357
+ router.member(item, {
358
+ root,
359
+ filePath: path,
360
+ plugin
361
+ });
362
+ return true;
363
+ }
364
+
365
+ });
366
+ setRegister({
367
+ extname: 'mjs',
368
+ type: 'static',
369
+
370
+ async register({
371
+ root,
372
+ path,
373
+ plugin
374
+ }, router) {
375
+ const item = await import(pathFn.join(root, path));
376
+
377
+ if (!item) {
378
+ return false;
379
+ }
380
+
381
+ router.collection(item, {
382
+ root,
383
+ filePath: path,
384
+ plugin
385
+ });
386
+ return true;
387
+ }
388
+
389
+ });
390
+ setRegister({
391
+ extname: 'mjs',
392
+ type: 'controller',
393
+
394
+ async register({
395
+ root,
396
+ path
397
+ }, router) {
398
+ const item = await import(pathFn.join(root, path));
399
+
400
+ if (!item) {
401
+ return false;
402
+ }
403
+
404
+ if (typeof item.default !== 'function') {
405
+ return false;
406
+ }
407
+
408
+ if (!Controller.isPrototypeOf(item.default)) {
409
+ return false;
410
+ }
411
+
412
+ router.controller = item.default;
413
+ return true;
414
+ }
415
+
416
+ });
417
+ setRegister({
418
+ extname: 'mjs',
419
+ type: 'guard',
420
+
421
+ async register({
422
+ root,
423
+ path
424
+ }, router) {
425
+ const item = await import(pathFn.join(root, path));
426
+
427
+ if (!item) {
428
+ return false;
429
+ }
430
+
431
+ if (typeof item.default !== 'function') {
432
+ return false;
433
+ }
434
+
435
+ if (!Guard.isPrototypeOf(item.default)) {
436
+ return false;
437
+ }
438
+
439
+ router.guards.add(item.default);
440
+ return true;
441
+ }
442
+
443
+ });
444
+ setRegister({
445
+ extname: 'mjs',
446
+ type: 'router',
447
+
448
+ async register({
449
+ root,
450
+ path
451
+ }, router) {
452
+ const item = await import(pathFn.join(root, path));
453
+
454
+ if (!item) {
455
+ return false;
456
+ }
457
+
458
+ if (typeof item.default !== 'function') {
459
+ return false;
460
+ }
461
+
462
+ if (!Router.isPrototypeOf(item.default)) {
463
+ return false;
464
+ }
465
+
466
+ router.route(item.default);
467
+ return true;
468
+ }
469
+
470
+ });
471
+
472
+ const dirRegex = /^((?:\d+\.)?)([:$]?)([a-zA-Z0-9_-]+)(\${0,3}|[?*+])$/;
473
+ const fileRegex = /^((?:\d+\.)?)([:$]?)([a-zA-Z0-9_-]+)(\${0,3}|[?*+])((?:\.[a-z]+)?)(\.[a-z]+)$/;
474
+ function getPathSortInfo(filename) {
475
+ const dir = dirRegex.exec(filename);
476
+
477
+ if (dir) {
478
+ const no = Number.parseInt(dir[1]);
479
+ const tuple = Boolean(dir[2]);
480
+ const extend = dir[4].replace(/\${3}$/, '+').replace(/\${2}$/, '*').replace(/\${1}$/, '?');
481
+ const name = [tuple && ':', dir[3], extend].filter(Boolean).join('');
482
+ return {
483
+ dir: true,
484
+ filename,
485
+ no,
486
+ tuple,
487
+ name,
488
+ extend
489
+ };
490
+ }
491
+
492
+ const file = fileRegex.exec(filename);
493
+
494
+ if (!file) {
495
+ return null;
496
+ }
497
+
498
+ const no = Number.parseInt(file[1]);
499
+ const tuple = Boolean(file[2]);
500
+ const extend = file[4].replace(/\${3}$/, '+').replace(/\${2}$/, '*').replace(/\${1}$/, '?');
501
+ const name = !file[1] && !tuple && !extend && file[3] === 'index' ? '' : [tuple && ':', file[3], extend].filter(Boolean).join('');
502
+ const type = file[5].substr(1);
503
+ const extname = file[6].substr(1);
504
+ return {
505
+ filename,
506
+ no,
507
+ tuple,
508
+ name,
509
+ extend,
510
+ type,
511
+ extname
512
+ };
513
+ }
514
+
515
+ function sortValid(a, b) {
516
+ if (a.name && !b.name) {
517
+ return 1;
518
+ }
519
+
520
+ if (!a.name && b.name) {
521
+ return -1;
522
+ }
523
+
524
+ if (!a.name && !b.name) {
525
+ return 0;
526
+ }
527
+
528
+ if (Number.isFinite(a.no) && Number.isFinite(b.no) && a.no !== b.no) {
529
+ return a.no - b.no;
530
+ }
531
+
532
+ if (Number.isFinite(a.no) && !Number.isFinite(b.no)) {
533
+ return -1;
534
+ }
535
+
536
+ if (!Number.isFinite(a.no) && Number.isFinite(b.no)) {
537
+ return 1;
538
+ }
539
+
540
+ if (a.tuple && !b.tuple) {
541
+ return 1;
542
+ }
543
+
544
+ if (!a.tuple && b.tuple) {
545
+ return -1;
546
+ }
547
+
548
+ if (a.dir && !b.dir) {
549
+ return 1;
550
+ }
551
+
552
+ if (!a.dir && b.dir) {
553
+ return -1;
554
+ }
555
+
556
+ if (a.extend === b.extend) {
557
+ let aName = a.name.toLowerCase();
558
+ let bName = b.name.toLowerCase();
559
+ return aName > bName ? 1 : aName < bName ? -1 : a.name < b.name ? 1 : a.name > b.name ? -1 : 0;
560
+ }
561
+
562
+ if (a.extend && !b.extend) {
563
+ return 1;
564
+ }
565
+
566
+ if (!a.extend && b.extend) {
567
+ return -1;
568
+ }
569
+
570
+ if (a.extend === '*') {
571
+ return 1;
572
+ }
573
+
574
+ if (b.extend === '*') {
575
+ return -1;
576
+ }
577
+
578
+ if (a.extend === '+') {
579
+ return 1;
580
+ }
581
+
582
+ if (b.extend === '+') {
583
+ return -1;
584
+ }
585
+
586
+ if (a.extend === '?') {
587
+ return 1;
588
+ }
589
+
590
+ return -1;
591
+ }
592
+
593
+ function isValidInfo(t) {
594
+ return Boolean(t);
595
+ }
596
+
597
+ async function readdir$1(path) {
598
+ return new Promise(resolve => fsFn.readdir(path, {
599
+ encoding: 'utf-8'
600
+ }, (err, files) => err ? resolve([]) : resolve(files))).then(paths => paths.map(getPathSortInfo).filter(isValidInfo).sort(sortValid));
601
+ }
602
+
603
+ async function stat(path) {
604
+ return new Promise(resolve => fsFn.stat(path, (err, stat) => err ? resolve() : resolve(stat)));
605
+ }
606
+
607
+ async function isFile$1(path) {
608
+ const s = await stat(path);
609
+ return s && s.isFile();
610
+ }
611
+
612
+ async function isDir(path) {
613
+ const s = await stat(path);
614
+ return s && s.isDirectory();
615
+ }
616
+
617
+ async function scan(root, router, plugin, list, path = '', scope = []) {
618
+ const routers = Object.create(null);
619
+
620
+ function getRouter(name) {
621
+ if (!name) {
622
+ return router;
623
+ }
624
+
625
+ let child = routers[name];
626
+
627
+ if (!child) {
628
+ child = router.route(name);
629
+ routers[name] = child;
630
+ }
631
+
632
+ return child;
633
+ }
634
+
635
+ for (let item of await readdir$1(pathFn.resolve(root, path))) {
636
+ const {
637
+ filename,
638
+ name
639
+ } = item;
640
+ const newPath = pathFn.join(path, filename);
641
+
642
+ if (item.dir) {
643
+ if (isDir(pathFn.resolve(root, newPath))) {
644
+ await scan(root, getRouter(name), plugin, list, newPath, [...scope, name]);
645
+ }
646
+ } else if (isFile$1(pathFn.resolve(root, newPath))) {
647
+ const {
648
+ extname,
649
+ type
650
+ } = item;
651
+ await register({
652
+ extname,
653
+ type,
654
+ root,
655
+ path: newPath,
656
+ plugin,
657
+ scope: name ? [...scope, name] : scope
658
+ }, getRouter(name), list);
659
+ }
660
+ }
661
+ }
662
+
663
+ class Scanner {
664
+ constructor() {
665
+ _defineProperty(this, "__registers", Object.create(null));
666
+ }
667
+
668
+ /**
669
+ * 设置公共的文件注册器
670
+ * @param register 注册配置
671
+ */
672
+ static setRegister(register) {
673
+ return setRegister(register);
674
+ }
675
+ /**
676
+ * 扫描指定路径,并将扫描到的文件进行注册
677
+ * @param root 要扫描的路径
678
+ * @param router 被注册的路由
679
+ */
680
+
681
+
682
+ static scan(root, router, plugin) {
683
+ return scan(root, router, plugin);
684
+ }
685
+ /** 注册器列表 */
686
+
687
+
688
+ /**
689
+ * 扫描指定路径,并将扫描到的文件进行注册
690
+ * @param root 要扫描的路径
691
+ * @param router 被注册的路由
692
+ */
693
+ scan(root, router, plugin) {
694
+ return scan(root, router, plugin, this.__registers);
695
+ }
696
+ /** 为当前路由设置注册器 */
697
+
698
+
699
+ setRegister(register) {
700
+ return setRegister(register, this.__registers);
701
+ }
702
+
703
+ }
704
+
705
+ async function getRouters(router, routers) {
706
+ const r = await getRouter(router);
707
+
708
+ if (!Array.isArray(routers)) {
709
+ return r ? [r] : undefined;
710
+ }
711
+
712
+ const list = r ? [r] : [];
713
+
714
+ for (const router of routers) {
715
+ const r = await getRouter(router);
716
+
717
+ if (r) {
718
+ list.push(r);
719
+ }
720
+ }
721
+
722
+ if (list.length) {
723
+ return list;
724
+ }
725
+ }
726
+
727
+ async function getRouter(router) {
728
+ if (typeof router === 'function') {
729
+ router = await router();
730
+ }
731
+
732
+ if (router instanceof Router) {
733
+ return router;
734
+ }
735
+ }
736
+
737
+ class FsPlugin extends Plugin {
738
+ /** 路径 */
739
+ async readSettings(path) {
740
+ const p = pathFn.resolve(this.settingsPath, `${path}.json`);
741
+
742
+ try {
743
+ return JSON.parse((await new Promise((resolve, reject) => fsFn.readFile(p, 'utf-8', (e, d) => e ? reject(e) : resolve(d)))));
744
+ } catch {}
745
+ }
746
+
747
+ readAsset(path, encoding) {
748
+ return new Promise(resolve => fsFn.readFile(pathFn.resolve(this.assetsPath, path), encoding ? 'utf-8' : null, (e, d) => e ? resolve(null) : resolve(typeof d === 'string' ? d : d.buffer)));
749
+ }
750
+
751
+ constructor(config, name) {
752
+ const {
753
+ path,
754
+ version,
755
+ author,
756
+ license,
757
+ assetsPath,
758
+ settingsPath,
759
+ logsPath
760
+ } = config;
761
+ super(name, version || '', {
762
+ author,
763
+ license
764
+ });
765
+ this._config = config;
766
+ this.assetsPath = pathFn.resolve(path, assetsPath || 'assets');
767
+ this.settingsPath = pathFn.resolve(path, settingsPath || 'settings');
768
+ this.logsPath = pathFn.resolve(path, logsPath || 'logs');
769
+ this.path = path;
770
+ }
771
+
772
+ async _initRouter(pluginRouter) {
773
+ const {
774
+ _config
775
+ } = this;
776
+ const list = await getRouters(_config.router, _config.routers);
777
+
778
+ for (const router of list || []) {
779
+ pluginRouter.route(router);
780
+ }
781
+
782
+ const {
783
+ appPath
784
+ } = _config;
785
+
786
+ if (list && !appPath) {
787
+ return;
788
+ }
789
+
790
+ const {
791
+ path
792
+ } = _config;
793
+ await Scanner.scan(pathFn.resolve(path, appPath || 'app'), pluginRouter);
794
+ }
795
+
796
+ }
797
+
798
+ function createFsLogApi(logsPath) {
799
+ const basePath = pathFn.resolve(logsPath, '.');
800
+ return {
801
+ async read(path) {
802
+ path = `${basePath}/${path}.log`;
803
+ return new Promise(resolve => fsFn.readFile(path, 'utf-8', (e, d) => resolve(e ? '' : d)));
804
+ },
805
+
806
+ async write(path, log) {
807
+ path = `${basePath}/${path}.log`;
808
+ await new Promise(r => fsFn.mkdir(pathFn.dirname(path), {
809
+ recursive: true
810
+ }, () => r()));
811
+ return new Promise(resolve => fsFn.appendFile(path, log, e => resolve(!e)));
812
+ },
813
+
814
+ async clear(path) {
815
+ path = `${basePath}/${path}.log`;
816
+ return new Promise(resolve => fsFn.writeFile(path, '', () => resolve()));
817
+ }
818
+
819
+ };
820
+ }
821
+
822
+ function createFsSettingsApi(settingsPath) {
823
+ const basePath = pathFn.resolve(settingsPath, '.');
824
+ return {
825
+ async read(path) {
826
+ const p = `${basePath}/${path}.json`;
827
+ const text = await new Promise(r => fsFn.readFile(p, 'utf8', (e, d) => e ? r('') : r(d)));
828
+
829
+ if (!text) {
830
+ return undefined;
831
+ }
832
+
833
+ try {
834
+ return JSON.parse(text);
835
+ } catch {}
836
+ },
837
+
838
+ async write(path, cfg) {
839
+ const p = `${basePath}/${path}.json`;
840
+
841
+ if (cfg === undefined) {
842
+ return new Promise(r => fsFn.unlink(p, e => r(!e)));
843
+ }
844
+
845
+ await new Promise(r => fsFn.mkdir(pathFn.dirname(p), {
846
+ recursive: true
847
+ }, r));
848
+ const text = JSON.stringify(cfg);
849
+ return new Promise(r => fsFn.writeFile(p, text, e => r(!e)));
850
+ }
851
+
852
+ };
853
+ }
854
+
855
+ function getStat(s) {
856
+ return {
857
+ get isDirectory() {
858
+ return s.isDirectory();
859
+ },
860
+
861
+ size: s.size,
862
+ updateTime: s.mtime,
863
+ createTime: s.birthtime
864
+ };
865
+ }
866
+
867
+ function createFsAssetsApi(assetsPath) {
868
+ const basePath = pathFn.resolve(assetsPath, '.');
869
+
870
+ function read(path, encoding) {
871
+ const p = `${basePath}/${path}`;
872
+ const options = encoding ? 'utf8' : null;
873
+ return new Promise(r => fsFn.readFile(p, options, (e, d) => e ? r(null) : r(typeof d === 'string' ? d : d.buffer)));
874
+ }
875
+
876
+ return {
877
+ read,
878
+
879
+ async write(path, data) {
880
+ const p = `${basePath}/${path}`;
881
+ await new Promise(r => fsFn.mkdir(pathFn.dirname(p), {
882
+ recursive: true
883
+ }, r));
884
+ return new Promise(r => fsFn.writeFile(p, data, e => r(!e)));
885
+ },
886
+
887
+ delete(path) {
888
+ const p = `${basePath}/${path}`;
889
+ return new Promise(resolve => fsFn.unlink(p, e => resolve(!e)));
890
+ },
891
+
892
+ stat(path) {
893
+ const p = `${basePath}/${path}`;
894
+ return new Promise(r => fsFn.stat(p, (e, s) => e ? r(null) : r(getStat(s))));
895
+ }
896
+
897
+ };
898
+ }
899
+
900
+ class NodeApp extends App {
901
+ constructor({
902
+ path,
903
+ settingsPath,
904
+ assetsPath,
905
+ logsPath,
906
+ router
907
+ } = {}, plugins) {
908
+ const cwd = pathFn.resolve(path || process.cwd());
909
+ const newSettingsPath = pathFn.resolve(cwd, settingsPath || 'settings');
910
+ const newAssetsPath = pathFn.resolve(cwd, assetsPath || 'assets');
911
+ const newLogsPath = pathFn.resolve(cwd, logsPath || 'logs');
912
+ super({
913
+ path: cwd,
914
+ settingApi: createFsSettingsApi(newSettingsPath),
915
+ assetApi: createFsAssetsApi(newAssetsPath),
916
+ logApi: createFsLogApi(newLogsPath),
917
+ router
918
+ }, plugins);
919
+ this.cwd = cwd;
920
+ this.settingsPath = newSettingsPath;
921
+ this.assetsPath = newAssetsPath;
922
+ this.logsPath = newLogsPath;
923
+ }
924
+
925
+ }
926
+
927
+ function createRead(req) {
928
+ let currentEncoding = false;
929
+ let current = 0;
930
+ let cb = null;
931
+ let end = false;
932
+ const dataList = [];
933
+ let dataSize = 0;
934
+ const list = [];
935
+ let running = false;
936
+
937
+ function get(size) {
938
+ const chunk = Buffer.concat(dataList, dataSize);
939
+
940
+ if (size && dataSize > size) {
941
+ dataList.length = 0;
942
+ dataList.push(chunk.slice(size));
943
+ dataSize -= size;
944
+ return chunk.slice(0, size);
945
+ }
946
+
947
+ dataSize = 0;
948
+ dataList.length = 0;
949
+ return chunk;
950
+ }
951
+
952
+ function add(data) {
953
+ const buffer = typeof data === 'string' ? Buffer.from(data) : data;
954
+ dataSize += buffer.length || 0;
955
+ dataList.push(buffer);
956
+ return dataSize;
957
+ }
958
+
959
+ function nextData() {
960
+ return current ? req.read(current) : req.read();
961
+ }
962
+
963
+ function runCb(v) {
964
+ if (!cb) {
965
+ return;
966
+ }
967
+
968
+ cb(v);
969
+ [current, currentEncoding, cb] = list.shift() || [0, false, null];
970
+ }
971
+
972
+ function runMain() {
973
+ for (;;) {
974
+ if (!cb) {
975
+ return;
976
+ }
977
+
978
+ if (end) {
979
+ runCb(dataSize ? get(current) : null);
980
+ continue;
981
+ }
982
+
983
+ if (!current && dataSize) {
984
+ runCb(get(current));
985
+ continue;
986
+ }
987
+
988
+ const data = nextData();
989
+
990
+ if (data === null) {
991
+ return;
992
+ }
993
+
994
+ if (current) {
995
+ if (add(data) < current) {
996
+ continue;
997
+ }
998
+
999
+ runCb(get(current));
1000
+ continue;
1001
+ }
1002
+
1003
+ if (currentEncoding) {
1004
+ runCb(typeof data === 'string' ? data : String(data));
1005
+ } else {
1006
+ runCb(typeof data === 'string' ? Buffer.from(data) : data);
1007
+ }
1008
+ }
1009
+ }
1010
+
1011
+ let setEnd = false;
1012
+
1013
+ function run() {
1014
+ running = true;
1015
+ runMain();
1016
+
1017
+ if (setEnd) {
1018
+ end = true;
1019
+ runMain();
1020
+ }
1021
+
1022
+ running = false;
1023
+ }
1024
+
1025
+ req.addListener('end', () => {
1026
+ if (end || setEnd) {
1027
+ return;
1028
+ }
1029
+
1030
+ if (running) {
1031
+ setEnd = true;
1032
+ } else {
1033
+ end = true;
1034
+ run();
1035
+ }
1036
+ });
1037
+
1038
+ function read(size = 0, encoding = false) {
1039
+ return new Promise(resolve => {
1040
+ size = Math.max(size, 0);
1041
+
1042
+ if (cb) {
1043
+ list.push([size, encoding, resolve]);
1044
+ return;
1045
+ }
1046
+
1047
+ currentEncoding = encoding;
1048
+ current = size;
1049
+ cb = resolve;
1050
+ run();
1051
+ });
1052
+ }
1053
+
1054
+ return read;
1055
+ }
1056
+
1057
+ function createRequest(req) {
1058
+ const urlInfo = urlFn.parse(req.url || '/', true);
1059
+ return {
1060
+ method: (req.method || 'GET').toUpperCase(),
1061
+ url: req.url || '/',
1062
+ headers: req.headers,
1063
+ pathname: 'pathname' in req && req['pathname'] || urlInfo.pathname || '/',
1064
+ search: 'search' in req && req['search'] || urlInfo.search || '',
1065
+ query: 'query' in req && req['query'] || urlInfo.query || {},
1066
+ read: createRead(req)
1067
+ };
1068
+ }
1069
+
1070
+ async function sendResponse(res, target) {
1071
+ res.statusCode = target.statusCode;
1072
+
1073
+ for (const [k, v] of Object.entries(target.headers)) {
1074
+ res.setHeader(k, v);
1075
+ }
1076
+
1077
+ const stream = res instanceof Http2ServerResponse ? res.stream : res;
1078
+
1079
+ for await (const data of target) {
1080
+ if (res.finished) {
1081
+ break;
1082
+ }
1083
+
1084
+ if (stream.write(data)) {
1085
+ continue;
1086
+ }
1087
+
1088
+ await new Promise(cb => stream.once('drain', cb));
1089
+ }
1090
+
1091
+ res.end();
1092
+ }
1093
+
1094
+ function createHttpCallback(app, notFound) {
1095
+ if (notFound) {
1096
+ return async function httpCallback(req, res, next) {
1097
+ const r = await app.request(createRequest(req));
1098
+
1099
+ if (r) {
1100
+ return sendResponse(res, r);
1101
+ }
1102
+
1103
+ return notFound(req, res, next);
1104
+ };
1105
+ }
1106
+
1107
+ return async function httpCallback(req, res, next) {
1108
+ const r = await app.request(createRequest(req));
1109
+
1110
+ if (r) {
1111
+ return sendResponse(res, r);
1112
+ }
1113
+
1114
+ if (next) {
1115
+ return next();
1116
+ }
1117
+ };
1118
+ }
1119
+
1120
+ /** 判断是否为文件 */
1121
+
1122
+ async function readdir(path) {
1123
+ return new Promise(resolve => fsFn.readdir(path, {
1124
+ encoding: 'utf-8'
1125
+ }, (err, files) => err ? resolve([]) : resolve(files)));
1126
+ }
1127
+
1128
+ /** 判断是否为文件 */
1129
+
1130
+ async function isFile(path) {
1131
+ return new Promise((resolve, reject) => fsFn.stat(path, (err, stats) => err ? reject(err) : resolve(stats))).then(s => s.isFile()).catch(() => false);
1132
+ }
1133
+
1134
+ const configFileNames = ['k99.config.js', '.k99.config.js', 'k99.config.json', '.k99.config.json'];
1135
+ /**
1136
+ * 从 npm 包目录中查找
1137
+ * @param id 相对 node_modules 的路径
1138
+ * @param parent 父配置
1139
+ */
1140
+
1141
+ async function readConfig(path) {
1142
+ // TODO: 获取原始路径
1143
+ for (let f of configFileNames) {
1144
+ const file = pathFn.resolve(path, f);
1145
+
1146
+ if (!(await isFile(file))) {
1147
+ continue;
1148
+ }
1149
+
1150
+ const config = (await import(file)).default;
1151
+
1152
+ if (config && typeof config === 'object') {
1153
+ return { ...config,
1154
+ path
1155
+ };
1156
+ }
1157
+ }
1158
+ }
1159
+
1160
+ /**
1161
+ * 从 npm 包目录中查找
1162
+ * @param id 相对 node_modules 的路径
1163
+ * @param parent 父配置
1164
+ */
1165
+
1166
+ async function find(path, id, plugins) {
1167
+ for (const modulePath of getModulePaths(path)) {
1168
+ const pluginPath = pathFn.resolve(modulePath, id);
1169
+ const config = plugins[pluginPath] || (await readConfig(pluginPath));
1170
+
1171
+ if (config) {
1172
+ return config;
1173
+ }
1174
+ }
1175
+ }
1176
+
1177
+ function* getModulePaths(path) {
1178
+ for (;;) {
1179
+ yield pathFn.resolve(path, 'node_modules');
1180
+ const p = pathFn.dirname(path);
1181
+
1182
+ if (p === path) {
1183
+ return;
1184
+ }
1185
+
1186
+ path = p;
1187
+ }
1188
+ }
1189
+
1190
+ const idRegex = '[a-zA-Z][a-zA-Z0-9_-]*(?:.[a-zA-Z][a-zA-Z0-9_-]*)*';
1191
+ const nsPluginRegex = new RegExp(`^(?:@${idRegex}/)?${idRegex}$`);
1192
+ const pluginRegex = new RegExp(`^${idRegex}$`);
1193
+ function isNsPluginName(id) {
1194
+ if (!id) {
1195
+ return false;
1196
+ }
1197
+
1198
+ if (typeof id !== 'string') {
1199
+ return false;
1200
+ }
1201
+
1202
+ return pluginRegex.test(id) || nsPluginRegex.test(id);
1203
+ }
1204
+ function isPluginName(id) {
1205
+ if (!id) {
1206
+ return false;
1207
+ }
1208
+
1209
+ if (typeof id !== 'string') {
1210
+ return false;
1211
+ }
1212
+
1213
+ return pluginRegex.test(id);
1214
+ }
1215
+
1216
+ function getName(config) {
1217
+ if (isPluginName(config.name)) {
1218
+ return config.name;
1219
+ }
1220
+
1221
+ const name = pathFn.basename(config.path);
1222
+
1223
+ if (isPluginName(name)) {
1224
+ return name;
1225
+ }
1226
+
1227
+ return '';
1228
+ }
1229
+
1230
+ async function findSubPackages(plugin, configs, plugins) {
1231
+ if (plugin.packages) {
1232
+ for (let name of plugin.packages) {
1233
+ if (!isNsPluginName(name)) {
1234
+ // TODO: 抛出错误
1235
+ continue;
1236
+ }
1237
+
1238
+ if (name in plugins) {
1239
+ continue;
1240
+ }
1241
+
1242
+ const config = await find(plugin.path, name, configs);
1243
+
1244
+ if (!config) {
1245
+ // TODO: 抛出错误
1246
+ continue;
1247
+ }
1248
+
1249
+ plugins[name] = new FsPlugin(config, name);
1250
+
1251
+ if (config.path in configs) {
1252
+ return;
1253
+ }
1254
+
1255
+ configs[config.path] = config;
1256
+ findSubPackages(config, configs, plugins);
1257
+ }
1258
+ }
1259
+
1260
+ for (const path of plugin.plugins || []) {
1261
+ const pluginPath = pathFn.resolve(plugin.path, path);
1262
+ const config = await readConfig(pluginPath);
1263
+
1264
+ if (!config) {
1265
+ // TODO: 抛出错误
1266
+ continue;
1267
+ }
1268
+
1269
+ const name = getName(config);
1270
+
1271
+ if (!name) {
1272
+ // TODO: 抛出错误
1273
+ continue;
1274
+ }
1275
+
1276
+ if (name in plugins) {
1277
+ // TODO: 抛出错误
1278
+ continue;
1279
+ }
1280
+
1281
+ plugins[name] = new FsPlugin(config, name);
1282
+ configs[config.path] = config;
1283
+ findSubPackages(config, configs, plugins);
1284
+ }
1285
+ }
1286
+
1287
+ async function start() {
1288
+ const cwd = process.cwd();
1289
+ /** 入口模块 */
1290
+
1291
+ const main = (await readConfig(process.cwd())) || {
1292
+ scan: 'plugins',
1293
+ path: cwd
1294
+ };
1295
+ const mainPlugin = new FsPlugin(main, '');
1296
+ /** 插件映射 */
1297
+
1298
+ const configs = Object.create(null);
1299
+ const plugins = Object.create(null);
1300
+ configs[cwd] = main; // 递归 npm 包插件
1301
+
1302
+ findSubPackages(main, configs, plugins);
1303
+
1304
+ if (main.scan) {
1305
+ const scanPath = pathFn.join(cwd, main.scan);
1306
+
1307
+ for (let name of await readdir(scanPath)) {
1308
+ if (!isPluginName(name)) {
1309
+ continue;
1310
+ }
1311
+
1312
+ if (name in plugins) {
1313
+ continue;
1314
+ }
1315
+
1316
+ const pluginPath = pathFn.resolve(cwd, name);
1317
+ const config = await readConfig(pluginPath);
1318
+
1319
+ if (!config) {
1320
+ continue;
1321
+ }
1322
+
1323
+ configs[config.path] = config;
1324
+ plugins[name] = new FsPlugin(config, name);
1325
+ await findSubPackages(config, configs, plugins);
1326
+ }
1327
+ }
1328
+
1329
+ for (const plugin of Object.values(plugins)) {
1330
+ await plugin.initRouter();
1331
+ }
1332
+
1333
+ await mainPlugin.initRouter();
1334
+ const app = new NodeApp(mainPlugin, plugins);
1335
+ return app;
1336
+ }
1337
+
1338
+ var K99Node = /*#__PURE__*/Object.freeze({
1339
+ __proto__: null,
1340
+ FsPlugin: FsPlugin,
1341
+ NodeApp: NodeApp,
1342
+ createHttpCallback: createHttpCallback,
1343
+ Scanner: Scanner,
1344
+ start: start,
1345
+ createFsAssetsApi: createFsAssetsApi,
1346
+ createFsLogApi: createFsLogApi,
1347
+ createFsSettingsApi: createFsSettingsApi
1348
+ });
1349
+
1350
+ export { FsPlugin, NodeApp, Scanner, createFsAssetsApi, createFsLogApi, createFsSettingsApi, createHttpCallback, K99Node as default, start };