@jayfong/x-server 2.12.7 → 2.12.15

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 (84) hide show
  1. package/lib/_cjs/cli/api_generator.js +20 -54
  2. package/lib/_cjs/cli/build_util.js +16 -45
  3. package/lib/_cjs/cli/cli.js +6 -27
  4. package/lib/_cjs/cli/deploy_util.js +0 -12
  5. package/lib/_cjs/cli/env_util.js +16 -49
  6. package/lib/_cjs/cli/template_util.js +26 -29
  7. package/lib/_cjs/core/define_bus.js +9 -6
  8. package/lib/_cjs/core/define_cron.js +0 -2
  9. package/lib/_cjs/core/define_handler.js +10 -12
  10. package/lib/_cjs/core/define_hook.js +0 -2
  11. package/lib/_cjs/core/define_server.js +0 -2
  12. package/lib/_cjs/core/define_task.js +7 -13
  13. package/lib/_cjs/core/get_handler_url.js +1 -2
  14. package/lib/_cjs/core/handler.js +8 -29
  15. package/lib/_cjs/core/http_error.js +0 -3
  16. package/lib/_cjs/core/http_header.js +8 -12
  17. package/lib/_cjs/core/server.js +8 -41
  18. package/lib/_cjs/core/types.js +0 -7
  19. package/lib/_cjs/index.js +0 -72
  20. package/lib/_cjs/plugins/cors.js +0 -7
  21. package/lib/_cjs/plugins/file_parser.js +2 -9
  22. package/lib/_cjs/plugins/form_body_parser.js +0 -6
  23. package/lib/_cjs/plugins/ws_parser.js +0 -6
  24. package/lib/_cjs/plugins/xml_parser.js +0 -12
  25. package/lib/_cjs/services/cache.js +18 -58
  26. package/lib/_cjs/services/captcha.js +0 -14
  27. package/lib/_cjs/services/dingtalk.js +0 -14
  28. package/lib/_cjs/services/dispose.js +0 -9
  29. package/lib/_cjs/services/emoji.js +2 -5
  30. package/lib/_cjs/services/jwt.js +0 -21
  31. package/lib/_cjs/services/log.js +0 -17
  32. package/lib/_cjs/services/mail.js +0 -9
  33. package/lib/_cjs/services/pay.js +9 -40
  34. package/lib/_cjs/services/rate_limit.js +0 -12
  35. package/lib/_cjs/services/redis.js +0 -4
  36. package/lib/_cjs/services/request.js +14 -299
  37. package/lib/_cjs/services/sensitive_words.js +13 -19
  38. package/lib/_cjs/x.js +0 -11
  39. package/lib/cli/api_generator.js +20 -42
  40. package/lib/cli/build_util.js +16 -19
  41. package/lib/cli/cli.js +6 -12
  42. package/lib/cli/deploy_util.js +0 -4
  43. package/lib/cli/env_util.js +16 -37
  44. package/lib/cli/template_util.d.ts +1 -0
  45. package/lib/cli/template_util.js +26 -14
  46. package/lib/core/define_bus.js +7 -5
  47. package/lib/core/define_handler.js +10 -9
  48. package/lib/core/define_task.js +7 -6
  49. package/lib/core/get_handler_url.js +2 -1
  50. package/lib/core/handler.js +9 -22
  51. package/lib/core/http_header.js +6 -9
  52. package/lib/core/server.js +8 -31
  53. package/lib/core/types.js +0 -7
  54. package/lib/index.js +4 -3
  55. package/lib/plugins/cors.js +0 -3
  56. package/lib/plugins/file_parser.js +2 -5
  57. package/lib/plugins/form_body_parser.js +0 -3
  58. package/lib/plugins/ws_parser.js +0 -3
  59. package/lib/plugins/xml_parser.js +0 -10
  60. package/lib/services/cache.js +18 -52
  61. package/lib/services/captcha.js +0 -7
  62. package/lib/services/dingtalk.js +0 -7
  63. package/lib/services/dispose.js +0 -5
  64. package/lib/services/emoji.js +2 -3
  65. package/lib/services/jwt.js +0 -13
  66. package/lib/services/log.js +0 -8
  67. package/lib/services/mail.js +0 -3
  68. package/lib/services/pay.js +9 -30
  69. package/lib/services/rate_limit.js +0 -8
  70. package/lib/services/redis.js +0 -1
  71. package/lib/services/request.d.ts +3 -130
  72. package/lib/services/request.js +5 -274
  73. package/lib/services/sensitive_words.js +13 -15
  74. package/package.json +4 -28
  75. package/README.md +0 -51
  76. package/lib/_cjs/cli/register.js +0 -8
  77. package/lib/_cjs/client_helper.js +0 -26
  78. package/lib/_cjs/types/_formstream.js +0 -1
  79. package/lib/cli/register.d.ts +0 -1
  80. package/lib/cli/register.js +0 -5
  81. package/lib/client_helper.d.ts +0 -1
  82. package/lib/client_helper.js +0 -16
  83. package/lib/types/_formstream.d.ts +0 -49
  84. package/lib/types/_formstream.js +0 -0
