@jayfong/x-server 1.11.0 → 1.11.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/lib/_cjs/cli/api_generator.js +295 -0
  3. package/lib/_cjs/cli/build_util.js +151 -0
  4. package/lib/_cjs/cli/cli.js +190 -0
  5. package/lib/_cjs/cli/deploy_util.js +61 -0
  6. package/lib/_cjs/cli/env_util.js +145 -0
  7. package/lib/_cjs/cli/register.js +8 -0
  8. package/lib/_cjs/cli/template_util.js +77 -0
  9. package/lib/_cjs/cli/templates/handlers.ts +3 -0
  10. package/lib/_cjs/cli/templates/hooks.ts +2 -0
  11. package/lib/_cjs/cli/templates/models.ts +22 -0
  12. package/lib/_cjs/cli/templates/package.json +3 -0
  13. package/lib/_cjs/cli/templates/routes.ts +26 -0
  14. package/lib/_cjs/cli/templates/tasks.ts +2 -0
  15. package/lib/_cjs/core/define_bus.js +28 -0
  16. package/lib/_cjs/core/define_handler.js +43 -0
  17. package/lib/_cjs/core/define_hook.js +10 -0
  18. package/lib/_cjs/core/define_server.js +12 -0
  19. package/lib/_cjs/core/define_task.js +30 -0
  20. package/lib/_cjs/core/handler.js +90 -0
  21. package/lib/_cjs/core/http_error.js +9 -0
  22. package/lib/_cjs/core/http_method.js +12 -0
  23. package/lib/_cjs/core/server.js +145 -0
  24. package/lib/_cjs/core/types.js +18 -0
  25. package/lib/_cjs/index.js +179 -0
  26. package/lib/_cjs/plugins/base.js +3 -0
  27. package/lib/_cjs/plugins/cors.js +44 -0
  28. package/lib/_cjs/plugins/file_parser.js +24 -0
  29. package/lib/_cjs/plugins/ws_parser.js +24 -0
  30. package/lib/_cjs/plugins/xml_parser.js +61 -0
  31. package/lib/_cjs/services/base.js +3 -0
  32. package/lib/_cjs/services/cache.js +231 -0
  33. package/lib/_cjs/services/captcha.js +45 -0
  34. package/lib/_cjs/services/dispose.js +33 -0
  35. package/lib/_cjs/services/jwt.js +59 -0
  36. package/lib/_cjs/services/redis.js +18 -0
  37. package/lib/_cjs/x.js +20 -0
  38. package/lib/cli/api_generator.js +269 -332
  39. package/lib/cli/build_util.js +113 -130
  40. package/lib/cli/cli.js +161 -187
  41. package/lib/cli/deploy_util.js +37 -41
  42. package/lib/cli/env_util.js +112 -120
  43. package/lib/cli/register.js +5 -7
  44. package/lib/cli/template_util.js +47 -52
  45. package/lib/core/define_bus.js +22 -14
  46. package/lib/core/define_handler.js +31 -36
  47. package/lib/core/define_hook.js +4 -8
  48. package/lib/core/define_server.js +6 -10
  49. package/lib/core/define_task.js +20 -25
  50. package/lib/core/handler.js +78 -74
  51. package/lib/core/http_error.js +2 -8
  52. package/lib/core/http_method.js +7 -10
  53. package/lib/core/server.js +125 -139
  54. package/lib/core/types.js +11 -2
  55. package/lib/index.js +23 -39
  56. package/lib/plugins/base.js +1 -2
  57. package/lib/plugins/cors.js +30 -36
  58. package/lib/plugins/file_parser.d.ts +1 -1
  59. package/lib/plugins/file_parser.js +12 -16
  60. package/lib/plugins/ws_parser.d.ts +1 -1
  61. package/lib/plugins/ws_parser.js +12 -16
  62. package/lib/plugins/xml_parser.d.ts +1 -1
  63. package/lib/plugins/xml_parser.js +47 -43
  64. package/lib/services/base.js +1 -2
  65. package/lib/services/cache.js +213 -190
  66. package/lib/services/captcha.js +32 -33
  67. package/lib/services/dispose.d.ts +1 -1
  68. package/lib/services/dispose.js +22 -23
  69. package/lib/services/jwt.js +45 -48
  70. package/lib/services/redis.js +8 -14
  71. package/lib/x.js +12 -15
  72. package/package.json +5 -4
