node-karin 0.6.27 → 0.7.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/README.md +2 -0
- package/config/defSet/pm2.yaml +1 -1
- package/lib/cli/karin.js +208 -0
- package/lib/cli/up.d.ts +2 -0
- package/lib/cli/up.js +35 -1
- package/lib/core/init.js +27 -15
- package/lib/core/karin.d.ts +5 -1
- package/lib/core/karin.js +21 -2
- package/lib/core/plugin.d.ts +4 -0
- package/lib/core/plugin.js +4 -0
- package/lib/core/plugin.loader.d.ts +16 -1
- package/lib/core/plugin.loader.js +41 -10
- package/lib/core/process.js +2 -2
- package/lib/core/server.js +8 -1
- package/lib/index.d.ts +1 -80
- package/lib/index.js +1 -23
- package/lib/render/app.d.ts +6 -2
- package/lib/render/app.js +6 -2
- package/lib/utils/common.d.ts +1 -0
- package/lib/utils/common.js +2 -2
- package/lib/utils/config.d.ts +85 -0
- package/lib/utils/config.js +1 -0
- package/lib/utils/update.d.ts +62 -0
- package/lib/utils/update.js +1 -0
- package/lib/utils/yamlEditor.d.ts +40 -15
- package/lib/utils/yamlEditor.js +92 -39
- package/package.json +17 -22
- package/lib/cli/log.js +0 -12
- package/lib/cli/restart.d.ts +0 -2
- package/lib/cli/restart.js +0 -10
- package/lib/cli/start.d.ts +0 -2
- package/lib/cli/start.js +0 -10
- package/lib/cli/stop.d.ts +0 -2
- package/lib/cli/stop.js +0 -10
- /package/lib/cli/{log.d.ts → karin.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
1
3
|
[](https://github.com/neostandard/neostandard)
|
|
2
4
|
|
|
3
5
|
[文档](https://karinjs.github.io/Karin/)
|
package/config/defSet/pm2.yaml
CHANGED
package/lib/cli/karin.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'fs'
|
|
3
|
+
import path from 'path'
|
|
4
|
+
import yaml from 'yaml'
|
|
5
|
+
import axios from 'axios'
|
|
6
|
+
import { fileURLToPath } from 'url'
|
|
7
|
+
import { program } from 'commander'
|
|
8
|
+
import { exec as execCmd, spawn } from 'child_process'
|
|
9
|
+
class KarinCli {
|
|
10
|
+
child
|
|
11
|
+
filename
|
|
12
|
+
karinDir
|
|
13
|
+
file
|
|
14
|
+
constructor () {
|
|
15
|
+
process.env.karin_app_start_count = '0'
|
|
16
|
+
/** 当前文件绝对路径 */
|
|
17
|
+
this.filename = fileURLToPath(import.meta.url)
|
|
18
|
+
/** karin目录 */
|
|
19
|
+
this.karinDir = path.join(path.dirname(this.filename), '../..')
|
|
20
|
+
/** 入口文件(注意后缀) */
|
|
21
|
+
this.file = path.join(path.dirname(this.filename), '../index')
|
|
22
|
+
this.child = null
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* 获取pkg
|
|
27
|
+
*/
|
|
28
|
+
get pkg () {
|
|
29
|
+
const filePath = path.join(this.karinDir, 'package.json')
|
|
30
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf-8'))
|
|
31
|
+
return data
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* 获取配置文件路径
|
|
36
|
+
* @param name - 配置文件名
|
|
37
|
+
*/
|
|
38
|
+
getConfigPath (name) {
|
|
39
|
+
const filePath = `./config/config/${name}.yaml`
|
|
40
|
+
if (!fs.existsSync(filePath)) { return `${this.karinDir}/config/config/${name}.yaml` }
|
|
41
|
+
return filePath
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 获取pm2配置
|
|
46
|
+
* @param name - 配置文件名
|
|
47
|
+
*/
|
|
48
|
+
getConfigData (name) {
|
|
49
|
+
const _path = this.getConfigPath(name)
|
|
50
|
+
const data = yaml.parse(fs.readFileSync(_path, 'utf-8'))
|
|
51
|
+
return data
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* 启动
|
|
56
|
+
* @param mode - 模式
|
|
57
|
+
* @param lang - 语言环境
|
|
58
|
+
* @param runner - 运行器
|
|
59
|
+
*/
|
|
60
|
+
start (mode, lang, runner) {
|
|
61
|
+
process.env.karin_app_mode = mode
|
|
62
|
+
process.env.karin_app_lang = lang
|
|
63
|
+
process.env.karin_app_runner = runner
|
|
64
|
+
let cmd
|
|
65
|
+
switch (runner) {
|
|
66
|
+
case 'node' /* Runner.Node */:
|
|
67
|
+
cmd = [this.file + '.js']
|
|
68
|
+
break
|
|
69
|
+
case 'tsx' /* Runner.Tsx */:
|
|
70
|
+
cmd = [this.file + '.ts']
|
|
71
|
+
break
|
|
72
|
+
case 'pm2' /* Runner.Pm2 */: {
|
|
73
|
+
this.pm2()
|
|
74
|
+
return
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/** 启动 */
|
|
78
|
+
this.child = spawn(runner, cmd, { stdio: ['inherit', 'inherit', 'inherit', 'ipc'], cwd: process.cwd(), env: process.env })
|
|
79
|
+
/** 监听退出 */
|
|
80
|
+
this.child.once('exit', (code) => process.exit(code))
|
|
81
|
+
/** 监听子进程消息 */
|
|
82
|
+
this.child.on('message', (data) => {
|
|
83
|
+
/** pm2重启 */
|
|
84
|
+
if (data.env.pm_id) { return this.restart() }
|
|
85
|
+
try {
|
|
86
|
+
/** 先结束进程 */
|
|
87
|
+
this.child.kill('SIGINT')
|
|
88
|
+
/** 停止监听 */
|
|
89
|
+
this.child.removeAllListeners()
|
|
90
|
+
/** 重启次数+1 */
|
|
91
|
+
const count = Number(process.env.karin_app_start_count) || 0
|
|
92
|
+
process.env.karin_app_start_count = String(count + 1)
|
|
93
|
+
} catch { }
|
|
94
|
+
return this.start(mode, lang, runner)
|
|
95
|
+
})
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* pm2重启
|
|
100
|
+
*/
|
|
101
|
+
async restart () {
|
|
102
|
+
const pm2Cfg = this.getConfigData('pm2')
|
|
103
|
+
const serverCfg = this.getConfigData('server')
|
|
104
|
+
/** 尝试获取pm2的进程id */
|
|
105
|
+
const port = serverCfg?.http?.port || 7000
|
|
106
|
+
const res = await this.Axios(`http://127.0.0.1:${port}/api/ping`, 1000)
|
|
107
|
+
if (res) {
|
|
108
|
+
await this.exec(`pm2 restart ${res.pm2_id}`)
|
|
109
|
+
} else {
|
|
110
|
+
await this.exec(`pm2 restart ${pm2Cfg?.apps[0]?.name || 'Karin'}`)
|
|
111
|
+
}
|
|
112
|
+
console.log('pm2服务已重启')
|
|
113
|
+
process.exit(0)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* pm2启动
|
|
118
|
+
*/
|
|
119
|
+
async pm2 () {
|
|
120
|
+
console.log('pm2启动中...')
|
|
121
|
+
const filePath = this.getConfigPath('pm2')
|
|
122
|
+
const data = this.getConfigData('pm2')
|
|
123
|
+
/** 修正入口文件路径 兼容0.6.28以前的版本 */
|
|
124
|
+
if (!fs.existsSync('./src') && filePath === './config/config/pm2.yaml') {
|
|
125
|
+
const script = './node_modules/node-karin/lib/index.js'
|
|
126
|
+
if (data.apps[0].script !== script) {
|
|
127
|
+
data.apps[0].script = script
|
|
128
|
+
fs.writeFileSync(filePath, yaml.stringify(data))
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const cmd = `pm2 start ${filePath} --env ${JSON.stringify(process.env)}`
|
|
132
|
+
await this.exec(cmd)
|
|
133
|
+
console.log('pm2服务已启动 可执行 【npx karin log】 查看日志')
|
|
134
|
+
process.exit(0)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* pm2结束进程
|
|
139
|
+
*/
|
|
140
|
+
async stop () {
|
|
141
|
+
console.log('pm2服务停止中...')
|
|
142
|
+
const pm2Cfg = this.getConfigData('pm2')
|
|
143
|
+
const serverCfg = this.getConfigData('server')
|
|
144
|
+
const port = serverCfg?.http?.port || 7000
|
|
145
|
+
const res = await this.Axios(`http://127.0.0.1:${port}/api/ping`, 1000)
|
|
146
|
+
if (res) {
|
|
147
|
+
await this.exec(`pm2 delete ${res.pm2_id}`)
|
|
148
|
+
} else {
|
|
149
|
+
await this.exec(`pm2 delete ${pm2Cfg?.apps[0]?.name || 'Karin'}`)
|
|
150
|
+
}
|
|
151
|
+
console.log('pm2服务已停止')
|
|
152
|
+
process.exit(0)
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* pm2查看日志
|
|
157
|
+
*/
|
|
158
|
+
async log () {
|
|
159
|
+
const pm2Cfg = this.getConfigData('pm2')
|
|
160
|
+
const serverCfg = this.getConfigData('server')
|
|
161
|
+
const port = serverCfg?.http?.port || 7000
|
|
162
|
+
const res = await this.Axios(`http://127.0.0.1:${port}/api/ping`, 1000)
|
|
163
|
+
const lines = pm2Cfg?.lines || 1000
|
|
164
|
+
const cmd = process.platform === 'win32' ? 'pm2.cmd' : 'pm2'
|
|
165
|
+
const type = res ? res.pm_id : pm2Cfg?.apps[0]?.name || 'Karin'
|
|
166
|
+
spawn(cmd, ['logs', type, '--lines', lines], { stdio: 'inherit', shell: true, cwd: process.cwd() })
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* 封装exec
|
|
171
|
+
* @param cmd - 命令
|
|
172
|
+
*/
|
|
173
|
+
exec (cmd) {
|
|
174
|
+
return new Promise((resolve, reject) => {
|
|
175
|
+
execCmd(cmd, (error, stdout, stderr) => {
|
|
176
|
+
if (stdout) { return resolve(stdout) }
|
|
177
|
+
if (error) { return reject(error) }
|
|
178
|
+
return reject(stderr)
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* 封装axios 超时返回false
|
|
185
|
+
* @param url - 请求地址
|
|
186
|
+
* @param timeout - 超时时间
|
|
187
|
+
* @returns - 请求结果
|
|
188
|
+
*/
|
|
189
|
+
async Axios (url, timeout) {
|
|
190
|
+
try {
|
|
191
|
+
const res = await axios.get(url, { timeout })
|
|
192
|
+
return res.data
|
|
193
|
+
} catch {
|
|
194
|
+
return false
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const cli = new KarinCli()
|
|
199
|
+
program.version(cli.pkg.version, '-v, --version', '显示版本号')
|
|
200
|
+
program.command('.').description('启动karin').action(() => cli.start('prod' /* Mode.Prod */, 'js' /* Lang.Js */, 'node' /* Runner.Node */))
|
|
201
|
+
program.command('start').description('启动karin').action(() => cli.start('prod' /* Mode.Prod */, 'js' /* Lang.Js */, 'node' /* Runner.Node */))
|
|
202
|
+
program.command('pm2').description('后台运行karin').action(() => cli.start('prod' /* Mode.Prod */, 'js' /* Lang.Js */, 'pm2' /* Runner.Pm2 */))
|
|
203
|
+
program.command('stop').description('停止后台运行').action(() => cli.stop())
|
|
204
|
+
program.command('rs').description('重启pm2服务').action(() => cli.restart())
|
|
205
|
+
program.command('dev').description('TypeScript开发模式').action(() => cli.start('dev' /* Mode.Dev */, 'ts' /* Lang.Ts */, 'tsx' /* Runner.Tsx */))
|
|
206
|
+
program.command('debug').description('JavaScript调试模式').action(() => cli.start('dev' /* Mode.Dev */, 'js' /* Lang.Js */, 'node' /* Runner.Node */))
|
|
207
|
+
program.command('log').description('查看日志').action(() => cli.log())
|
|
208
|
+
program.parse(process.argv)
|
package/lib/cli/up.d.ts
CHANGED
package/lib/cli/up.js
CHANGED
|
@@ -1 +1,35 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { exec } from 'child_process'
|
|
3
|
+
import { KarinInit } from '../utils/init.js'
|
|
4
|
+
/** 获取包管理器 */
|
|
5
|
+
const pkg = new KarinInit().getRegistry()
|
|
6
|
+
let cmd = ''
|
|
7
|
+
/** 更新所有依赖到最新版本 */
|
|
8
|
+
switch (pkg) {
|
|
9
|
+
case 'pnpm': {
|
|
10
|
+
cmd = 'pnpm update --latest'
|
|
11
|
+
break
|
|
12
|
+
}
|
|
13
|
+
case 'yarn': {
|
|
14
|
+
cmd = 'yarn upgrade --latest'
|
|
15
|
+
break
|
|
16
|
+
}
|
|
17
|
+
case 'npm': {
|
|
18
|
+
cmd = 'npm update --latest'
|
|
19
|
+
break
|
|
20
|
+
}
|
|
21
|
+
case 'cnpm': {
|
|
22
|
+
cmd = 'cnpm update --latest'
|
|
23
|
+
break
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exec(cmd, (error, stdout, stderr) => {
|
|
27
|
+
if (error) {
|
|
28
|
+
console.error('[更新依赖] 发送错误:')
|
|
29
|
+
console.error(`error.stack: ${error.stack}`)
|
|
30
|
+
console.error(`error.message: ${error.message}`)
|
|
31
|
+
return
|
|
32
|
+
}
|
|
33
|
+
console.log(`[更新依赖] 更新完成: ${stdout}`)
|
|
34
|
+
console.log(`[更新依赖] 更新错误: ${stderr}`)
|
|
35
|
+
})
|
package/lib/core/init.js
CHANGED
|
@@ -12,19 +12,31 @@ process.title = 'Karin'
|
|
|
12
12
|
* 设置时区
|
|
13
13
|
*/
|
|
14
14
|
process.env.TZ = 'Asia/Shanghai'
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
process.env.
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
15
|
+
const init = () => {
|
|
16
|
+
if (!process.env.karin_app_lang) { process.env.karin_app_lang = 'js' }
|
|
17
|
+
if (!process.env.karin_app_mode) { process.env.karin_app_mode = 'prod' }
|
|
18
|
+
if (!process.env.karin_app_runner) { process.env.karin_app_runner = 'node' }
|
|
19
|
+
if (!process.env.karin_app_start_count) { process.env.karin_app_start_count = '0' }
|
|
20
|
+
/** 正常启动 */
|
|
21
|
+
if (process.env.karin_app_runner === 'node' && process.env.karin_app_lang === 'js' && process.env.karin_app_mode === 'prod') {
|
|
22
|
+
logger.debug('当前为 JavaScript 生产模式')
|
|
23
|
+
return
|
|
24
|
+
}
|
|
25
|
+
/** pm2 */
|
|
26
|
+
if (process.env.karin_app_runner === 'pm2') {
|
|
27
|
+
logger.info('当前为 PM2 模式')
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
/** js开发模式 */
|
|
31
|
+
if (process.env.karin_app_lang === 'js' && process.env.karin_app_mode === 'dev') {
|
|
32
|
+
logger.info('当前为 JavaScript 开发模式')
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
/** ts开发模式 */
|
|
36
|
+
if (process.env.karin_app_lang === 'ts' && process.env.karin_app_mode === 'dev') {
|
|
37
|
+
logger.info('当前为 TypeScript 开发模式')
|
|
38
|
+
return
|
|
39
|
+
}
|
|
40
|
+
logger.error('未知的启动模式')
|
|
30
41
|
}
|
|
42
|
+
init()
|
package/lib/core/karin.d.ts
CHANGED
|
@@ -49,6 +49,8 @@ export interface OptionsElement extends OptionsCommand {
|
|
|
49
49
|
stop?: boolean;
|
|
50
50
|
}
|
|
51
51
|
export declare class Karin {
|
|
52
|
+
start: boolean;
|
|
53
|
+
constructor();
|
|
52
54
|
/**
|
|
53
55
|
* @param reg - 正则表达式
|
|
54
56
|
* @param fnc - 函数
|
|
@@ -140,5 +142,7 @@ export declare class Karin {
|
|
|
140
142
|
*/
|
|
141
143
|
replyMsg?: string;
|
|
142
144
|
}): Promise<KarinMessage>;
|
|
145
|
+
run(): void;
|
|
143
146
|
}
|
|
144
|
-
export
|
|
147
|
+
export declare const karin: Karin;
|
|
148
|
+
export default karin;
|
package/lib/core/karin.js
CHANGED
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import { server } from './server.js'
|
|
2
|
+
import { stateArr } from './plugin.js'
|
|
1
3
|
import PluginApp from './plugin.app.js'
|
|
2
4
|
import { common } from '../utils/index.js'
|
|
3
|
-
import { render } from '../render/index.js'
|
|
4
|
-
import { stateArr } from './plugin.js'
|
|
5
5
|
import { listener } from './listener.js'
|
|
6
|
+
import onebot11 from '../adapter/onebot/11/index.js'
|
|
7
|
+
import { render, RenderServer } from '../render/index.js'
|
|
6
8
|
export class Karin {
|
|
9
|
+
start
|
|
10
|
+
constructor () {
|
|
11
|
+
this.start = false
|
|
12
|
+
this.run()
|
|
13
|
+
}
|
|
14
|
+
|
|
7
15
|
/**
|
|
8
16
|
* - 快速构建命令
|
|
9
17
|
* @param reg - 正则表达式
|
|
@@ -141,4 +149,15 @@ export class Karin {
|
|
|
141
149
|
listener.once(`ctx:${key}`, (e) => resolve(e))
|
|
142
150
|
})
|
|
143
151
|
}
|
|
152
|
+
|
|
153
|
+
run () {
|
|
154
|
+
if (this.start) { return }
|
|
155
|
+
this.start = true
|
|
156
|
+
server.init()
|
|
157
|
+
listener.emit('load.plugin')
|
|
158
|
+
listener.emit('adapter', RenderServer)
|
|
159
|
+
listener.emit('adapter', onebot11)
|
|
160
|
+
}
|
|
144
161
|
}
|
|
162
|
+
export const karin = new Karin()
|
|
163
|
+
export default karin
|
package/lib/core/plugin.d.ts
CHANGED
|
@@ -168,3 +168,7 @@ export declare const stateArr: stateArrType;
|
|
|
168
168
|
export interface ExtendedPlugin extends Plugin {
|
|
169
169
|
accept: (e: KarinNoticeType | KarinRequestType) => Promise<void>;
|
|
170
170
|
}
|
|
171
|
+
/**
|
|
172
|
+
* @description 即将废弃,请使用 `Plugin`
|
|
173
|
+
*/
|
|
174
|
+
export declare const plugin: typeof Plugin;
|
package/lib/core/plugin.js
CHANGED
|
@@ -77,6 +77,16 @@ declare class PluginLoader {
|
|
|
77
77
|
pkgJson: {
|
|
78
78
|
[key: string]: any;
|
|
79
79
|
};
|
|
80
|
+
/**
|
|
81
|
+
* - 依赖缺失收集
|
|
82
|
+
*/
|
|
83
|
+
dependErr: {
|
|
84
|
+
[key: string]: {
|
|
85
|
+
dir: dirName;
|
|
86
|
+
name: fileName;
|
|
87
|
+
depend: string;
|
|
88
|
+
};
|
|
89
|
+
};
|
|
80
90
|
constructor();
|
|
81
91
|
/**
|
|
82
92
|
* 插件初始化
|
|
@@ -103,8 +113,13 @@ declare class PluginLoader {
|
|
|
103
113
|
* @param name - 插件名称
|
|
104
114
|
* @param isOrderBy - 是否为动态导入 默认为静态导入
|
|
105
115
|
* @param isNpm - 是否为npm包
|
|
116
|
+
* @param isMain - 是否为主入口文件
|
|
117
|
+
*/
|
|
118
|
+
createdApp(dir: dirName, name: fileName, isOrderBy?: boolean, isNpm?: boolean, isMain?: boolean): Promise<boolean>;
|
|
119
|
+
/**
|
|
120
|
+
* 打印依赖缺失
|
|
106
121
|
*/
|
|
107
|
-
|
|
122
|
+
printDependErr(): void;
|
|
108
123
|
/**
|
|
109
124
|
* 新增rule
|
|
110
125
|
*/
|
|
@@ -62,6 +62,10 @@ class PluginLoader {
|
|
|
62
62
|
* - 所有插件包package.json
|
|
63
63
|
*/
|
|
64
64
|
pkgJson
|
|
65
|
+
/**
|
|
66
|
+
* - 依赖缺失收集
|
|
67
|
+
*/
|
|
68
|
+
dependErr
|
|
65
69
|
constructor () {
|
|
66
70
|
this.index = 0
|
|
67
71
|
this.dir = './plugins'
|
|
@@ -78,6 +82,7 @@ class PluginLoader {
|
|
|
78
82
|
this.buttonIds = []
|
|
79
83
|
this.handlerIds = {}
|
|
80
84
|
this.pkgJson = {}
|
|
85
|
+
this.dependErr = {}
|
|
81
86
|
}
|
|
82
87
|
|
|
83
88
|
/**
|
|
@@ -98,9 +103,11 @@ class PluginLoader {
|
|
|
98
103
|
/** 获取npm插件 */
|
|
99
104
|
const npm = await common.getNpmPlugins(true)
|
|
100
105
|
/** 载入npm插件 */
|
|
101
|
-
promises.push(...npm.map(async ({ dir, name }) => await this.createdApp(dir, name, false, true)))
|
|
106
|
+
promises.push(...npm.map(async ({ dir, name, isMain }) => await this.createdApp(dir, name, false, true, isMain)))
|
|
102
107
|
/** 等待所有插件加载完成 */
|
|
103
108
|
await Promise.all(promises)
|
|
109
|
+
/** 打印依赖缺失 */
|
|
110
|
+
this.printDependErr()
|
|
104
111
|
/** 释放缓存 */
|
|
105
112
|
this.FileList = []
|
|
106
113
|
/** 优先级排序并打印插件信息 */
|
|
@@ -252,13 +259,16 @@ class PluginLoader {
|
|
|
252
259
|
* @param name - 插件名称
|
|
253
260
|
* @param isOrderBy - 是否为动态导入 默认为静态导入
|
|
254
261
|
* @param isNpm - 是否为npm包
|
|
262
|
+
* @param isMain - 是否为主入口文件
|
|
255
263
|
*/
|
|
256
|
-
async createdApp (dir, name, isOrderBy = false, isNpm = false) {
|
|
264
|
+
async createdApp (dir, name, isOrderBy = false, isNpm = false, isMain = false) {
|
|
257
265
|
try {
|
|
258
266
|
const list = []
|
|
259
267
|
let path = `${this.dirPath}${isNpm ? 'node_modules' : 'plugins'}/${dir}/${name}`
|
|
260
268
|
if (isOrderBy) { path = path + `?${Date.now()}` }
|
|
261
269
|
const tmp = await import(path)
|
|
270
|
+
/** npm包的入口文件不作为app载入 只加载 */
|
|
271
|
+
if (isMain) { return true }
|
|
262
272
|
lodash.forEach(tmp, (App) => {
|
|
263
273
|
const index = this.index
|
|
264
274
|
this.index++
|
|
@@ -307,14 +317,13 @@ class PluginLoader {
|
|
|
307
317
|
return true
|
|
308
318
|
} catch (error) {
|
|
309
319
|
if (/Cannot find package '(.+?)'/.exec(error)?.[1]) {
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
logger.error(logger.red('-----------------------------'))
|
|
320
|
+
const key = `${dir}.${name}`
|
|
321
|
+
if (this.dependErr[key]) { return false }
|
|
322
|
+
this.dependErr[key] = {
|
|
323
|
+
dir,
|
|
324
|
+
name,
|
|
325
|
+
depend: /Cannot find package '(.+?)'/.exec(error)?.[1] || '',
|
|
326
|
+
}
|
|
318
327
|
} else {
|
|
319
328
|
logger.error(`载入插件错误:${logger.red(`${dir}/${name}`)}`)
|
|
320
329
|
logger.error(error)
|
|
@@ -323,6 +332,28 @@ class PluginLoader {
|
|
|
323
332
|
}
|
|
324
333
|
}
|
|
325
334
|
|
|
335
|
+
/**
|
|
336
|
+
* 打印依赖缺失
|
|
337
|
+
*/
|
|
338
|
+
printDependErr () {
|
|
339
|
+
try {
|
|
340
|
+
const keys = Object.keys(this.dependErr)
|
|
341
|
+
if (!keys.length) { return }
|
|
342
|
+
const msg = [
|
|
343
|
+
'-----依赖缺失----',
|
|
344
|
+
]
|
|
345
|
+
keys.forEach(key => {
|
|
346
|
+
const { dir, name, depend } = this.dependErr[key]
|
|
347
|
+
msg.push(`[${dir}][${name}] 缺少依赖:${logger.red(depend)}`)
|
|
348
|
+
})
|
|
349
|
+
msg.push('-------------------')
|
|
350
|
+
logger.error(msg.join('\n'))
|
|
351
|
+
} finally {
|
|
352
|
+
/** 回收缓存 */
|
|
353
|
+
this.dependErr = {}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
326
357
|
/**
|
|
327
358
|
* 新增rule
|
|
328
359
|
*/
|
package/lib/core/process.js
CHANGED
|
@@ -55,13 +55,13 @@ export default class Process {
|
|
|
55
55
|
/**
|
|
56
56
|
* 使用api来检查后台
|
|
57
57
|
*/
|
|
58
|
-
const res = await common.axios(host + '/
|
|
58
|
+
const res = await common.axios(host + '/ping', 'get', { timeout: 100 })
|
|
59
59
|
if (!res) { return this }
|
|
60
60
|
logger.mark(logger.red('检测到后台进程 正在关闭'))
|
|
61
61
|
/** 发退出信号 */
|
|
62
62
|
await common.axios(host + '/exit', 'get', { timeout: 10 })
|
|
63
63
|
for (let i = 0; i < 50; i++) {
|
|
64
|
-
const res = await common.axios(host + '/
|
|
64
|
+
const res = await common.axios(host + '/ping', 'get', { timeout: 100 })
|
|
65
65
|
/** 请求成功继续循环 */
|
|
66
66
|
if (res) { continue }
|
|
67
67
|
/** 请求异常即代表后台进程已关闭 */
|
package/lib/core/server.js
CHANGED
|
@@ -53,13 +53,20 @@ export const server = new (class Server {
|
|
|
53
53
|
}
|
|
54
54
|
})
|
|
55
55
|
/** GET接口 - 获取当前启动信息 */
|
|
56
|
-
this.app.get('/api/
|
|
56
|
+
this.app.get('/api/ping', (req, res) => {
|
|
57
57
|
/** 只允许本机ip访问 */
|
|
58
58
|
if (req.hostname === 'localhost' || req.hostname === '127.0.0.1') {
|
|
59
59
|
const data = {
|
|
60
60
|
pm2_id: process.env.pm_id || '',
|
|
61
|
+
uptime: process.uptime(),
|
|
62
|
+
karin_app_mode: process.env.karin_app_mode,
|
|
63
|
+
karin_app_lang: process.env.karin_app_lang,
|
|
64
|
+
karin_app_runner: process.env.karin_app_runner,
|
|
65
|
+
karin_app_start_count: process.env.karin_app_start_count,
|
|
61
66
|
}
|
|
62
67
|
res.json(data)
|
|
68
|
+
} else {
|
|
69
|
+
res.status(403).json({ error: '禁止访问', message: '无效的请求' })
|
|
63
70
|
}
|
|
64
71
|
})
|
|
65
72
|
/** GET接口 - 退出当前进程 */
|
package/lib/index.d.ts
CHANGED
|
@@ -6,83 +6,4 @@ export * from './render/index.js';
|
|
|
6
6
|
export * from './utils/index.js';
|
|
7
7
|
export * from './types/index.js';
|
|
8
8
|
export * from './adapter/index.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @description 即将废弃,请使用 `Plugin`
|
|
12
|
-
*/
|
|
13
|
-
export declare const plugin: typeof Plugin;
|
|
14
|
-
/**
|
|
15
|
-
* @description 即将废弃,请使用 `render`
|
|
16
|
-
*/
|
|
17
|
-
export declare const Renderer: {
|
|
18
|
-
index: number;
|
|
19
|
-
Apps: Array<import("./types/index.js").KarinRenderApp>;
|
|
20
|
-
app(data: {
|
|
21
|
-
id: string;
|
|
22
|
-
type?: "image" | string;
|
|
23
|
-
render: import("./types/index.js").KarinRender["render"];
|
|
24
|
-
}): number;
|
|
25
|
-
unapp(index: number): boolean;
|
|
26
|
-
App(id?: string): import("./types/index.js").KarinRenderApp;
|
|
27
|
-
render(options: import("./types/index.js").KarinRenderType, id?: string): Promise<string | string[]>;
|
|
28
|
-
renderHtml(data: string): Promise<string | string[]>;
|
|
29
|
-
};
|
|
30
|
-
export declare const Cfg: {
|
|
31
|
-
projPath: string;
|
|
32
|
-
projConfigPath: string;
|
|
33
|
-
pkgPath: string;
|
|
34
|
-
pkgConfigPath: string;
|
|
35
|
-
change: Map<string, any>;
|
|
36
|
-
watcher: Map<string, any>;
|
|
37
|
-
review: boolean;
|
|
38
|
-
logger: import("log4js").Logger;
|
|
39
|
-
initCfg(): Promise<void>;
|
|
40
|
-
getPlugins(): Promise<string[]>;
|
|
41
|
-
mkdir(dirname: string): boolean;
|
|
42
|
-
dirPath(_path: string, plugins: string[]): Promise<void>;
|
|
43
|
-
timeout(type?: "ws" | "grpc"): number;
|
|
44
|
-
readonly redis: import("./types/index.js").Redis;
|
|
45
|
-
readonly master: string[];
|
|
46
|
-
readonly admin: string[];
|
|
47
|
-
readonly App: import("./types/index.js").App;
|
|
48
|
-
readonly Config: import("./types/index.js").Config;
|
|
49
|
-
readonly Server: import("./types/index.js").Server;
|
|
50
|
-
readonly package: import("./types/index.js").Package;
|
|
51
|
-
group(group_id?: string): import("./types/index.js").GroupCfg;
|
|
52
|
-
getYaml(type: "defSet" | "config", name: string, isWatch?: boolean): any;
|
|
53
|
-
watch(type: "defSet" | "config", name: string, file: string): Promise<true | undefined>;
|
|
54
|
-
change_App(): Promise<void>;
|
|
55
|
-
change_config(): Promise<void>;
|
|
56
|
-
change_group(): Promise<void>;
|
|
57
|
-
"__#2@#review"(): Promise<void>;
|
|
58
|
-
};
|
|
59
|
-
export declare const Update: {
|
|
60
|
-
dir: string;
|
|
61
|
-
update(path: string, cmd?: string, time?: number): Promise<{
|
|
62
|
-
status: string;
|
|
63
|
-
data: string;
|
|
64
|
-
}>;
|
|
65
|
-
getTime(path: string): Promise<string>;
|
|
66
|
-
getHash(path: string, short?: boolean): Promise<string>;
|
|
67
|
-
getCommit(options: {
|
|
68
|
-
path: any;
|
|
69
|
-
count?: any;
|
|
70
|
-
hash?: any;
|
|
71
|
-
branch?: any;
|
|
72
|
-
}): Promise<string>;
|
|
73
|
-
checkUpdate(path: import("fs").PathLike, time?: number): Promise<{
|
|
74
|
-
status: string;
|
|
75
|
-
data: string | undefined;
|
|
76
|
-
count?: undefined;
|
|
77
|
-
} | {
|
|
78
|
-
status: string;
|
|
79
|
-
data: boolean;
|
|
80
|
-
count?: undefined;
|
|
81
|
-
} | {
|
|
82
|
-
status: string;
|
|
83
|
-
data: string;
|
|
84
|
-
count: string | number;
|
|
85
|
-
}>;
|
|
86
|
-
};
|
|
87
|
-
export declare const karin: Karin;
|
|
88
|
-
export default karin;
|
|
9
|
+
export { karin as default } from './core/index.js';
|
package/lib/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// 基本模块
|
|
2
1
|
export * from 'kritor-proto';
|
|
3
2
|
export * from './core/index.js';
|
|
4
3
|
export * from './event/index.js';
|
|
@@ -7,25 +6,4 @@ export * from './render/index.js';
|
|
|
7
6
|
export * from './utils/index.js';
|
|
8
7
|
export * from './types/index.js';
|
|
9
8
|
export * from './adapter/index.js';
|
|
10
|
-
|
|
11
|
-
import { render } from './render/index.js';
|
|
12
|
-
import { RenderServer } from './render/index.js';
|
|
13
|
-
import OneBot11 from './adapter/onebot/11/index.js';
|
|
14
|
-
import { server, Karin, listener, Plugin } from './core/index.js';
|
|
15
|
-
// 初始化
|
|
16
|
-
server.init();
|
|
17
|
-
listener.emit('load.plugin');
|
|
18
|
-
listener.emit('adapter', RenderServer);
|
|
19
|
-
listener.emit('adapter', OneBot11);
|
|
20
|
-
/**
|
|
21
|
-
* @description 即将废弃,请使用 `Plugin`
|
|
22
|
-
*/
|
|
23
|
-
export const plugin = Plugin;
|
|
24
|
-
/**
|
|
25
|
-
* @description 即将废弃,请使用 `render`
|
|
26
|
-
*/
|
|
27
|
-
export const Renderer = render;
|
|
28
|
-
export const Cfg = config;
|
|
29
|
-
export const Update = update;
|
|
30
|
-
export const karin = new Karin();
|
|
31
|
-
export default karin;
|
|
9
|
+
export { karin as default } from './core/index.js';
|