@@ -1,4 +1,5 @@
1
1
  import fs from 'fs-extra';
2
+ import globby from 'globby';
2
3
  import path from 'path';
3
4
  import { camelCase, dedent, snakeCase, upperFirst } from 'vtils';
4
5
  import { generateManyIndex } from 'vscode-generate-index-standalone';
@@ -9,32 +10,39 @@ export class TemplateUtil {
9
10
  static async init(cwd) {
10
11
  await Promise.all([this.initHelperPackage(cwd), this.initTasks(cwd)]);
11
12
  }
13
+
12
14
  /**
13
15
  * 初始化辅助包。
14
16
  */
15
-
16
-
17
17
  static async initHelperPackage(cwd) {
18
+ const prismaClientFile = TemplateUtil.getPrismaClientTypeFile();
18
19
  const fromDir = path.join(__dirname, 'templates');
19
20
  const toDir = path.join(cwd, 'node_modules/.x');
20
- await fs.copy(fromDir, toDir, {
21
- overwrite: true
21
+ const fromFiles = await globby('*', {
22
+ cwd: fromDir,
23
+ onlyFiles: true,
24
+ absolute: true
22
25
  });
26
+ await fs.ensureDir(toDir);
27
+ await Promise.all(fromFiles.map(async fromFile => {
28
+ const toFile = fromFile.replace(fromDir, toDir);
29
+ let fromFileContent = await fs.readFile(fromFile, 'utf-8');
30
+ fromFileContent = fromFileContent.replaceAll('../.prisma/client/index.d.ts', path.relative(toDir, prismaClientFile)).replaceAll('../../src', path.relative(toDir, `${cwd}/src`));
31
+ await fs.writeFile(toFile, fromFileContent);
32
+ }));
23
33
  await generateManyIndex({
24
34
  cwd: cwd,
25
35
  patterns: ['node_modules/.x/*.ts'],
26
36
  replaceFile: true
27
37
  });
28
38
  }
39
+
29
40
  /**
30
41
  * 初始化任务。
31
42
  */
32
-
33
-
34
43
  static async initTasks(cwd) {
35
44
  const tasksDir = path.join(cwd, 'src/tasks');
36
45
  const tasksIndexFile = path.join(tasksDir, 'index.ts');
37
-
38
46
  if (!(await fs.pathExists(tasksIndexFile))) {
39
47
  await fs.outputFile(tasksIndexFile, dedent`
40
48
  // @index(['./**/*.ts', '!**/*.test.ts', '!**/_*'], f => \`export * from '\${f.path}'\`)
@@ -42,23 +50,21 @@ export class TemplateUtil {
42
50
  `);
43
51
  }
44
52
  }
53
+
45
54
  /**
46
55
  * 初始化模型。
47
56
  */
48
-
49
-
50
57
  static async initModels(cwd) {
51
58
  const modelsDir = path.join(cwd, 'src/models');
52
59
  const indexFile = path.join(modelsDir, 'index.ts');
53
60
  const indexFile2 = path.join(cwd, 'node_modules/.x/models.ts');
54
- const prismaClientFile = path.join(cwd, 'node_modules/.prisma/client/index.d.ts');
61
+ const prismaClientFile = TemplateUtil.getPrismaClientTypeFile();
55
62
  const prismaClientFileContent = await fs.readFile(prismaClientFile, 'utf8');
56
63
  const modelNames = [...prismaClientFileContent.match(/(?<=const ModelName:).+?(?=\})/s)[0].matchAll(/(\S+?):/g)].map(match => camelCase(match[1]));
57
64
  await Promise.all(modelNames.map(async modelName => {
58
65
  const model_name = snakeCase(modelName);
59
66
  const ModelName = upperFirst(modelName);
60
67
  const modelFile = path.join(modelsDir, `${model_name}.ts`);
61
-
62
68
  if (!(await fs.pathExists(modelFile))) {
63
69
  await fs.outputFile(modelFile, dedent`
64
70
  import { ${ModelName}BaseModel } from '@jayfong/x-server'
@@ -69,19 +75,25 @@ export class TemplateUtil {
69
75
  `);
70
76
  }
71
77
  }));
72
-
73
78
  if (!(await fs.pathExists(indexFile))) {
74
79
  await fs.outputFile(indexFile, dedent`
75
80
  // @index(['./**/*.ts', '!**/*.test.ts', '!**/_*'], f => \`export * from '\${f.path}'\`)
76
81
  // @endindex
77
82
  `);
78
83
  }
79
-
80
84
  await generateManyIndex({
81
85
  cwd: cwd,
82
86
  patterns: [indexFile, indexFile2],
83
87
  replaceFile: true
84
88
  });
85
89
  }
86
-
90
+ static getPrismaClientTypeFile() {
91
+ // const prismaClientFile = path.join(
92
+ // cwd,
93
+ // 'node_modules/.prisma/client/index.d.ts',
94
+ // )
95
+ // 用 require.resolve 以兼容 pnpm
96
+ const prismaClientFile = require.resolve('@prisma/client/package.json').replace('@prisma/client/package.json', '.prisma/client/index.d.ts');
97
+ return prismaClientFile;
98
+ }
87
99
  }
@@ -1,18 +1,18 @@
1
1
  import { EventEmitter } from 'node:events';
2
-
3
2
  class EventBus extends EventEmitter {
4
3
  onReturnOff(event, listener) {
5
4
  this.on(event, listener);
6
5
  return () => this.off(event, listener);
7
6
  }
8
-
9
7
  }
10
-
11
8
  export function defineBus() {
12
9
  const eventEmitter = new EventBus();
13
10
  return eventEmitter;
14
- } // strict-event-emitter-types
11
+ }
12
+
13
+ // strict-event-emitter-types
15
14
  // https://github.com/bterlson/strict-event-emitter-types/blob/9ed45fc68a69f0b7f85ce4e5fe11ff53cc6a009e/src/index.ts