@@ -0,0 +1,231 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
5
+ exports.__esModule = true;
6
+ exports.CacheService = void 0;
7
+
8
+ var _cuid = _interopRequireDefault(require("cuid"));
9
+
10
+ var _date = require("vtils/date");
11
+
12
+ var _x = require("../x");
13
+
14
+ class CacheService {
15
+ constructor(options) {
16
+ this.options = options;
17
+ this.serviceName = 'cache';
18
+ this.prefix = void 0;
19
+ this.prefix = `${_x.x.appName}:`;
20
+ }
21
+
22
+ toRedisKey(key) {
23
+ return `${this.prefix}${Array.isArray(key) ? key.join('_') : String(key)}`;
24
+ }
25
+ /**
26
+ * 设置缓存内容。对象类内容尽量避免使用,以免造成问题。
27
+ *
28
+ * @param key 键
29
+ * @param value 值
30
+ * @param ttl 缓存时间(单位:时)
31
+ * @returns 返回设置的缓存内容
32
+ */
33
+
34
+
35
+ async set(key, value, ttl = this.options.ttl) {
36
+ const redisKey = this.toRedisKey(key);
37
+ const redisValue = JSON.stringify(value);
38
+ const redisTtl = typeof ttl === 'function' ? ttl(value, this.options.ttl) : ttl;
39
+ await _x.x.redis.set(redisKey, redisValue, // 毫秒
40
+ 'PX', (0, _date.ms)(redisTtl));
41
+ return value;
42
+ }
43
+ /**
44
+ * 存储值然后返回其对应的键,该键 URL 友好。
45
+ *
46
+ * @param value 值
47
+ * @param ttl 存活时间
48
+ */
49
+
50
+
51
+ async save(value, ttl = this.options.ttl) {
52
+ const key = `X__${(0, _cuid.default)()}`;
53
+ await this.set(key, typeof value === 'function' ? await value(key) : value, ttl);
54
+ return key;
55
+ }
56
+ /**
57
+ * 获取缓存内容。
58
+ *
59
+ * @param key 键
60
+ * @returns 返回获取到的缓存内容
61
+ */
62
+
63
+
64
+ async get(key) {
65
+ const redisKey = this.toRedisKey(key);
66
+ const gotValue = await _x.x.redis.get(redisKey);
67
+
68
+ if (gotValue) {
69
+ try {
70
+ return JSON.parse(gotValue);
71
+ } catch {}
72
+ }
73
+
74
+ return null;
75
+ }
76
+ /**
77
+ * 获取多个缓存内容。
78
+ *
79
+ * @param keys 键
80
+ * @returns 返回获取到的缓存内容
81
+ */
82
+
83
+
84
+ async getMany(...keys) {
85
+ const redisKeys = keys.map(key => this.toRedisKey(key));
86
+ if (!redisKeys.length) return [];
87
+ const gotValues = await _x.x.redis.mget(...redisKeys);
88
+ return gotValues.map(value => {
89
+ if (value == null) return null;
90
+
91
+ try {
92
+ return JSON.parse(value);
93
+ } catch {
94
+ return null;
95
+ }
96
+ });
97
+ }
98
+ /**
99
+ * 缓存内容。
100
+ *
101
+ * @param key 键
102
+ * @param action 获取缓存内容的操作
103
+ * @param ttl 缓存时间(单位:时)
104
+ * @returns 返回获取到的内容
105
+ */
106
+
107
+
108
+ async remember(key, action, ttl = this.options.ttl) {
109
+ let value = await this.get(key);
110
+
111
+ if (value === null) {
112
+ value = await action();
113
+ await this.set(key, value, ttl);
114
+ }
115
+
116
+ return value;
117
+ }
118
+ /**
119
+ * 自增。
120
+ *
121
+ * @param key 键
122
+ * @param increment 增量
123
+ */
124
+
125
+
126
+ async increase(key, increment = 1) {
127
+ const redisKey = this.toRedisKey(key);
128
+ return _x.x.redis.incrby(redisKey, increment);
129
+ }
130
+ /**
131
+ * 自减。
132
+ *
133
+ * @param key 键
134
+ * @param decrement 减量
135
+ */
136
+
137
+
138
+ async decrease(key, decrement = 1) {
139
+ return this.increase(key, -decrement);
140
+ }
141
+ /**
142
+ * 新增元素。
143
+ *
144
+ * @param key 键
145
+ * @param values 元素列表
146
+ */
147
+
148
+
149
+ async push(key, ...values) {
150
+ const redisKey = this.toRedisKey(key);
151
+ return _x.x.redis.rpush(redisKey, ...values.map(value => JSON.stringify(value)));
152
+ }
153
+ /**
154
+ * 从头部弹出元素并返回。
155
+ *
156
+ * @param key 键
157
+ * @param count 弹出元素个数
158
+ */
159
+
160
+
161
+ async shift(key, count = 1) {
162
+ const redisKey = this.toRedisKey(key);
163
+ const res = [];
164
+
165
+ for (let i = 0; i < count; i++) {
166
+ const item = await _x.x.redis.lpop(redisKey);
167
+
168
+ if (item) {
169
+ res.push(JSON.parse(item));
170
+ } else {
171
+ break;
172
+ }
173
+ }
174
+
175
+ return res;
176
+ }
177
+ /**
178
+ * 删除缓存。
179
+ *
180
+ * @param keys 键列表
181
+ */
182
+
183
+
184
+ async remove(...keys) {
185
+ return Promise.all(keys.map(async key => {
186
+ const redisKey = this.toRedisKey(key);
187
+ return _x.x.redis.del(redisKey);
188
+ }));
189
+ }
190
+ /**
191
+ * 清空全部缓存。
192
+ */
193
+
194
+
195
+ async clearAll() {
196
+ const keys = await _x.x.redis.keys(`${this.prefix}*`);
197
+
198
+ if (keys.length) {
199
+ return _x.x.redis.del(...keys);
200
+ }
201
+
202
+ return 0;
203
+ }
204
+ /**
205
+ * 清空指定前缀的缓存。
206
+ */
207
+
208
+
209
+ async clear(...prefixes) {
210
+ const keys = (await Promise.all(prefixes.map(prefix => _x.x.redis.keys(`${this.toRedisKey(prefix)}*`)))).flat();
211
+
212
+ if (keys.length) {
213
+ return _x.x.redis.del(...keys);
214
+ }
215
+
216
+ return 0;
217
+ }
218
+ /**
219
+ * 派生出一个指定类型的缓存服务。
220
+ */
221
+
222
+
223
+ fork(options) {
224
+ return options ? new CacheService({ ...this.options,
225
+ ...options
226
+ }) : this;
227
+ }
228
+
229
+ }
230
+
231
+ exports.CacheService = CacheService;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
5
+ exports.__esModule = true;
6
+ exports.CaptchaService = void 0;
7
+
8
+ var _svgCaptcha = _interopRequireDefault(require("svg-captcha"));
9
+
10
+ var _x = require("../x");
11
+
12
+ class CaptchaService {
13
+ constructor(options) {
14
+ this.options = options;
15
+ this.serviceName = 'captcha';
16
+ }
17
+
18
+ async generate() {
19
+ const res = _svgCaptcha.default.create({
20
+ size: this.options.size
21
+ });
22
+
23
+ const token = await _x.x.cache.save(res.text, this.options.ttl);
24
+ return {
25
+ text: res.text,
26
+ svg: res.data,
27
+ token: token
28
+ };
29
+ }
30
+
31
+ async verify(options) {
32
+ var _options$text;
33
+
34
+ if (((_options$text = options.text) == null ? void 0 : _options$text.length) !== this.options.size) {
35
+ return false;
36
+ }
37
+
38
+ const expectedText = await _x.x.cache.get(options.token);
39
+ await _x.x.cache.remove(options.token);
40
+ return options.text === expectedText;
41
+ }
42
+
43
+ }
44
+
45
+ exports.CaptchaService = CaptchaService;
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
5
+ exports.__esModule = true;
6
+ exports.DisposeService = void 0;
7
+
8
+ var _exitHook = _interopRequireDefault(require("exit-hook"));
9
+
10
+ class DisposeService {
11
+ constructor(options) {
12
+ var _this$options;
13
+
14
+ this.options = options;
15
+ this.serviceName = 'dispose';
16
+ this.disposes = [];
17
+
18
+ if ((_this$options = this.options) != null && _this$options.disposeOnExit) {
19
+ (0, _exitHook.default)(() => this.dispose());
20
+ }
21
+ }
22
+
23
+ add(fn) {
24
+ this.disposes.push(fn);
25
+ }
26
+
27
+ dispose() {
28
+ return Promise.all(this.disposes.map(dispose => dispose()));
29
+ }
30
+
31
+ }
32
+
33
+ exports.DisposeService = DisposeService;
@@ -0,0 +1,59 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
5
+ exports.__esModule = true;
6
+ exports.JwtService = void 0;
7
+
8
+ var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));
9
+
10
+ var _http_error = require("../core/http_error");
11
+
12
+ var _date = require("vtils/date");
13
+
14
+ class JwtService {
15
+ constructor(options) {
16
+ this.options = options;
17
+ this.serviceName = 'jwt';
18
+ }
19
+
20
+ sign(payload) {
21
+ return _jsonwebtoken.default.sign(payload, this.options.secret, {
22
+ expiresIn: (0, _date.ms)(this.options.ttl, true)
23
+ });
24
+ }
25
+
26
+ async verify(token) {
27
+ return new Promise((resolve, reject) => {
28
+ _jsonwebtoken.default.verify(token, this.options.secret, {
29
+ ignoreExpiration: false
30
+ }, (err, data) => {
31
+ if (err) {
32
+ console.log(err);
33
+ reject(new _http_error.HttpError.Unauthorized());
34
+ } else {
35
+ resolve(data);
36
+ }
37
+ });
38
+ });
39
+ }
40
+
41
+ async verifyFromHttpHeaders(headers) {
42
+ const authorization = headers.authorization || headers['sec-websocket-protocol'] && `Bearer ${headers['sec-websocket-protocol']}` || '';
43
+
44
+ if (!authorization) {
45
+ throw new _http_error.HttpError.Unauthorized();
46
+ }
47
+
48
+ const [scheme, token] = authorization.split(' ');
49
+
50
+ if (scheme.toLowerCase() !== 'bearer') {
51
+ throw new _http_error.HttpError.Unauthorized();
52
+ }
53
+
54
+ return this.verify(token);
55
+ }
56
+
57
+ }
58
+
59
+ exports.JwtService = JwtService;
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
4
+
5
+ exports.__esModule = true;
6
+ exports.RedisService = void 0;
7
+
8
+ var _ioredis = _interopRequireDefault(require("ioredis"));
9
+
10
+ class RedisService extends _ioredis.default {
11
+ constructor(...args) {
12
+ super(...args);
13
+ this.serviceName = 'redis';
14
+ }
15
+
16
+ }
17
+
18
+ exports.RedisService = RedisService;
package/lib/_cjs/x.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
4
+ exports.x = void 0;
5
+
6
+ var _dispose = require("./services/dispose");
7
+
8
+ const x = {
9
+ appName: process.env.APP_NAME,
10
+ register: (...services) => {
11
+ for (const service of services) {
12
+ // @ts-ignore
13
+ x[service.serviceName] = service;
14
+ }
15
+ }
16
+ };
17
+ exports.x = x;
18
+ x.register(new _dispose.DisposeService({
19
+ disposeOnExit: true
20
+ }));