node-karin 0.11.14 → 0.12.0
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.
- package/config/defSet/config.yaml +3 -3
- package/lib/adapter/input/index.d.ts +1 -1
- package/lib/adapter/input/index.js +1 -1
- package/lib/adapter/onebot/11/index.d.ts +1 -1
- package/lib/adapter/onebot/11/index.js +1 -1
- package/lib/cli/index.d.ts +7 -3
- package/lib/cli/index.js +38 -10
- package/lib/cli/init.js +2 -1
- package/lib/cli/pkg.d.ts +4 -0
- package/lib/cli/pkg.js +14 -0
- package/lib/core/init/config.d.ts +0 -4
- package/lib/core/init/config.js +0 -13
- package/lib/core/karin/karin.d.ts +19 -3
- package/lib/core/karin/karin.js +26 -15
- package/lib/core/listener/listener.js +1 -1
- package/lib/core/process/process.js +1 -5
- package/lib/render/client.d.ts +11 -0
- package/lib/render/client.js +91 -11
- package/lib/types/adapter/base.d.ts +1 -1
- package/lib/types/config/config.d.ts +2 -2
- package/lib/types/logger/logger.d.ts +1 -1
- package/lib/utils/common/common.js +8 -3
- package/lib/utils/index.d.ts +2 -0
- package/lib/utils/index.js +2 -0
- package/lib/utils/tools/exec.d.ts +5 -17
- package/lib/utils/tools/exec.js +28 -26
- package/lib/utils/tools/ffmpeg.d.ts +2 -2
- package/lib/utils/tools/restart.d.ts +15 -0
- package/lib/utils/tools/restart.js +39 -0
- package/lib/utils/tools/stop.d.ts +7 -0
- package/lib/utils/tools/stop.js +13 -0
- package/lib/utils/tools/update.d.ts +26 -84
- package/lib/utils/tools/update.js +40 -28
- package/package.json +9 -3
- package/lib/render/client_even.d.ts +0 -30
- package/lib/render/client_even.js +0 -156
|
@@ -11,12 +11,12 @@ log4jsCfg:
|
|
|
11
11
|
# 日志文件最大大小 MB
|
|
12
12
|
maxLogSize: 30
|
|
13
13
|
|
|
14
|
-
# 关闭后台进程失败后是否继续启动 继续启动会导致多进程
|
|
15
|
-
multi_progress: false
|
|
16
|
-
|
|
17
14
|
# 控制台触发插件日志颜色 十六进制 默认#FFFF00 不支持热更新
|
|
18
15
|
log_color: "#E1D919"
|
|
19
16
|
|
|
17
|
+
# 重启是否调用pm2 如果不调用则会直接关机 此配置适合有进程守护的程序
|
|
18
|
+
pm2Restart: true
|
|
19
|
+
|
|
20
20
|
# 私聊设置
|
|
21
21
|
private:
|
|
22
22
|
# 关闭私聊后回复的提示词 为空则不回复
|
|
@@ -148,7 +148,7 @@ export class AdapterInput {
|
|
|
148
148
|
getAvatarUrl() {
|
|
149
149
|
return 'https://p.qlogo.cn/gh/967068507/967068507/0';
|
|
150
150
|
}
|
|
151
|
-
|
|
151
|
+
getGroupAvatarUrl() {
|
|
152
152
|
return 'https://p.qlogo.cn/gh/967068507/967068507/0';
|
|
153
153
|
}
|
|
154
154
|
async GetCurrentAccount() {
|
|
@@ -60,7 +60,7 @@ export declare class AdapterOneBot11 implements KarinAdapter {
|
|
|
60
60
|
* @param history - 历史头像记录,默认`0`,若要获取历史群头像则填写1,2,3...
|
|
61
61
|
* @returns - 群头像的url地址
|
|
62
62
|
*/
|
|
63
|
-
|
|
63
|
+
getGroupAvatarUrl(group_id: string, size?: number, history?: number): string;
|
|
64
64
|
/**
|
|
65
65
|
* 发送消息
|
|
66
66
|
*
|
|
@@ -161,7 +161,7 @@ export class AdapterOneBot11 {
|
|
|
161
161
|
* @param history - 历史头像记录,默认`0`,若要获取历史群头像则填写1,2,3...
|
|
162
162
|
* @returns - 群头像的url地址
|
|
163
163
|
*/
|
|
164
|
-
|
|
164
|
+
getGroupAvatarUrl(group_id, size = 0, history = 0) {
|
|
165
165
|
return `https://p.qlogo.cn/gh/${group_id}/${group_id}${history ? '_' + history : ''}/` + size;
|
|
166
166
|
}
|
|
167
167
|
/**
|
package/lib/cli/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ChildProcess } from 'child_process';
|
|
1
|
+
import { ChildProcess, ExecOptions } from 'child_process';
|
|
2
2
|
export declare const enum Runner {
|
|
3
3
|
Node = "node",
|
|
4
4
|
Tsx = "tsx",
|
|
@@ -19,7 +19,7 @@ export declare class KarinCli {
|
|
|
19
19
|
file: string;
|
|
20
20
|
constructor();
|
|
21
21
|
/**
|
|
22
|
-
* 获取pkg
|
|
22
|
+
* 获取pkg配置
|
|
23
23
|
* @param isNpm - 是否是npm包
|
|
24
24
|
*/
|
|
25
25
|
pkg(isNpm: boolean): any;
|
|
@@ -73,11 +73,15 @@ export declare class KarinCli {
|
|
|
73
73
|
* @param pkg - 包管理器
|
|
74
74
|
*/
|
|
75
75
|
getRemoteVersion(name: string, pkg: 'pnpm' | 'cnpm' | 'yarn' | 'npm'): Promise<string>;
|
|
76
|
+
/**
|
|
77
|
+
* 获取git插件列表
|
|
78
|
+
*/
|
|
79
|
+
getGitPlugins(): Array<string>;
|
|
76
80
|
/**
|
|
77
81
|
* 封装exec
|
|
78
82
|
* @param cmd - 命令
|
|
79
83
|
*/
|
|
80
|
-
exec(cmd: string): Promise<string>;
|
|
84
|
+
exec(cmd: string, options?: ExecOptions): Promise<string>;
|
|
81
85
|
/**
|
|
82
86
|
* 封装axios 超时返回false
|
|
83
87
|
* @param url - 请求地址
|
package/lib/cli/index.js
CHANGED
|
@@ -3,8 +3,8 @@ import path from 'path';
|
|
|
3
3
|
import yaml from 'yaml';
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
|
+
import { getRegistry } from './pkg.js';
|
|
6
7
|
import { exec as execCmd, spawn } from 'child_process';
|
|
7
|
-
import { KarinCfgInit } from '../core/init/config.js';
|
|
8
8
|
export class KarinCli {
|
|
9
9
|
child;
|
|
10
10
|
filename;
|
|
@@ -20,10 +20,11 @@ export class KarinCli {
|
|
|
20
20
|
/** 入口文件(注意后缀) */
|
|
21
21
|
this.file = path.join(path.dirname(this.filename), '../index.js');
|
|
22
22
|
this.child = null;
|
|
23
|
+
process.env.karin_app_pkg = getRegistry();
|
|
23
24
|
process.env.karin_app_version = this.pkg(true).version;
|
|
24
25
|
}
|
|
25
26
|
/**
|
|
26
|
-
* 获取pkg
|
|
27
|
+
* 获取pkg配置
|
|
27
28
|
* @param isNpm - 是否是npm包
|
|
28
29
|
*/
|
|
29
30
|
pkg(isNpm) {
|
|
@@ -187,9 +188,8 @@ export class KarinCli {
|
|
|
187
188
|
];
|
|
188
189
|
const list = Object.keys(this.pkg(false).dependencies).filter(key => !pkgdependencies.includes(key));
|
|
189
190
|
/** 获取包管理器 */
|
|
190
|
-
const pkg =
|
|
191
|
+
const pkg = getRegistry();
|
|
191
192
|
const cmd = pkg === 'yarn' ? 'yarn upgrade' : `${pkg} update`;
|
|
192
|
-
/** 异步并发更新依赖 */
|
|
193
193
|
await Promise.all(list.map(async (item) => {
|
|
194
194
|
try {
|
|
195
195
|
/** 检查是否已经是最新版本 */
|
|
@@ -205,11 +205,26 @@ export class KarinCli {
|
|
|
205
205
|
}
|
|
206
206
|
catch (error) {
|
|
207
207
|
console.error(`[依赖更新] ${item} 更新失败:`);
|
|
208
|
-
console.error(
|
|
209
|
-
console.error(`error.message: ${error.message}`);
|
|
208
|
+
console.error(error.stack || error.message || error);
|
|
210
209
|
}
|
|
211
210
|
}));
|
|
212
|
-
console.log('
|
|
211
|
+
console.log('[依赖更新] 所有npm依赖已更新完成~');
|
|
212
|
+
console.log('[依赖更新] 开始更新git插件...');
|
|
213
|
+
const gitList = this.getGitPlugins();
|
|
214
|
+
if (!gitList.length)
|
|
215
|
+
return console.log('[依赖更新] 没有git插件需要更新~');
|
|
216
|
+
await Promise.all(gitList.map(async (item) => {
|
|
217
|
+
const dir = path.resolve(process.cwd(), 'plugins', item);
|
|
218
|
+
try {
|
|
219
|
+
await this.exec('git pull', { cwd: dir });
|
|
220
|
+
console.log(`[依赖更新] ${item} 更新完成~`);
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
console.error(`[依赖更新] ${item} 更新失败`);
|
|
224
|
+
console.error(error.stack || error.message || error);
|
|
225
|
+
}
|
|
226
|
+
}));
|
|
227
|
+
console.log('[依赖更新] 所有git插件已更新完成~');
|
|
213
228
|
}
|
|
214
229
|
/**
|
|
215
230
|
* 获取指定包的本地版本
|
|
@@ -246,15 +261,28 @@ export class KarinCli {
|
|
|
246
261
|
}
|
|
247
262
|
return text.trim();
|
|
248
263
|
}
|
|
264
|
+
/**
|
|
265
|
+
* 获取git插件列表
|
|
266
|
+
*/
|
|
267
|
+
getGitPlugins() {
|
|
268
|
+
const dir = path.resolve(process.cwd(), 'plugins');
|
|
269
|
+
let list = fs.readdirSync(dir, { withFileTypes: true });
|
|
270
|
+
/** 忽略非文件夹、非 karin-plugin-开头的文件夹 */
|
|
271
|
+
list = list.filter(v => v.isDirectory() && v.name.startsWith('karin-plugin-'));
|
|
272
|
+
list = list.filter(v => fs.existsSync(`${dir}/${v.name}/package.json`));
|
|
273
|
+
const arr = [];
|
|
274
|
+
list.map(v => arr.push(v.name));
|
|
275
|
+
return arr;
|
|
276
|
+
}
|
|
249
277
|
/**
|
|
250
278
|
* 封装exec
|
|
251
279
|
* @param cmd - 命令
|
|
252
280
|
*/
|
|
253
|
-
exec(cmd) {
|
|
281
|
+
exec(cmd, options) {
|
|
254
282
|
return new Promise((resolve, reject) => {
|
|
255
|
-
execCmd(cmd, (error, stdout, stderr) => {
|
|
283
|
+
execCmd(cmd, options, (error, stdout, stderr) => {
|
|
256
284
|
if (stdout)
|
|
257
|
-
return resolve(stdout.trim());
|
|
285
|
+
return resolve(stdout.toString().trim());
|
|
258
286
|
if (error)
|
|
259
287
|
return reject(error);
|
|
260
288
|
return reject(stderr);
|
package/lib/cli/init.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { getRegistry } from './pkg.js';
|
|
2
3
|
import { KarinCfgInit } from '../core/init/config.js';
|
|
3
4
|
/**
|
|
4
5
|
* 休眠函数
|
|
@@ -14,7 +15,7 @@ async function main() {
|
|
|
14
15
|
const init = new KarinCfgInit();
|
|
15
16
|
init.init();
|
|
16
17
|
await sleep(1000);
|
|
17
|
-
const pkg =
|
|
18
|
+
const pkg = getRegistry();
|
|
18
19
|
/** 结果 */
|
|
19
20
|
await init.install(pkg);
|
|
20
21
|
}
|
package/lib/cli/pkg.d.ts
ADDED
package/lib/cli/pkg.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
/**
|
|
3
|
+
* 获取当前的包管理器 根据锁文件判断 优先级 pnpm > yarn > npm > cnpm
|
|
4
|
+
*/
|
|
5
|
+
export const getRegistry = () => {
|
|
6
|
+
if (fs.existsSync('./pnpm-lock.yaml'))
|
|
7
|
+
return 'pnpm';
|
|
8
|
+
if (fs.existsSync('./yarn.lock'))
|
|
9
|
+
return 'yarn';
|
|
10
|
+
if (fs.existsSync('./package-lock.json'))
|
|
11
|
+
return 'npm';
|
|
12
|
+
// cnpm 没有锁文件
|
|
13
|
+
return 'cnpm';
|
|
14
|
+
};
|
package/lib/core/init/config.js
CHANGED
|
@@ -198,17 +198,4 @@ export class KarinCfgInit {
|
|
|
198
198
|
});
|
|
199
199
|
});
|
|
200
200
|
}
|
|
201
|
-
/**
|
|
202
|
-
* 获取当前的包管理器 根据锁文件判断
|
|
203
|
-
*/
|
|
204
|
-
getRegistry() {
|
|
205
|
-
if (fs.existsSync('./pnpm-lock.yaml'))
|
|
206
|
-
return 'pnpm';
|
|
207
|
-
if (fs.existsSync('./yarn.lock'))
|
|
208
|
-
return 'yarn';
|
|
209
|
-
if (fs.existsSync('./package-lock.json'))
|
|
210
|
-
return 'npm';
|
|
211
|
-
// cnpm 没有锁文件
|
|
212
|
-
return 'cnpm';
|
|
213
|
-
}
|
|
214
201
|
}
|
|
@@ -111,11 +111,27 @@ export declare class Karin extends Listeners {
|
|
|
111
111
|
reject: (msg?: string) => void) => Promise<any>, options?: Omit<Options, 'log'>): HandlerInfo;
|
|
112
112
|
/**
|
|
113
113
|
* 构建contact
|
|
114
|
-
* @param
|
|
115
|
-
* @param
|
|
114
|
+
* @param scene - 场景
|
|
115
|
+
* @param peer - 群号或者用户id
|
|
116
116
|
* @param sub_peer - 子id
|
|
117
117
|
*/
|
|
118
|
-
contact(
|
|
118
|
+
contact(scene: Contact['scene'], peer: Contact['peer'], sub_peer?: Contact['sub_peer']): Contact;
|
|
119
|
+
/**
|
|
120
|
+
* 构建group_contact
|
|
121
|
+
* @param peer - 群号
|
|
122
|
+
*/
|
|
123
|
+
contactGroup(peer: Contact['peer']): Contact;
|
|
124
|
+
/**
|
|
125
|
+
* 构建friend_contact
|
|
126
|
+
* @param peer - 用户id
|
|
127
|
+
*/
|
|
128
|
+
contactFriend(peer: Contact['peer']): Contact;
|
|
129
|
+
/**
|
|
130
|
+
* 构建guild_contact
|
|
131
|
+
* @param peer - 频道id
|
|
132
|
+
* @param sub_peer - 子频道id
|
|
133
|
+
*/
|
|
134
|
+
contactGuild(peer: Contact['peer'], sub_peer: string): Contact;
|
|
119
135
|
/**
|
|
120
136
|
* 快速渲染
|
|
121
137
|
* @param file - 文件路径、http地址
|
package/lib/core/karin/karin.js
CHANGED
|
@@ -97,23 +97,34 @@ export class Karin extends Listeners {
|
|
|
97
97
|
}
|
|
98
98
|
/**
|
|
99
99
|
* 构建contact
|
|
100
|
-
* @param
|
|
101
|
-
* @param
|
|
100
|
+
* @param scene - 场景
|
|
101
|
+
* @param peer - 群号或者用户id
|
|
102
102
|
* @param sub_peer - 子id
|
|
103
103
|
*/
|
|
104
|
-
contact(
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
104
|
+
contact(scene, peer, sub_peer) {
|
|
105
|
+
return { scene, peer, sub_peer };
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 构建group_contact
|
|
109
|
+
* @param peer - 群号
|
|
110
|
+
*/
|
|
111
|
+
contactGroup(peer) {
|
|
112
|
+
return { scene: "group" /* Scene.Group */, peer };
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* 构建friend_contact
|
|
116
|
+
* @param peer - 用户id
|
|
117
|
+
*/
|
|
118
|
+
contactFriend(peer) {
|
|
119
|
+
return { scene: "friend" /* Scene.Private */, peer };
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* 构建guild_contact
|
|
123
|
+
* @param peer - 频道id
|
|
124
|
+
* @param sub_peer - 子频道id
|
|
125
|
+
*/
|
|
126
|
+
contactGuild(peer, sub_peer) {
|
|
127
|
+
return { scene: "guild" /* Scene.Guild */, peer, sub_peer };
|
|
117
128
|
}
|
|
118
129
|
/**
|
|
119
130
|
* - 渲染
|
|
@@ -71,7 +71,7 @@ export class Listeners extends EventEmitter {
|
|
|
71
71
|
}
|
|
72
72
|
const element = [
|
|
73
73
|
segment.reply(message_id),
|
|
74
|
-
segment.text(
|
|
74
|
+
segment.text(`\nKarin 重启成功:${restartTime}秒`),
|
|
75
75
|
];
|
|
76
76
|
await this.sendMsg(id, contact, element);
|
|
77
77
|
await level.del(key);
|
|
@@ -74,11 +74,7 @@ export default class Process {
|
|
|
74
74
|
* 根据配置文件判断是否继续
|
|
75
75
|
*/
|
|
76
76
|
logger.error(logger.red(`后台进程关闭失败,请检查是否有进程正在占用端口${config.Server.http.port}`));
|
|
77
|
-
|
|
78
|
-
logger.error(logger.red('当前配置不允许多进程运行,程序即将退出'));
|
|
79
|
-
await this.exit(1);
|
|
80
|
-
}
|
|
81
|
-
logger.error(logger.red('当前配置允许多进程运行,程序继续运行'));
|
|
77
|
+
await this.exit();
|
|
82
78
|
return this;
|
|
83
79
|
}
|
|
84
80
|
/**
|
package/lib/render/client.d.ts
CHANGED
|
@@ -7,13 +7,24 @@ export declare class RenderClient extends RenderBase {
|
|
|
7
7
|
id: string;
|
|
8
8
|
index: number;
|
|
9
9
|
retry: number;
|
|
10
|
+
short: boolean;
|
|
10
11
|
reg: RegExp;
|
|
11
12
|
ws: WebSocket;
|
|
13
|
+
protocol?: {
|
|
14
|
+
application: string;
|
|
15
|
+
short: boolean;
|
|
16
|
+
cache: boolean;
|
|
17
|
+
vue: boolean;
|
|
18
|
+
};
|
|
12
19
|
constructor(url: string);
|
|
13
20
|
/**
|
|
14
21
|
* 初始化
|
|
15
22
|
*/
|
|
16
23
|
start(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* 创建短连接
|
|
26
|
+
*/
|
|
27
|
+
link(): Promise<void>;
|
|
17
28
|
/**
|
|
18
29
|
* 心跳
|
|
19
30
|
*/
|
package/lib/render/client.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
+
import axios from 'axios';
|
|
2
3
|
import WebSocket from 'ws';
|
|
3
4
|
import { render } from './app.js';
|
|
4
5
|
import { RenderBase } from './base.js';
|
|
5
6
|
import { createHash, randomUUID } from 'crypto';
|
|
6
|
-
import {
|
|
7
|
+
import { karin } from '../core/index.js';
|
|
7
8
|
import { common, logger } from '../utils/index.js';
|
|
8
9
|
export class RenderClient extends RenderBase {
|
|
9
10
|
url;
|
|
@@ -11,8 +12,11 @@ export class RenderClient extends RenderBase {
|
|
|
11
12
|
id;
|
|
12
13
|
index;
|
|
13
14
|
retry;
|
|
15
|
+
short;
|
|
14
16
|
reg;
|
|
15
17
|
ws;
|
|
18
|
+
// NOTE: 渲染器协议暂定方案,目前仅short用于短连接模式确认,其他无用
|
|
19
|
+
protocol;
|
|
16
20
|
constructor(url) {
|
|
17
21
|
super();
|
|
18
22
|
this.url = url;
|
|
@@ -20,6 +24,7 @@ export class RenderClient extends RenderBase {
|
|
|
20
24
|
this.id = 'puppeteer';
|
|
21
25
|
this.index = 0;
|
|
22
26
|
this.retry = 0;
|
|
27
|
+
this.short = false;
|
|
23
28
|
this.reg = new RegExp(`(${process.cwd().replace(/\\/g, '\\\\')}|${process.cwd().replace(/\\/g, '/')})`, 'g');
|
|
24
29
|
}
|
|
25
30
|
/**
|
|
@@ -64,22 +69,73 @@ export class RenderClient extends RenderBase {
|
|
|
64
69
|
this.ws.close();
|
|
65
70
|
});
|
|
66
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* 创建短连接
|
|
74
|
+
*/
|
|
75
|
+
async link() {
|
|
76
|
+
return new Promise((resolve, reject) => {
|
|
77
|
+
if (this.ws && this.ws.readyState === WebSocket.OPEN) {
|
|
78
|
+
return resolve();
|
|
79
|
+
}
|
|
80
|
+
logger.debug(`[渲染器:${this.id}][正向WS] 创建短连接`);
|
|
81
|
+
/** 连接ws */
|
|
82
|
+
this.ws = new WebSocket(this.url);
|
|
83
|
+
/** 建立连接 */
|
|
84
|
+
this.ws.on('open', () => {
|
|
85
|
+
logger.mark(`[渲染器:${this.id}][WebSocket] 建立连接:${logger.green(this.url)}`);
|
|
86
|
+
/** 监听消息 */
|
|
87
|
+
this.ws.on('message', data => this.message(data.toString()));
|
|
88
|
+
resolve();
|
|
89
|
+
});
|
|
90
|
+
/** 监听断开 */
|
|
91
|
+
this.ws.once('close', async () => {
|
|
92
|
+
logger.debug(`[渲染器:${this.id}][正向WS] 关闭短连接`);
|
|
93
|
+
/** 停止监听 */
|
|
94
|
+
this.ws.removeAllListeners();
|
|
95
|
+
});
|
|
96
|
+
/** 监听错误 */
|
|
97
|
+
this.ws.on('error', async (e) => {
|
|
98
|
+
logger.debug(e);
|
|
99
|
+
this.ws.close();
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
}
|
|
67
103
|
/**
|
|
68
104
|
* 心跳
|
|
69
105
|
*/
|
|
70
106
|
async heartbeat() {
|
|
71
107
|
/** 无限循环 错误则停止 */
|
|
72
108
|
while (true) {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
109
|
+
if (this.short) {
|
|
110
|
+
try {
|
|
111
|
+
const res = await axios.head(this.url);
|
|
112
|
+
if (res.status === 200) {
|
|
113
|
+
logger.debug(`[渲染器:${this.id}] 心跳:${this.url}`);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
logger.debug(`[渲染器:${this.id}] 心跳失败:服务器错误,错误代码 ${res.status}`);
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
logger.debug(`[渲染器:${this.id}] 心跳失败:`, e);
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
// NOTE: 真的需要心跳的这么快吗
|
|
125
|
+
await common.sleep(60 * 1000);
|
|
76
126
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
127
|
+
else {
|
|
128
|
+
try {
|
|
129
|
+
this.ws.send(JSON.stringify({ action: 'heartbeat' }));
|
|
130
|
+
logger.debug(`[渲染器:${this.id}] 心跳:${this.url}`);
|
|
131
|
+
}
|
|
132
|
+
catch (e) {
|
|
133
|
+
logger.debug(`[渲染器:${this.id}] 心跳失败:`, e);
|
|
134
|
+
this.ws.close();
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
await common.sleep(5000);
|
|
81
138
|
}
|
|
82
|
-
await common.sleep(5000);
|
|
83
139
|
}
|
|
84
140
|
}
|
|
85
141
|
/**
|
|
@@ -101,7 +157,28 @@ export class RenderClient extends RenderBase {
|
|
|
101
157
|
}
|
|
102
158
|
/** 渲染结果 */
|
|
103
159
|
case 'renderRes': {
|
|
104
|
-
|
|
160
|
+
karin.emit(data.echo, data);
|
|
161
|
+
break;
|
|
162
|
+
}
|
|
163
|
+
/** 超时 */
|
|
164
|
+
case 'timeout': {
|
|
165
|
+
logger.debug(`[渲染器:${this.id}][正向WS] 处理超时`);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
/** 确认协议 */
|
|
169
|
+
case 'protocol': {
|
|
170
|
+
// 已确认协议,跳过
|
|
171
|
+
if (this.protocol)
|
|
172
|
+
break;
|
|
173
|
+
if (data.data)
|
|
174
|
+
this.protocol = data.data;
|
|
175
|
+
// 短连接模式
|
|
176
|
+
if (data.data?.short) {
|
|
177
|
+
logger.debug(`[渲染器:${this.id}][正向WS] 切换到短连接模式`);
|
|
178
|
+
this.short = data.data?.short;
|
|
179
|
+
this.ws.removeAllListeners();
|
|
180
|
+
this.ws.close();
|
|
181
|
+
}
|
|
105
182
|
break;
|
|
106
183
|
}
|
|
107
184
|
/** 未知数据 */
|
|
@@ -146,9 +223,12 @@ export class RenderClient extends RenderBase {
|
|
|
146
223
|
data.file = file;
|
|
147
224
|
const req = JSON.stringify({ echo, action, data });
|
|
148
225
|
logger.debug(`[渲染器:${this.id}:${this.index}][正向WS] 请求:${this.url} \nhtml: ${options.file} \ndata: ${JSON.stringify(data)}`);
|
|
226
|
+
if (this.short) {
|
|
227
|
+
await this.link();
|
|
228
|
+
}
|
|
149
229
|
this.ws.send(req);
|
|
150
230
|
return new Promise((resolve, reject) => {
|
|
151
|
-
|
|
231
|
+
karin.once(echo, (data) => {
|
|
152
232
|
if (data.ok)
|
|
153
233
|
return resolve(data.data);
|
|
154
234
|
reject(new Error(JSON.stringify(data)));
|
|
@@ -109,7 +109,7 @@ export interface KarinAdapter {
|
|
|
109
109
|
* @param history - 历史头像记录,默认`0`,若要获取历史群头像则填写1,2,3...
|
|
110
110
|
* @returns 头像的url地址
|
|
111
111
|
*/
|
|
112
|
-
|
|
112
|
+
getGroupAvatarUrl(group_id: string, size?: 0 | 40 | 100 | 140, history?: number): string;
|
|
113
113
|
/**
|
|
114
114
|
* 发送消息
|
|
115
115
|
* @param contact - 联系人信息
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
|
-
export type LoggerLevel = 'trace' | 'debug' | 'mark' | 'info' | 'mark' | 'warn' | 'error' | 'fatal';
|
|
2
|
+
export type LoggerLevel = 'all' | 'trace' | 'debug' | 'mark' | 'info' | 'mark' | 'warn' | 'error' | 'fatal' | 'off';
|
|
3
3
|
export interface Logger {
|
|
4
4
|
/**
|
|
5
5
|
* 颜色模块
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import Yaml from 'yaml';
|
|
4
|
-
import axios from 'axios';
|
|
4
|
+
import axios, { AxiosError } from 'axios';
|
|
5
5
|
import lodash from 'lodash';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
7
|
import { fileURLToPath } from 'url';
|
|
@@ -38,7 +38,12 @@ export class Common {
|
|
|
38
38
|
return true;
|
|
39
39
|
}
|
|
40
40
|
catch (err) {
|
|
41
|
-
|
|
41
|
+
if (err instanceof AxiosError) {
|
|
42
|
+
logger.error(`下载文件错误:${err.stack}`);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
logger.error(`下载文件错误:${err}`);
|
|
46
|
+
}
|
|
42
47
|
return false;
|
|
43
48
|
}
|
|
44
49
|
}
|
|
@@ -55,7 +60,7 @@ export class Common {
|
|
|
55
60
|
return await axios.get(url, param);
|
|
56
61
|
}
|
|
57
62
|
catch (error) {
|
|
58
|
-
logger.debug(error);
|
|
63
|
+
error instanceof AxiosError ? logger.debug(error.stack) : logger.debug(error);
|
|
59
64
|
return null;
|
|
60
65
|
}
|
|
61
66
|
}
|
package/lib/utils/index.d.ts
CHANGED
package/lib/utils/index.js
CHANGED
|
@@ -1,32 +1,20 @@
|
|
|
1
|
+
import { ExecOptions } from 'child_process';
|
|
1
2
|
/**
|
|
2
3
|
* 执行 shell 命令
|
|
3
4
|
* @param cmd 命令
|
|
4
5
|
* @param log 是否打印日志
|
|
5
6
|
* @param options 选项
|
|
6
7
|
*/
|
|
7
|
-
export declare const exec: (cmd: string, log?: boolean, options?: {
|
|
8
|
-
cwd: string;
|
|
9
|
-
encoding: string;
|
|
10
|
-
}) => Promise<{
|
|
11
|
-
/**
|
|
12
|
-
* - 执行状态
|
|
13
|
-
*/
|
|
8
|
+
export declare const exec: (cmd: string, log?: boolean, options?: ExecOptions) => Promise<{
|
|
14
9
|
status: "ok" | "failed";
|
|
15
|
-
/**
|
|
16
|
-
* - 错误信息
|
|
17
|
-
*/
|
|
18
10
|
error: Error | null;
|
|
19
|
-
stdout: string
|
|
20
|
-
stderr: string
|
|
11
|
+
stdout: string;
|
|
12
|
+
stderr: string;
|
|
21
13
|
}>;
|
|
22
14
|
/**
|
|
23
15
|
* 执行 shell 命令
|
|
24
16
|
* @param cmd 命令
|
|
25
|
-
* @param log 是否打印日志
|
|
26
17
|
* @param options 选项
|
|
27
18
|
*/
|
|
28
|
-
export declare const execs: (cmd: string, options?:
|
|
29
|
-
cwd: string;
|
|
30
|
-
encoding: string;
|
|
31
|
-
}) => Promise<string>;
|
|
19
|
+
export declare const execs: (cmd: string, options?: ExecOptions) => Promise<string>;
|
|
32
20
|
export default exec;
|