15
+
16
16
  // the overridden signatures need to be assignment compatible, but
17
17
  // due to how tuple types work[0] it's not possible to be assignment
18
18
  // compatible anymore. This hack fixes it with a unique symbol that
@@ -20,4 +20,6 @@ export function defineBus() {
20
20
  //
21
21
  // Unfortunately, this has the result of giving a poor error message when
22
22
  // you mix up types.
23
- // 0: https://github.com/Microsoft/TypeScript/issues/26013)
23
+ // 0: https://github.com/Microsoft/TypeScript/issues/26013)
24
+ // TODO: Stash under a symbol key once TS compiler bug is fixed
25
+ // EventEmitter method overrides
@@ -1,35 +1,36 @@
1
1
  import { Handler } from "./handler";
2
2
  export function defineHandler(options) {
3
- const handler = new Handler({ ...options,
3
+ const handler = new Handler({
4
+ ...options,
4
5
  requestMethod: 'POST'
5
6
  });
6
7
  return handler;
7
8
  }
8
9
  defineHandler.POST = defineHandler;
9
-
10
10
  defineHandler.GET = options => {
11
- const handler = new Handler({ ...options,
11
+ const handler = new Handler({
12
+ ...options,
12
13
  requestMethod: 'GET'
13
14
  });
14
15
  return handler;
15
16
  };
16
-
17
17
  defineHandler.FILE = options => {
18
- const handler = new Handler({ ...options,
18
+ const handler = new Handler({
19
+ ...options,
19
20
  requestMethod: 'FILE'
20
21
  });
21
22
  return handler;
22
23
  };
23
-
24
24
  defineHandler.WS = options => {
25
- const handler = new Handler({ ...options,
25
+ const handler = new Handler({
26
+ ...options,
26
27
  requestMethod: 'WS'
27
28
  });
28
29
  return handler;
29
30
  };
30
-
31
31
  defineHandler.XML = options => {
32
- const handler = new Handler({ ...options,
32
+ const handler = new Handler({
33
+ ...options,
33
34
  requestMethod: 'XML'
34
35
  });
35
36
  return handler;
@@ -4,7 +4,8 @@ import { ms } from 'vtils';
4
4
  import { x } from "../x";
5
5
  export function defineTask(options) {
6
6
  const queue = new Queue(options.name, {
7
- redis: { ...x.redis.options,
7
+ redis: {
8
+ ...x.redis.options,
8
9
  // https://github.com/OptimalBits/bull/issues/2186
9
10
  maxRetriesPerRequest: null,
10
11
  enableReadyCheck: false
@@ -28,7 +29,6 @@ export function defineSliceTask(options) {
28
29
  handle: async data => {
29
30
  const res = data.count ? await x.redis.multi([['lrange', data.redisKey, `-${data.count}`, '-1'], ['ltrim', data.redisKey, '0', `-${data.count + 1}`]]).exec() : await x.redis.multi([['lrange', data.redisKey, '0', '-1'], ['del', data.redisKey]]).exec();
30
31
  const list = res[0][1].reverse().map(item => JSON.parse(item));
31
-
32
32
  if (list.length) {
33
33
  return options.handle(list, data.key);
34
34
  }
@@ -44,9 +44,10 @@ export function defineSliceTask(options) {
44
44
  assert(duration != null || threshold != null, '参数 threshold 和 duration 必须至少设置 1 个');
45
45
  const redisKey = !key ? redisKeyPrefix : `${redisKeyPrefix}_${key}`;
46
46
  const res = await x.redis.multi([['llen', redisKey], ['lpush', redisKey, JSON.stringify(data)]]).exec();
47
- const count = parseInt(res[0][1], 10) + 1; // 仅时段
48
- // 1分钟内的合并推送
47
+ const count = parseInt(res[0][1], 10) + 1;
49
48
 
49
+ // 仅时段
50
+ // 1分钟内的合并推送
50
51
  if (duration != null) {
51
52
  if (count === 1) {
52
53
  await task.add({
@@ -56,7 +57,8 @@ export function defineSliceTask(options) {
56
57
  delay: duration
57
58
  });
58
59
  }
59
- } // 仅阈值
60
+ }
61
+ // 仅阈值
60
62
  // 满10条推送
61
63
  else if (threshold != null) {
62
64
  if (thresholdTimeout) {
@@ -70,7 +72,6 @@ export function defineSliceTask(options) {
70
72
  delay: thresholdTimeout
71
73
  });
72
74
  }
73
-
74
75
  if (count === threshold) {
75
76
  await task.add({
76
77
  key: key,
@@ -1,5 +1,6 @@
1
1
  import { createUrlQueryString } from 'vtils';
2
- import { x } from "../x"; // @ts-ignore
2
+ import { x } from "../x";
3
+ // @ts-ignore
3
4
 
4
5
  export function getHandlerUrl(path, query) {
5
6
  return `${x.env.APP_URL.replace(/\/+$/, '')}${path}${query ? `?${createUrlQueryString(query)}` : ''}`;
@@ -3,24 +3,23 @@ import { DataPacker } from 'vtils';
3
3
  import { DisposeService } from "../services/dispose";
4
4
  import { HttpError } from "../core/http_error";
5
5
  import { yup } from 'vtils/validator';
6
+
7
+ // @ts-ignore
8
+ // prettier-ignore
6
9
  export class Handler {
7
10
  constructor(options) {
8
11
  this.options = options;
9
12
  this.requestDataSchema = void 0;
10
-
11
13
  this.handle = async (data, ctx) => {
12
14
  // 前置 hook
13
15
  if (Handler.hooks.length) {
14
16
  await Promise.all(Handler.hooks.map(hook => hook(this.options, data, ctx)));
15
17
  }
16
-
17
18
  if (this.options.requestMethod === 'WS') {
18
19
  return this.handleWs(data, ctx);
19
20
  }
20
-
21
21
  return this.handleHttp(data, ctx);
22
22
  };
23
-
24
23
  this.handleHttp = async (data, ctx) => {
25
24
  // 请求数据验证
26
25
  if (this.requestDataSchema) {
@@ -33,45 +32,40 @@ export class Handler {
33
32
  throw new HttpError.BadRequest(err.message);
34
33
  }
35
34
  }
35
+ let res = await this.options.handle(data, ctx);
36
36
 
37
- let res = await this.options.handle(data, ctx); // 设置响应的 Content-Type 头
38
-
37
+ // 设置响应的 Content-Type 头
39
38
  if (this.options.responseContentType) {
40
39
  ctx.setHeader('Content-Type', this.options.responseContentType);
41
- } // 打包返回数据
42
-
40
+ }
43
41
 
42
+ // 打包返回数据
44
43
  if (this.options.responseDataPack) {
45
44
  res = DataPacker.packAsRawType(res);
46
- } // 混淆返回数据
47
-
45
+ }
48
46
 
47
+ // 混淆返回数据
49
48
  if (this.options.responseDataObfuscate) {
50
49
  res = {
51
50
  '_#': LZString.compress(JSON.stringify(res))
52
51
  };
53
52
  }
54
-
55
53
  return res == null ? {} : res;
56
54
  };
57
-
58
55
  this.handleWs = async (data, ctx) => {
59
56
  const dispose = new DisposeService();
60
57
  ctx.ws.socket.on('message', async payload => {
61
58
  try {
62
59
  const _ = JSON.parse(payload.toString('utf8'));
63
-
64
60
  const send = data => {
65
61
  ctx.ws.socket.send(JSON.stringify({
66
62
  id: _.id,
67
63
  data: data
68
64
  }));
69
65
  };
70
-
71
66
  const process = async (type, fn) => {
72
67
  if (_.type === type) {
73
68
  let sent = false;
74
-
75
69
  try {
76
70
  await fn({
77
71
  data: _.data,
@@ -81,13 +75,11 @@ export class Handler {
81
75
  },
82
76
  dispose: dispose
83
77
  });
84
-
85
78
  if (!sent) {
86
79
  send();
87
80
  }
88
81
  } catch (err) {
89
82
  const _err = HttpError.isHttpError(err) ? err : new HttpError.InternalServerError();
90
-
91
83
  send({
92
84
  statusCode: _err.statusCode,
93
85
  error: _err.name,
@@ -96,7 +88,6 @@ export class Handler {
96
88
  }
97
89
  }
98
90
  };
99
-
100
91
  if (_.type === 'ping') {
101
92
  send();
102
93
  } else {
@@ -104,7 +95,6 @@ export class Handler {
104
95
  }
105
96
  } catch (err) {
106
97
  const _err = HttpError.isHttpError(err) ? err : new HttpError.InternalServerError();
107
-
108
98
  ctx.ws.socket.send(JSON.stringify({
109
99
  statusCode: _err.statusCode,
110
100
  error: _err.name,
@@ -116,15 +106,12 @@ export class Handler {
116
106
  dispose.dispose();
117
107
  });
118
108
  };
119
-
120
109
  if (options.requestDataSchema) {
121
110
  this.requestDataSchema = options.requestDataSchema(yup);
122
111
  }
123
112
  }
124
-
125
113
  static addHook(hook) {
126
114
  this.hooks.push(hook);
127
115
  }
128
-
129
116
  }
130
117
  Handler.hooks = [];
@@ -1,5 +1,4 @@
1
1
  // https://en.wikipedia.org/wiki/List_of_HTTP_header_fields
2
-
3
2
  /**
4
3
  [...$0.querySelectorAll('tr')].map(v => v.querySelector('td:nth-child(1)').innerText.trim().split(',').map(name => name.replace(/\[.*?\]/g, '').trim()).map((name) => ({
5
4
  name: name,
@@ -16,9 +15,8 @@ ${'/'}**
16
15
  ${item.pascalName} = '${item.name}',
17
16
  `).join('\n\n')
18
17
  */
19
- export let HttpRequestHeader;
20
18
 
21
- (function (HttpRequestHeader) {
19
+ export let HttpRequestHeader = /*#__PURE__*/function (HttpRequestHeader) {
22
20
  HttpRequestHeader["A_IM"] = "A-IM";
23
21
  HttpRequestHeader["ACCEPT"] = "Accept";
24
22
  HttpRequestHeader["ACCEPT_CHARSET"] = "Accept-Charset";
@@ -75,11 +73,9 @@ export let HttpRequestHeader;
75
73
  HttpRequestHeader["X_REQUEST_ID"] = "X-Request-ID";
76
74
  HttpRequestHeader["X_CORRELATION_ID"] = "X-Correlation-ID";
77
75
  HttpRequestHeader["SAVE_DATA"] = "Save-Data";
78
- })(HttpRequestHeader || (HttpRequestHeader = {}));
79
-
80
- export let HttpResponseHeader;
81
-
82
- (function (HttpResponseHeader) {
76
+ return HttpRequestHeader;
77
+ }({});
78
+ export let HttpResponseHeader = /*#__PURE__*/function (HttpResponseHeader) {
83
79
  HttpResponseHeader["ACCESS_CONTROL_ALLOW_ORIGIN"] = "Access-Control-Allow-Origin";
84
80
  HttpResponseHeader["ACCESS_CONTROL_ALLOW_CREDENTIALS"] = "Access-Control-Allow-Credentials";
85
81
  HttpResponseHeader["ACCESS_CONTROL_EXPOSE_HEADERS"] = "Access-Control-Expose-Headers";
@@ -139,4 +135,5 @@ export let HttpResponseHeader;
139
135
  HttpResponseHeader["X_CORRELATION_ID"] = "X-Correlation-ID";
140
136
  HttpResponseHeader["X_UA_COMPATIBLE"] = "X-UA-Compatible";
141
137
  HttpResponseHeader["X_XSS_PROTECTION"] = "X-XSS-Protection";
142
- })(HttpResponseHeader || (HttpResponseHeader = {}));
138
+ return HttpResponseHeader;
139
+ }({});
@@ -10,7 +10,6 @@ export class Server {
10
10
  this.routes = [];
11
11
  Server.options = options;
12
12
  }
13
-
14
13
  async start() {
15
14
  this.applyServices();
16
15
  await this.prepareFastify();
@@ -22,13 +21,10 @@ export class Server {
22
21
  await this.startCrons();
23
22
  await this.applyAutoClose();
24
23
  }
25
-
26
24
  async close() {
27
25
  var _this$fastify;
28
-
29
26
  await ((_this$fastify = this.fastify) == null ? void 0 : _this$fastify.close());
30
27
  }
31
-
32
28
  async prepareFastify() {
33
29
  this.fastify = await Fastify({
34
30
  logger: process.env.NODE_ENV === 'development' ? {
@@ -42,14 +38,12 @@ export class Server {
42
38
  ...this.options.fastifyOptions
43
39
  });
44
40
  }
45
-
46
41
  async startFastify() {
47
42
  await this.fastify.listen({
48
43
  host: this.options.host || '0.0.0.0',
49
44
  port: this.options.port
50
45
  });
51
46
  }
52
-
53
47
  async prepareRoutes() {
54
48
  // @ts-ignore
55
49
  const {
@@ -57,36 +51,30 @@ export class Server {
57
51
  } = await import('.x/routes');
58
52
  this.routes = routes;
59
53
  }
60
-
61
54
  async applyHooks() {
62
55
  // @ts-ignore
63
56
  await import('.x/hooks');
64
57
  }
65
-
66
58
  applyServices() {
67
59
  x.register(...(this.options.services || []));
68
60
  }
69
-
70
61
  applyPlugins() {
71
62
  const plugins = this.options.plugins || [];
72
-
73
63
  for (const plugin of plugins) {
74
64
  plugin.register(this.fastify);
75
65
  }
76
66
  }
77
-
78
67
  async applyRoutes() {
79
68
  await this.fastify.register(async fastify => {
80
69
  const appUrl = x.env.APP_URL.replace(/\/+$/, '');
81
70
  const routeMap = keyBy(this.routes, item => item.path);
82
-
83
71
  const handleRoute = async (item, req, res, path) => {
84
72
  const handlerOptions = item.handler.options;
85
73
  const handlerMethod = handlerOptions.requestMethod || 'POST';
86
74
  const isWS = handlerMethod === 'WS';
87
- const url = `${appUrl}${// 结构:/test/sss?x=2
75
+ const url = `${appUrl}${
76
+ // 结构:/test/sss?x=2
88
77
  path != null ? path : isWS ? res.url : req.url}`;
89
-
90
78
  if (isWS) {
91
79
  await item.handler.handle(undefined, {
92
80
  url: url,
@@ -99,9 +87,7 @@ export class Server {
99
87
  });
100
88
  return;
101
89
  }
102
-
103
90
  let files = {};
104
-
105
91
  if (handlerMethod === 'FILE') {
106
92
  const part = await req.file();
107
93
  files = Object.keys(part.fields).reduce((res, name) => {
@@ -110,8 +96,8 @@ export class Server {
110
96
  return res;
111
97
  }, {});
112
98
  }
113
-
114
- const data = await item.handler.handle({ // @ts-ignore
99
+ const data = await item.handler.handle({
100
+ // @ts-ignore
115
101
  ...req.params,
116
102
  // @ts-ignore
117
103
  ...req.query,
@@ -129,7 +115,6 @@ export class Server {
129
115
  });
130
116
  return data;
131
117
  };
132
-
133
118
  for (const item of this.routes) {
134
119
  const handlerOptions = item.handler.options;
135
120
  const handlerMethod = handlerOptions.requestMethod || 'POST';
@@ -144,39 +129,34 @@ export class Server {
144
129
  websocket: isWS,
145
130
  handler: (req, res) => handleRoute(item, req, res)
146
131
  });
147
- } // 接口统一入口
148
-
132
+ }
149
133
 
134
+ // 接口统一入口
150
135
  fastify.route({
151
136
  method: 'POST',
152
137
  url: '/@',
153
138
  handler: async (req, res) => {
154
139
  let requestPath = req.headers['x-path'] || '';
155
-
156
140
  if (!requestPath.startsWith('/')) {
157
141
  const [_requestPath, _time] = base64UrlDecode(rot13(requestPath)).split('#');
158
-
159
142
  if (!_time || Date.now() / 1000 - Number(_time) > 5 * 60) {
160
143
  throw new HttpError.Forbidden();
161
144
  }
162
-
163
145
  requestPath = _requestPath;
164
146
  }
165
-
166
147
  if (!requestPath || !routeMap[requestPath]) {
167
148
  throw new HttpError.NotFound();
168
149
  }
169
-
170
150
  return handleRoute(routeMap[requestPath], req, res, requestPath);
171
151
  }
172
- }); // 开发管理入口
152
+ });
173
153
 
154
+ // 开发管理入口
174
155
  fastify.route({
175
156
  method: 'POST',
176
157
  url: '/$',
177
158
  handler: async req => {
178
159
  const payload = req.body;
179
-
180
160
  if (payload && typeof payload === 'object' && x.env.APP_TOKEN && payload.token === x.env.APP_TOKEN) {
181
161
  if (payload.type === 'ping') {
182
162
  return 'ping:success';
@@ -188,15 +168,12 @@ export class Server {
188
168
  });
189
169
  });
190
170
  }
191
-
192
171
  async startCrons() {
193
172
  // @ts-ignore
194
173
  await import('.x/crons');
195
174
  }
196
-
197
175
  async applyAutoClose() {
198
176
  x.dispose.add(() => this.close());
199
177
  }
200
-
201
178
  }
202
179
  Server.options = {};
package/lib/core/types.js CHANGED
@@ -1,15 +1,8 @@
1
1
  export let XServer;
2
-
3
2
  (function (_XServer) {})(XServer || (XServer = {}));
4
-
5
3
  export let XHandler;
6
-
7
4
  (function (_XHandler) {})(XHandler || (XHandler = {}));
8
-
9
5
  export let XTask;
10
-
11
6
  (function (_XTask) {})(XTask || (XTask = {}));
12
-
13
7
  export let XCron;
14
-
15
8
  (function (_XCron) {})(XCron || (XCron = {}));
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // @index(['./**/*.ts', '!**/*.test.ts', '!./cli/**', '!./client_helper.ts', '!**/_*'], f => `export * from '${f.path}'`)
1
+ // @index(['./**/*.ts', '!**/*.test.ts', '!./cli/**', '!**/_*'], f => `export * from '${f.path}'`)
2
2
  export * from "./core/define_bus";
3
3
  export * from "./core/define_cron";
4
4
  export * from "./core/define_handler";
@@ -33,7 +33,8 @@ export * from "./services/redis";
33
33
  export * from "./services/request";
34
34
  export * from "./services/sensitive_words";
35
35
  export * from "./types/index";
36
- export * from "./x"; // @endindex
37
- // @ts-ignore
36
+ export * from "./x";
37
+ // @endindex
38
38
 
39
+ // @ts-ignore
39
40
  export * from '.x/models';
@@ -1,7 +1,6 @@
1
1
  import FastifyCors from '@fastify/cors';
2
2
  import { memoize } from 'vtils';
3
3
  import { ms } from 'vtils';
4
-
5
4
  /**
6
5
  * CORS 支持插件
7
6
  */
@@ -9,7 +8,6 @@ export class CorsPlugin {
9
8
  constructor(options) {
10
9
  this.options = options;
11
10
  }
12
-
13
11
  register(fastify) {
14
12
  const allows = this.options.allow.map(item => ({
15
13
  type: item === '*' ? 'all' : item.startsWith('*.') ? 'endsWith' : 'equal',
@@ -30,5 +28,4 @@ export class CorsPlugin {
30
28
  maxAge: ms(this.options.ttl, true)
31
29
  });
32
30
  }
33
-
34
31
  }
@@ -1,6 +1,5 @@
1
1
  import FastifyMultipart from '@fastify/multipart';
2
2
  import { bytes } from 'vtils';
3
-
4
3
  /**
5
4
  * file 解析器插件
6
5
  *
@@ -10,16 +9,14 @@ export class FileParserPlugin {
10
9
  constructor(options) {
11
10
  this.options = options;
12
11
  }
13
-
14
12
  register(fastify) {
15
13
  var _this$options;
16
-
17
- fastify.register(FastifyMultipart, { ...this.options,
14
+ fastify.register(FastifyMultipart, {
15
+ ...this.options,
18
16
  limits: {
19
17
  fileSize: bytes(1, 'MB'),
20
18
  ...((_this$options = this.options) == null ? void 0 : _this$options.limits)
21
19
  }
22
20
  });
23
21
  }
24
-
25
22
  }
@@ -1,5 +1,4 @@
1
1
  import FastifyFormBody from '@fastify/formbody';
2
-
3
2
  /**
4
3
  * POST application/x-www-form-urlencoded 解析器插件
5
4
  */
@@ -7,9 +6,7 @@ export class FormBodyParserPlugin {
7
6
  constructor(options) {
8
7
  this.options = options;
9
8
  }
10
-
11
9
  register(fastify) {
12
10
  fastify.register(FastifyFormBody, this.options);
13
11
  }
14
-
15
12
  }
@@ -1,5 +1,4 @@
1
1
  import FastifyWebsocket from '@fastify/websocket';
2
-
3
2
  /**
4
3
  * websocket 解析器插件
5
4
  */
@@ -7,9 +6,7 @@ export class WsParserPlugin {
7
6
  constructor(options) {
8
7
  this.options = options;
9
8
  }
10
-
11
9
  register(fastify) {
12
10
  fastify.register(FastifyWebsocket, this.options);
13
11
  }
14
-
15
12
  }