onebots 0.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 (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -0
  3. package/lib/bin.d.ts +2 -0
  4. package/lib/bin.js +5 -0
  5. package/lib/config.sample.yaml +31 -0
  6. package/lib/db.d.ts +19 -0
  7. package/lib/db.js +91 -0
  8. package/lib/index.d.ts +5 -0
  9. package/lib/index.js +21 -0
  10. package/lib/onebot.d.ts +43 -0
  11. package/lib/onebot.js +85 -0
  12. package/lib/server/app.d.ts +52 -0
  13. package/lib/server/app.js +232 -0
  14. package/lib/server/router.d.ts +9 -0
  15. package/lib/server/router.js +32 -0
  16. package/lib/service/V11/action/common.d.ts +64 -0
  17. package/lib/service/V11/action/common.js +115 -0
  18. package/lib/service/V11/action/friend.d.ts +38 -0
  19. package/lib/service/V11/action/friend.js +44 -0
  20. package/lib/service/V11/action/group.d.ts +104 -0
  21. package/lib/service/V11/action/group.js +138 -0
  22. package/lib/service/V11/action/index.d.ts +9 -0
  23. package/lib/service/V11/action/index.js +10 -0
  24. package/lib/service/V11/config.d.ts +10 -0
  25. package/lib/service/V11/config.js +2 -0
  26. package/lib/service/V11/index.d.ts +95 -0
  27. package/lib/service/V11/index.js +481 -0
  28. package/lib/service/V12/action/common.d.ts +32 -0
  29. package/lib/service/V12/action/common.js +105 -0
  30. package/lib/service/V12/action/friend.d.ts +13 -0
  31. package/lib/service/V12/action/friend.js +15 -0
  32. package/lib/service/V12/action/group.d.ts +104 -0
  33. package/lib/service/V12/action/group.js +138 -0
  34. package/lib/service/V12/action/guild.d.ts +2 -0
  35. package/lib/service/V12/action/guild.js +6 -0
  36. package/lib/service/V12/action/index.d.ts +10 -0
  37. package/lib/service/V12/action/index.js +11 -0
  38. package/lib/service/V12/config.d.ts +17 -0
  39. package/lib/service/V12/config.js +2 -0
  40. package/lib/service/V12/index.d.ts +102 -0
  41. package/lib/service/V12/index.js +530 -0
  42. package/lib/types.d.ts +3 -0
  43. package/lib/types.js +2 -0
  44. package/lib/utils.d.ts +13 -0
  45. package/lib/utils.js +139 -0
  46. package/package.json +58 -0
@@ -0,0 +1,530 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.V12 = void 0;
7
+ const path_1 = require("path");
8
+ const onebot_1 = require("../../onebot");
9
+ const action_1 = require("./action");
10
+ const events_1 = require("events");
11
+ const url_1 = require("url");
12
+ const http_1 = __importDefault(require("http"));
13
+ const https_1 = __importDefault(require("https"));
14
+ const ws_1 = require("ws");
15
+ const icqq_cq_enable_1 = require("icqq-cq-enable");
16
+ const utils_1 = require("../../utils");
17
+ const db_1 = require("../../db");
18
+ const app_1 = require("../../server/app");
19
+ class V12 extends events_1.EventEmitter {
20
+ constructor(oneBot, client, config) {
21
+ super();
22
+ this.oneBot = oneBot;
23
+ this.client = client;
24
+ this.config = config;
25
+ this.version = 'V12';
26
+ this.timestamp = Date.now();
27
+ this.wsr = new Set();
28
+ this.db = new db_1.Db((0, path_1.join)(app_1.App.configDir, 'data', this.client.uin + '.json'));
29
+ if (!this.history)
30
+ this.db.set('eventBuffer', []);
31
+ this.action = new action_1.Action();
32
+ this.logger = this.oneBot.app.getLogger(this.client.uin, this.version);
33
+ }
34
+ get history() {
35
+ return this.db.get('eventBuffer');
36
+ }
37
+ start(path) {
38
+ this.path = `/${this.client.uin}`;
39
+ if (path)
40
+ this.path += path;
41
+ if (this.config.use_http) {
42
+ const config = typeof this.config.use_http === 'boolean' ? {} : this.config.use_http || {};
43
+ this.startHttp({
44
+ access_token: this.config.access_token,
45
+ event_enabled: true,
46
+ event_buffer_size: 50,
47
+ ...config
48
+ });
49
+ }
50
+ if (this.config.use_ws) {
51
+ const config = typeof this.config.use_ws === 'boolean' ? {} : this.config.use_ws || {};
52
+ this.startWs({
53
+ access_token: this.config.access_token,
54
+ ...config
55
+ });
56
+ }
57
+ this.config.webhook.forEach(config => {
58
+ if (typeof config === 'string') {
59
+ config = {
60
+ url: config,
61
+ access_token: this.config.access_token,
62
+ };
63
+ }
64
+ else {
65
+ config = {
66
+ access_token: this.config.access_token,
67
+ ...config
68
+ };
69
+ }
70
+ this.startWebhook(config);
71
+ });
72
+ this.config.ws_reverse.forEach(config => {
73
+ if (typeof config === 'string') {
74
+ config = {
75
+ url: config,
76
+ access_token: this.config.access_token,
77
+ };
78
+ }
79
+ else {
80
+ config = {
81
+ access_token: this.config.access_token,
82
+ ...config
83
+ };
84
+ }
85
+ this.startWsReverse(config);
86
+ });
87
+ if (this.config.heartbeat) {
88
+ this.heartbeat = setInterval(() => {
89
+ this.dispatch({
90
+ self_id: this.client.uin,
91
+ time: Math.floor(Date.now() / 1000),
92
+ type: "meta",
93
+ detail_type: "heartbeat",
94
+ interval: this.config.heartbeat * 1000,
95
+ status: this.action.getStatus.apply(this)
96
+ });
97
+ }, this.config.heartbeat * 1000);
98
+ }
99
+ }
100
+ startHttp(config) {
101
+ this.oneBot.app.router.all(new RegExp(`^${this.path}/(.*)$`), (ctx) => this._httpRequestHandler(ctx, config));
102
+ this.logger.mark(`开启http服务器成功,监听:http://127.0.0.1:${this.oneBot.app.config.port}${this.path}`);
103
+ this.on('dispatch', (payload) => {
104
+ if (!['message', 'notice', 'request', 'system'].includes(payload.type))
105
+ return;
106
+ if (config.event_enabled) {
107
+ this.history.push(payload);
108
+ if (config.event_buffer_size !== 0 && this.history.length > config.event_buffer_size)
109
+ this.history.shift();
110
+ }
111
+ });
112
+ }
113
+ startWebhook(config) {
114
+ this.on('dispatch', (unserialized) => {
115
+ const serialized = JSON.stringify(unserialized);
116
+ const options = {
117
+ method: "POST",
118
+ timeout: this.config.request_timeout * 1000,
119
+ headers: {
120
+ "Content-Type": "application/json",
121
+ "Content-Length": Buffer.byteLength(serialized),
122
+ "X-Self-ID": String(this.client.uin),
123
+ "User-Agent": "OneBot",
124
+ },
125
+ };
126
+ const protocol = config.url.startsWith("https") ? https_1.default : http_1.default;
127
+ try {
128
+ protocol.request(config.url, options, (res) => {
129
+ if (res.statusCode !== 200)
130
+ return this.logger.warn(`POST(${config.url})上报事件收到非200响应:` + res.statusCode);
131
+ let data = "";
132
+ res.setEncoding("utf-8");
133
+ res.on("data", (chunk) => data += chunk);
134
+ res.on("end", () => {
135
+ this.logger.debug(`收到HTTP响应 ${res.statusCode} :` + data);
136
+ if (!data)
137
+ return;
138
+ try {
139
+ this._quickOperate(unserialized, JSON.parse(data));
140
+ }
141
+ catch (e) {
142
+ this.logger.error(`快速操作遇到错误:` + e.message);
143
+ }
144
+ });
145
+ }).on("error", (err) => {
146
+ this.logger.error(`POST(${config.url})上报事件失败:` + err.message);
147
+ }).end(serialized, () => {
148
+ this.logger.debug(`POST(${config.url})上报事件成功: ` + serialized);
149
+ });
150
+ }
151
+ catch (e) {
152
+ this.logger.error(`POST(${config.url})上报失败:` + e.message);
153
+ }
154
+ });
155
+ }
156
+ startWs(config) {
157
+ this.wss = this.oneBot.app.router.ws(this.path, this.oneBot.app.httpServer);
158
+ this.logger.mark(`开启ws服务器成功,监听:ws://127.0.0.1:${this.oneBot.app.config.port}${this.path}`);
159
+ this.wss.on("error", (err) => {
160
+ this.logger.error(err.message);
161
+ });
162
+ this.wss.on("connection", (ws, req) => {
163
+ this.logger.info(`ws客户端(${req.headers.origin})已连接`);
164
+ ws.on("error", (err) => {
165
+ this.logger.error(`ws客户端(${req.headers.origin})报错:${err.message}`);
166
+ });
167
+ ws.on("close", (code, reason) => {
168
+ this.logger.warn(`ws客户端(${req.headers.origin})连接关闭,关闭码${code},关闭理由:` + reason);
169
+ });
170
+ if (config.access_token) {
171
+ const url = new url_1.URL(req.url, "http://127.0.0.1");
172
+ const token = url.searchParams.get('access_token');
173
+ if (token)
174
+ req.headers["authorization"] = `Bearer ${token}`;
175
+ if (!req.headers["authorization"] || req.headers["authorization"] !== `Bearer ${config.access_token}`)
176
+ return ws.close(1002, "wrong access token");
177
+ }
178
+ this._webSocketHandler(ws);
179
+ });
180
+ this.on('dispatch', (unserialized) => {
181
+ const serialized = JSON.stringify(unserialized);
182
+ for (const ws of this.wss.clients) {
183
+ ws.send(serialized, (err) => {
184
+ if (err)
185
+ this.logger.error(`正向WS(${ws.url})上报事件失败: ` + err.message);
186
+ else
187
+ this.logger.debug(`正向WS(${ws.url})上报事件成功: ` + serialized);
188
+ });
189
+ }
190
+ });
191
+ }
192
+ startWsReverse(config) {
193
+ const ws = this._createWsr(config.url, config);
194
+ this.on('dispatch', (unserialized) => {
195
+ if (this.wsr.has(ws)) {
196
+ ws.send(JSON.stringify(unserialized));
197
+ }
198
+ });
199
+ }
200
+ stop() {
201
+ return this.client.logout();
202
+ }
203
+ dispatch(data = {}) {
204
+ if (!data)
205
+ data = {};
206
+ if (!data.post_type) {
207
+ // @ts-ignore
208
+ data.sub_type = 'online';
209
+ if (data.image) {
210
+ // @ts-ignore
211
+ data.system_type = 'login';
212
+ // @ts-ignore
213
+ data.sub_type = 'qrcode';
214
+ }
215
+ else if (data.url) {
216
+ // @ts-ignore
217
+ data.system_type = 'login';
218
+ // @ts-ignore
219
+ data.sub_type = 'slider';
220
+ if (data.phone) {
221
+ // @ts-ignore
222
+ data.sub_type = 'device';
223
+ }
224
+ }
225
+ else if (data.message) {
226
+ // @ts-ignore
227
+ data.system_type = 'login';
228
+ // @ts-ignore
229
+ data.sub_type = 'error';
230
+ }
231
+ }
232
+ const payload = {
233
+ id: (0, utils_1.uuid)(),
234
+ impl: 'icqq_onebot',
235
+ platform: 'qq',
236
+ self_id: `${this.client.uin}`,
237
+ type: data.post_type || 'meta',
238
+ detail_type: data.message_type || data.notice_type || data.request_type || data.system_type,
239
+ ...data,
240
+ };
241
+ if (payload.type === 'notice') {
242
+ switch (payload.detail_type) {
243
+ case 'friend':
244
+ payload.detail_type += payload.sub_type;
245
+ break;
246
+ case 'group':
247
+ if (['increase', 'decrease'].includes(payload.sub_type))
248
+ payload.detail_type = 'group_member_' + payload.sub_type;
249
+ else if (payload.sub_type === 'recall')
250
+ payload.detail_type = 'group_message_delete';
251
+ }
252
+ }
253
+ this.emit('dispatch', payload);
254
+ }
255
+ async apply(req) {
256
+ let { action, params, echo } = req;
257
+ action = (0, utils_1.toLine)(action);
258
+ let is_async = action.includes("_async");
259
+ if (is_async)
260
+ action = action.replace("_async", "");
261
+ if (action === 'send_msg') {
262
+ if (["private", "group", "discuss", 'channel'].includes(params.detail_type)) {
263
+ action = "send_" + params.detail_type + "_msg";
264
+ }
265
+ else if (params.user_id)
266
+ action = "send_private_msg";
267
+ else if (params.group_id)
268
+ action = "send_group_msg";
269
+ else if (params.discuss_id)
270
+ action = "send_discuss_msg";
271
+ else if (params.channel_id && params.guild_id)
272
+ action = "send_guild_msg";
273
+ else
274
+ throw new Error('required detail_type or input (user_id/group_id/(guild_id and channel_id))');
275
+ }
276
+ const method = (0, utils_1.toHump)(action);
277
+ if (Reflect.has(this.action, method)) {
278
+ const ARGS = String(Reflect.get(this.action, method)).match(/\(.*\)/)?.[0]
279
+ .replace("(", "")
280
+ .replace(")", "")
281
+ .split(",")
282
+ .filter(Boolean).map(v => v.replace(/=.+/, "").trim());
283
+ const args = [];
284
+ for (let k of ARGS) {
285
+ if (Reflect.has(params, k)) {
286
+ if (onebot_1.BOOLS.includes(k))
287
+ params[k] = (0, utils_1.toBool)(params[k]);
288
+ if (k === 'message') {
289
+ if (typeof params[k] === 'string') {
290
+ params[k] = (0, icqq_cq_enable_1.fromCqcode)(params[k]);
291
+ }
292
+ else {
293
+ params[k] = (0, icqq_cq_enable_1.fromSegment)(params[k]);
294
+ }
295
+ }
296
+ args.push(params[k]);
297
+ }
298
+ }
299
+ let ret, result;
300
+ try {
301
+ ret = this.action[method].apply(this, args);
302
+ }
303
+ catch (e) {
304
+ return JSON.stringify(V12.error(e.message));
305
+ }
306
+ if (ret instanceof Promise) {
307
+ if (is_async) {
308
+ result = V12.success(null, 0);
309
+ }
310
+ else {
311
+ result = V12.success(await ret, 0);
312
+ }
313
+ }
314
+ else {
315
+ result = V12.success(await ret, 0);
316
+ }
317
+ if (result.data instanceof Map)
318
+ result.data = [...result.data.values()];
319
+ if (echo) {
320
+ result.echo = echo;
321
+ }
322
+ return JSON.stringify(result);
323
+ }
324
+ else
325
+ throw new onebot_1.NotFoundError();
326
+ }
327
+ async _httpRequestHandler(ctx, config) {
328
+ if (ctx.method === 'OPTIONS') {
329
+ return ctx.writeHead(200, {
330
+ 'Access-Control-Allow-Origin': '*',
331
+ 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
332
+ 'Access-Control-Allow-Headers': 'Content-Type, authorization'
333
+ }).end();
334
+ }
335
+ const url = new url_1.URL(ctx.url, `http://127.0.0.1`);
336
+ if (config.access_token) {
337
+ if (ctx.headers["authorization"]) {
338
+ if (ctx.headers["authorization"] !== `Bearer ${config.access_token}`)
339
+ return ctx.res.writeHead(403).end();
340
+ }
341
+ else {
342
+ const access_token = url.searchParams.get("access_token");
343
+ if (!access_token)
344
+ return ctx.res.writeHead(401).end();
345
+ else if (access_token !== this.config.access_token)
346
+ return ctx.res.writeHead(403).end();
347
+ }
348
+ }
349
+ ctx.res.setHeader("Content-Type", "application/json; charset=utf-8");
350
+ if (this.config.enable_cors)
351
+ ctx.res.setHeader("Access-Control-Allow-Origin", "*");
352
+ const action = url.pathname.replace(`${this.path}`, '').slice(1);
353
+ if (ctx.method === "GET") {
354
+ try {
355
+ const ret = await this.apply({ action, params: ctx.query });
356
+ ctx.res.writeHead(200).end(ret);
357
+ }
358
+ catch (e) {
359
+ ctx.res.writeHead(500).end(e.message);
360
+ }
361
+ }
362
+ else if (ctx.method === "POST") {
363
+ try {
364
+ const params = { ...ctx.query, ...ctx.request.body };
365
+ const ret = await this.apply({ action, params });
366
+ ctx.res.writeHead(200).end(ret);
367
+ }
368
+ catch (e) {
369
+ ctx.res.writeHead(500).end(e.message);
370
+ }
371
+ }
372
+ else {
373
+ ctx.res.writeHead(405).end();
374
+ }
375
+ }
376
+ /**
377
+ * 快速操作
378
+ */
379
+ _quickOperate(event, res) {
380
+ if (event.type === "message") {
381
+ if (res.reply) {
382
+ if (event.detail_type === "discuss")
383
+ return;
384
+ const action = event.detail_type === "private" ? "sendPrivateMsg" : "sendGroupMsg";
385
+ const id = event.detail_type === "private" ? event.user_id : event.group_id;
386
+ this.client[action](id, res.reply, res.auto_escape);
387
+ }
388
+ if (event.detail_type === "group") {
389
+ if (res.delete)
390
+ this.client.deleteMsg(event.message_id);
391
+ if (res.kick && !event.anonymous)
392
+ this.client.setGroupKick(event.group_id, event.user_id, res.reject_add_request);
393
+ if (res.ban)
394
+ this.client.setGroupBan(event.group_id, event.user_id, res.ban_duration > 0 ? res.ban_duration : 1800);
395
+ }
396
+ }
397
+ if (event.type === "request" && "approve" in res) {
398
+ const action = event.detail_type === "friend" ? "setFriendAddRequest" : "setGroupAddRequest";
399
+ this.client[action](event.flag, res.approve, res.reason ? res.reason : "", !!res.block);
400
+ }
401
+ }
402
+ /**
403
+ * 创建反向ws
404
+ */
405
+ _createWsr(url, config) {
406
+ const timestmap = Date.now();
407
+ const headers = {
408
+ "X-Self-ID": String(this.client.uin),
409
+ "X-Client-Role": "Universal",
410
+ "User-Agent": "OneBot",
411
+ };
412
+ if (config.access_token)
413
+ headers.Authorization = "Bearer " + config.access_token;
414
+ const ws = new ws_1.WebSocket(url, { headers });
415
+ ws.on("error", (err) => {
416
+ this.logger.error(err.message);
417
+ });
418
+ ws.on("open", () => {
419
+ this.logger.info(`反向ws(${url})连接成功。`);
420
+ this.wsr.add(ws);
421
+ this._webSocketHandler(ws);
422
+ });
423
+ ws.on("close", (code) => {
424
+ this.wsr.delete(ws);
425
+ if (timestmap < this.timestamp)
426
+ return;
427
+ this.logger.warn(`反向ws(${url})被关闭,关闭码${code},将在${this.config.reconnect_interval}秒后尝试重连。`);
428
+ setTimeout(() => {
429
+ if (timestmap < this.timestamp)
430
+ return;
431
+ this._createWsr(url, config);
432
+ }, this.config.reconnect_interval * 1000);
433
+ });
434
+ return ws;
435
+ }
436
+ /**
437
+ * 处理ws消息
438
+ */
439
+ _webSocketHandler(ws) {
440
+ ws.on("message", async (msg) => {
441
+ this.logger.debug(" 收到ws消息:" + msg);
442
+ var data;
443
+ try {
444
+ data = JSON.parse(String(msg));
445
+ let ret;
446
+ if (data.action.startsWith(".handle_quick_operation")) {
447
+ const event = data.params.context, res = data.params.operation;
448
+ this._quickOperate(event, res);
449
+ ret = JSON.stringify({
450
+ retcode: 0,
451
+ status: "ok",
452
+ data: null,
453
+ message: null,
454
+ echo: data.echo
455
+ });
456
+ }
457
+ else {
458
+ ret = await this.apply(data);
459
+ }
460
+ ws.send(ret);
461
+ }
462
+ catch (e) {
463
+ let code, message;
464
+ if (e instanceof onebot_1.NotFoundError) {
465
+ code = 10002;
466
+ message = "不支持的api";
467
+ }
468
+ else {
469
+ code = 10003;
470
+ message = "请求格式错误";
471
+ }
472
+ ws.send(JSON.stringify({
473
+ retcode: code,
474
+ status: "failed",
475
+ data: null,
476
+ error: {
477
+ code, message
478
+ },
479
+ echo: data?.echo
480
+ }));
481
+ }
482
+ });
483
+ this.dispatch(V12.genMetaEvent(this.client.uin, "connect"));
484
+ this.dispatch(V12.genMetaEvent(this.client.uin, "enable"));
485
+ }
486
+ }
487
+ exports.V12 = V12;
488
+ (function (V12) {
489
+ V12.defaultConfig = {
490
+ heartbeat: 3,
491
+ access_token: '',
492
+ request_timeout: 15,
493
+ reconnect_interval: 3,
494
+ enable_cors: true,
495
+ use_http: true,
496
+ use_ws: true,
497
+ webhook: [],
498
+ ws_reverse: []
499
+ };
500
+ function success(data, retcode = 0, echo) {
501
+ return {
502
+ retcode,
503
+ status: retcode === 0 ? 'ok' : 'failed',
504
+ data,
505
+ message: '',
506
+ echo
507
+ };
508
+ }
509
+ V12.success = success;
510
+ function error(message, retcode = 10001, echo) {
511
+ return {
512
+ retcode,
513
+ status: 'failed',
514
+ data: null,
515
+ message,
516
+ echo
517
+ };
518
+ }
519
+ V12.error = error;
520
+ function genMetaEvent(uin, type) {
521
+ return {
522
+ self_id: uin,
523
+ time: Math.floor(Date.now() / 1000),
524
+ type: "meta",
525
+ detail_type: "lifecycle",
526
+ sub_type: type,
527
+ };
528
+ }
529
+ V12.genMetaEvent = genMetaEvent;
530
+ })(V12 = exports.V12 || (exports.V12 = {}));
package/lib/types.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export declare type LogLevel = "trace" | "debug" | "info" | "warn" | "error" | "fatal" | "mark" | "off";
2
+ export declare type Dispose = () => any;
3
+ export declare type MayBeArray<T extends any> = T | T[];
package/lib/types.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/lib/utils.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ export declare function deepMerge<T extends any>(base: T, ...from: T[]): T;
2
+ export declare function deepClone<T extends any>(obj: T): T;
3
+ export declare function pick<T, K extends keyof T>(source: T, keys?: Iterable<K>, forced?: boolean): Pick<T, K>;
4
+ export declare function omit<T, K extends keyof T>(source: T, keys?: Iterable<K>): Omit<T, K>;
5
+ export interface Class {
6
+ new (...args: any[]): any;
7
+ }
8
+ export declare function Mixin(base: Class, ...classes: Class[]): Class;
9
+ export declare function toHump(action: string): string;
10
+ export declare function toLine(name: string): string;
11
+ export declare function toBool(v: any): boolean;
12
+ export declare function uuid(): string;
13
+ export declare function getProperties(obj: any): any;
package/lib/utils.js ADDED
@@ -0,0 +1,139 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.getProperties = exports.uuid = exports.toBool = exports.toLine = exports.toHump = exports.Mixin = exports.omit = exports.pick = exports.deepClone = exports.deepMerge = void 0;
27
+ // 合并对象/数组
28
+ const crypto = __importStar(require("crypto"));
29
+ function deepMerge(base, ...from) {
30
+ if (from.length === 0) {
31
+ return base;
32
+ }
33
+ if (typeof base !== 'object') {
34
+ return base;
35
+ }
36
+ if (Array.isArray(base)) {
37
+ return base.concat(...from);
38
+ }
39
+ for (const item of from) {
40
+ for (const key in item) {
41
+ if (base.hasOwnProperty(key)) {
42
+ if (typeof base[key] === 'object') {
43
+ base[key] = deepMerge(base[key], item[key]);
44
+ }
45
+ else {
46
+ base[key] = item[key];
47
+ }
48
+ }
49
+ else {
50
+ base[key] = item[key];
51
+ }
52
+ }
53
+ }
54
+ return base;
55
+ }
56
+ exports.deepMerge = deepMerge;
57
+ // 深拷贝
58
+ function deepClone(obj) {
59
+ if (typeof obj !== 'object')
60
+ return obj;
61
+ if (!obj)
62
+ return obj;
63
+ //判断拷贝的obj是对象还是数组
64
+ if (Array.isArray(obj))
65
+ return obj.map((item) => deepClone(item));
66
+ const objClone = {};
67
+ for (const key in obj) {
68
+ if (obj.hasOwnProperty(key)) {
69
+ if (obj[key] && typeof obj[key] === "object") {
70
+ objClone[key] = deepClone(obj[key]);
71
+ }
72
+ else {
73
+ objClone[key] = obj[key];
74
+ }
75
+ }
76
+ }
77
+ return objClone;
78
+ }
79
+ exports.deepClone = deepClone;
80
+ function pick(source, keys, forced) {
81
+ if (!keys)
82
+ return { ...source };
83
+ const result = {};
84
+ for (const key of keys) {
85
+ if (forced || key in source)
86
+ result[key] = source[key];
87
+ }
88
+ return result;
89
+ }
90
+ exports.pick = pick;
91
+ function omit(source, keys) {
92
+ if (!keys)
93
+ return { ...source };
94
+ const result = { ...source };
95
+ for (const key of keys) {
96
+ Reflect.deleteProperty(result, key);
97
+ }
98
+ return result;
99
+ }
100
+ exports.omit = omit;
101
+ function Mixin(base, ...classes) {
102
+ classes.forEach(ctr => {
103
+ Object.getOwnPropertyNames(ctr.prototype).forEach(name => {
104
+ if (name === 'constructor')
105
+ return;
106
+ base.prototype[name] = ctr.prototype[name];
107
+ });
108
+ });
109
+ return base;
110
+ }
111
+ exports.Mixin = Mixin;
112
+ function toHump(action) {
113
+ return action.replace(/_[\w]/g, (s) => {
114
+ return s[1].toUpperCase();
115
+ });
116
+ }
117
+ exports.toHump = toHump;
118
+ function toLine(name) {
119
+ return name.replace(/([A-Z])/g, "_$1").toLowerCase();
120
+ }
121
+ exports.toLine = toLine;
122
+ function toBool(v) {
123
+ if (v === "0" || v === "false")
124
+ v = false;
125
+ return Boolean(v);
126
+ }
127
+ exports.toBool = toBool;
128
+ function uuid() {
129
+ let hex = crypto.randomBytes(16).toString("hex");
130
+ return hex.substr(0, 8) + "-" + hex.substr(8, 4) + "-" + hex.substr(12, 4) + "-" + hex.substr(16, 4) + "-" + hex.substr(20);
131
+ }
132
+ exports.uuid = uuid;
133
+ function getProperties(obj) {
134
+ if (obj.__proto__ === null) { //说明该对象已经是最顶层的对象
135
+ return [];
136
+ }
137
+ return Object.getOwnPropertyNames(obj).concat(getProperties(obj.__proto__));
138
+ }
139
+ exports.getProperties = getProperties;