node-karin 0.10.0 → 0.10.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 (129) hide show
  1. package/config/defSet/group.yaml +40 -2
  2. package/lib/adapter/onebot/11/index.js +1 -1
  3. package/lib/cli/init.js +1 -1
  4. package/lib/cli/karin.js +1 -1
  5. package/lib/core/index.d.ts +9 -9
  6. package/lib/core/index.js +9 -9
  7. package/lib/core/init/dir.js +7 -0
  8. package/lib/core/init/init.js +46 -0
  9. package/lib/core/{karin.d.ts → karin/karin.d.ts} +1 -1
  10. package/lib/core/karin/karin.js +194 -0
  11. package/lib/core/{listener.d.ts → listener/listener.d.ts} +1 -1
  12. package/lib/core/listener/listener.js +213 -0
  13. package/lib/core/{plugin.app.d.ts → plugin/app.d.ts} +1 -1
  14. package/lib/core/plugin/app.js +19 -0
  15. package/lib/core/{plugin.d.ts → plugin/base.d.ts} +1 -1
  16. package/lib/core/plugin/base.js +140 -0
  17. package/lib/core/{plugin.loader.d.ts → plugin/loader.d.ts} +3 -3
  18. package/lib/core/plugin/loader.js +579 -0
  19. package/lib/core/process/process.js +100 -0
  20. package/lib/core/server/server.js +283 -0
  21. package/lib/db/index.d.ts +2 -2
  22. package/lib/db/index.js +2 -2
  23. package/lib/db/level/level.js +36 -0
  24. package/lib/db/redis/redis.js +135 -0
  25. package/lib/db/redis/redis_level.js +287 -0
  26. package/lib/event/{event.handler.d.ts → handler/base.d.ts} +2 -2
  27. package/lib/event/handler/base.js +173 -0
  28. package/lib/event/{message.handler.d.ts → handler/message.d.ts} +3 -3
  29. package/lib/event/handler/message.js +270 -0
  30. package/lib/event/{notice.handler.d.ts → handler/notice.d.ts} +3 -3
  31. package/lib/event/handler/notice.js +212 -0
  32. package/lib/event/{request.handler.d.ts → handler/request.d.ts} +3 -3
  33. package/lib/event/handler/request.js +118 -0
  34. package/lib/event/{review.handler.d.ts → handler/review.d.ts} +3 -3
  35. package/lib/event/handler/review.js +391 -0
  36. package/lib/event/index.d.ts +5 -5
  37. package/lib/event/index.js +5 -5
  38. package/lib/render/base.d.ts +1 -1
  39. package/lib/render/client.d.ts +1 -1
  40. package/lib/render/client.js +2 -12
  41. package/lib/render/client_even.d.ts +1 -1
  42. package/lib/render/client_even.js +2 -12
  43. package/lib/render/http.d.ts +1 -1
  44. package/lib/render/http.js +1 -1
  45. package/lib/render/server.js +1 -1
  46. package/lib/types/adapter/{adapter.d.ts → base.d.ts} +2 -2
  47. package/lib/types/config/config.js +1 -0
  48. package/lib/types/element/element.js +1 -0
  49. package/lib/types/event/message.d.ts +1 -1
  50. package/lib/types/event/reply.d.ts +1 -1
  51. package/lib/types/index.d.ts +6 -6
  52. package/lib/types/index.js +6 -6
  53. package/lib/types/logger/logger.js +1 -0
  54. package/lib/types/{plugin.d.ts → plugin/plugin.d.ts} +3 -3
  55. package/lib/types/plugin/plugin.js +1 -0
  56. package/lib/types/render/render.js +1 -0
  57. package/lib/utils/{common.d.ts → common/common.d.ts} +1 -1
  58. package/lib/utils/common/common.js +591 -0
  59. package/lib/utils/{config.d.ts → config/config.d.ts} +37 -19
  60. package/lib/utils/config/config.js +328 -0
  61. package/lib/utils/config/updateVersion.js +145 -0
  62. package/lib/utils/config/yamlEditor.js +292 -0
  63. package/lib/utils/{handler.d.ts → core/handler.d.ts} +1 -1
  64. package/lib/utils/core/handler.js +115 -0
  65. package/lib/utils/core/init.js +213 -0
  66. package/lib/utils/core/logger.js +105 -0
  67. package/lib/utils/{segment.d.ts → core/segment.d.ts} +1 -1
  68. package/lib/utils/core/segment.js +441 -0
  69. package/lib/utils/index.d.ts +11 -11
  70. package/lib/utils/index.js +11 -11
  71. package/lib/utils/{button.d.ts → tools/button.d.ts} +1 -1
  72. package/lib/utils/tools/button.js +38 -0
  73. package/lib/utils/tools/exec.js +37 -0
  74. package/lib/utils/tools/ffmpeg.js +25 -0
  75. package/lib/utils/tools/update.js +139 -0
  76. package/package.json +1 -1
  77. package/lib/core/dir.js +0 -7
  78. package/lib/core/init.js +0 -42
  79. package/lib/core/karin.js +0 -194
  80. package/lib/core/listener.js +0 -217
  81. package/lib/core/plugin.app.js +0 -19
  82. package/lib/core/plugin.js +0 -145
  83. package/lib/core/plugin.loader.js +0 -561
  84. package/lib/core/process.js +0 -98
  85. package/lib/core/server.js +0 -269
  86. package/lib/db/level.js +0 -37
  87. package/lib/db/redis.js +0 -134
  88. package/lib/db/redis_level.js +0 -293
  89. package/lib/event/event.handler.js +0 -167
  90. package/lib/event/message.handler.js +0 -254
  91. package/lib/event/notice.handler.js +0 -204
  92. package/lib/event/request.handler.js +0 -110
  93. package/lib/event/review.handler.js +0 -387
  94. package/lib/types/config.js +0 -1
  95. package/lib/types/element.js +0 -1
  96. package/lib/types/logger.js +0 -1
  97. package/lib/types/plugin.js +0 -1
  98. package/lib/types/render.js +0 -1
  99. package/lib/utils/button.js +0 -34
  100. package/lib/utils/common.js +0 -572
  101. package/lib/utils/config.js +0 -318
  102. package/lib/utils/exec.js +0 -36
  103. package/lib/utils/ffmpeg.js +0 -25
  104. package/lib/utils/handler.js +0 -109
  105. package/lib/utils/init.js +0 -208
  106. package/lib/utils/logger.js +0 -104
  107. package/lib/utils/segment.js +0 -470
  108. package/lib/utils/update.js +0 -135
  109. package/lib/utils/updateVersion.js +0 -145
  110. package/lib/utils/yamlEditor.js +0 -279
  111. /package/lib/core/{dir.d.ts → init/dir.d.ts} +0 -0
  112. /package/lib/core/{init.d.ts → init/init.d.ts} +0 -0
  113. /package/lib/core/{process.d.ts → process/process.d.ts} +0 -0
  114. /package/lib/core/{server.d.ts → server/server.d.ts} +0 -0
  115. /package/lib/db/{level.d.ts → level/level.d.ts} +0 -0
  116. /package/lib/db/{redis.d.ts → redis/redis.d.ts} +0 -0
  117. /package/lib/db/{redis_level.d.ts → redis/redis_level.d.ts} +0 -0
  118. /package/lib/types/adapter/{adapter.js → base.js} +0 -0
  119. /package/lib/types/{config.d.ts → config/config.d.ts} +0 -0
  120. /package/lib/types/{element.d.ts → element/element.d.ts} +0 -0
  121. /package/lib/types/{logger.d.ts → logger/logger.d.ts} +0 -0
  122. /package/lib/types/{render.d.ts → render/render.d.ts} +0 -0
  123. /package/lib/utils/{updateVersion.d.ts → config/updateVersion.d.ts} +0 -0
  124. /package/lib/utils/{yamlEditor.d.ts → config/yamlEditor.d.ts} +0 -0
  125. /package/lib/utils/{init.d.ts → core/init.d.ts} +0 -0
  126. /package/lib/utils/{logger.d.ts → core/logger.d.ts} +0 -0
  127. /package/lib/utils/{exec.d.ts → tools/exec.d.ts} +0 -0
  128. /package/lib/utils/{ffmpeg.d.ts → tools/ffmpeg.d.ts} +0 -0
  129. /package/lib/utils/{update.d.ts → tools/update.d.ts} +0 -0
@@ -1,104 +0,0 @@
1
- import fs from 'fs'
2
- import chalk from 'chalk'
3
- import log4js from 'log4js'
4
- import { config } from './config.js'
5
- const logsDir = './logs'
6
- if (!fs.existsSync(logsDir)) { fs.mkdirSync(logsDir) }
7
- const { log_level, log_days_Keep, log4jsCfg } = config.Config
8
- const level = log_level || log4jsCfg.level || 'info'
9
- const daysToKeep = log_days_Keep || log4jsCfg.daysToKeep || 7
10
- const { overall, fragments, maxLogSize } = log4jsCfg
11
- const defaultOptions = { appenders: ['console'], level, enableCallStack: process.env.KarinMode === 'dev' }
12
- const options = {
13
- appenders: {
14
- console: {
15
- type: 'console',
16
- layout: {
17
- type: 'pattern',
18
- pattern: `%[[Karin][%d{hh:mm:ss.SSS}][%4.4p]%] ${process.env.KarinMode === 'dev' ? '[%f{3}:%l] ' : ''}%m`,
19
- },
20
- },
21
- },
22
- categories: { default: defaultOptions },
23
- }
24
- if (overall) {
25
- defaultOptions.appenders.unshift('overall')
26
- options.appenders.overall = {
27
- /** 输出到文件 */
28
- type: 'file',
29
- filename: 'logs/logger',
30
- pattern: 'yyyy-MM-dd.log',
31
- /** 日期后缀 */
32
- keepFileExt: true,
33
- /** 日志文件名中包含日期模式 */
34
- alwaysIncludePattern: true,
35
- /** 日志文件保留天数 */
36
- daysToKeep,
37
- /** 日志输出格式 */
38
- layout: {
39
- type: 'pattern',
40
- pattern: '[%d{hh:mm:ss.SSS}][%4.4p] %m',
41
- },
42
- }
43
- }
44
- if (fragments) {
45
- defaultOptions.appenders.unshift('fragments')
46
- options.appenders.fragments = {
47
- type: 'file',
48
- filename: 'logs/app.log',
49
- pattern: 'MM-dd.log',
50
- keepFileExt: true,
51
- alwaysIncludePattern: true,
52
- daysToKeep,
53
- maxLogSize: (maxLogSize || 30) * 1024 * 1024,
54
- /** 最大文件数 */
55
- numBackups: 9999999,
56
- /** 日志输出格式 */
57
- layout: {
58
- type: 'pattern',
59
- pattern: '[%d{hh:mm:ss.SSS}][%4.4p] %m',
60
- },
61
- }
62
- }
63
- log4js.configure(options)
64
- export const logger = log4js.getLogger('default')
65
- logger.chalk = chalk
66
- logger.red = chalk.red
67
- logger.green = chalk.green
68
- logger.yellow = chalk.yellow
69
- logger.blue = chalk.blue
70
- logger.magenta = chalk.magenta
71
- logger.cyan = chalk.cyan
72
- logger.white = chalk.white
73
- logger.gray = chalk.gray
74
- logger.violet = chalk.hex('#868ECC')
75
- logger.fnc = chalk.hex(config.Config.log_color || '#FFFF00')
76
- logger.bot = (level, id, ...args) => {
77
- switch (level) {
78
- case 'trace':
79
- logger.trace(logger.violet(`[Bot:${id}]`), ...args)
80
- break
81
- case 'debug':
82
- logger.debug(logger.violet(`[Bot:${id}]`), ...args)
83
- break
84
- case 'mark':
85
- logger.mark(logger.violet(`[Bot:${id}]`), ...args)
86
- break
87
- case 'info':
88
- logger.info(logger.violet(`[Bot:${id}]`), ...args)
89
- break
90
- case 'warn':
91
- logger.warn(logger.violet(`[Bot:${id}]`), ...args)
92
- break
93
- case 'error':
94
- logger.error(logger.violet(`[Bot:${id}]`), ...args)
95
- break
96
- case 'fatal':
97
- logger.fatal(logger.violet(`[Bot:${id}]`), ...args)
98
- break
99
- default:
100
- logger.info(logger.violet(`[Bot:${id}]`), ...args)
101
- }
102
- }
103
- global.logger = logger
104
- export default logger
@@ -1,470 +0,0 @@
1
- export const segment = new (class Segment {
2
- /**
3
- * 纯文本
4
- * @param text - 文本内容
5
- * @returns {TextElement} 纯文本元素
6
- */
7
- text (text) {
8
- return {
9
- type: 'text',
10
- text: text + '',
11
- }
12
- }
13
-
14
- /**
15
- * 提及
16
- * 提供一个uid即可
17
- * @param uid - uid
18
- * @param uin - uin
19
- * @param name - 名称
20
- * @returns {AtElement} 提及元素
21
- */
22
- at (uid, uin, name) {
23
- return {
24
- type: 'at',
25
- uid: uid + '',
26
- uin: (uin || '') + '',
27
- name,
28
- }
29
- }
30
-
31
- /**
32
- * 表情
33
- * @param id - 表情ID
34
- * @param is_big - 是否大表情,默认不是
35
- * @returns {FaceElement} 表情元素
36
- */
37
- face (id, is_big = false) {
38
- return {
39
- type: 'face',
40
- id: Number(id),
41
- is_big,
42
- }
43
- }
44
-
45
- /**
46
- * 弹射表情
47
- * @param id - 表情ID
48
- * @param count - 数量
49
- * @returns {BubbleFaceElement} 弹射表情元素
50
- */
51
- bubble_face (id, count = 1) {
52
- return {
53
- type: 'bubble_face',
54
- id: Number(id),
55
- count: Number(count),
56
- }
57
- }
58
-
59
- /**
60
- * 引用回复
61
- * @param message_id - 消息ID
62
- * @returns {ReplyElement} 引用回复元素
63
- */
64
- reply (message_id) {
65
- return {
66
- type: 'reply',
67
- message_id: message_id + '',
68
- }
69
- }
70
-
71
- /**
72
- * 图片
73
- * - 一般情况提供一个file参数即可,其他参数一般为收到的消息中的参数
74
- * @param file - 图片URL或路径、Base64
75
- * @param options - 图片类型、名称、MD5、子类型、宽度、高度
76
- * @returns {ImageElement} 图片元素
77
- */
78
- image (file, options = {}) {
79
- const file_type = options.file_type || 'original'
80
- const name = options.name || ''
81
- const md5 = options.md5 || ''
82
- const sub_type = options.sub_type || ''
83
- const width = options.width || 0
84
- const height = options.height || 0
85
- return {
86
- type: 'image',
87
- file,
88
- file_type,
89
- name,
90
- md5,
91
- sub_type,
92
- width,
93
- height,
94
- }
95
- }
96
-
97
- /**
98
- * 语音
99
- * @description 即将废弃,请使用voice
100
- * @param file - 语音URL或路径、Base64
101
- * @param magic - 是否魔法语音,默认为 false
102
- * @param md5 - 语音md5
103
- * @param name - 语音名称
104
- * @returns {VoiceElement} 语音元素
105
- */
106
- record (file, magic = false, md5 = '', name = '') {
107
- return {
108
- type: 'record',
109
- file,
110
- magic,
111
- md5,
112
- name,
113
- }
114
- }
115
-
116
- /**
117
- * 语音 即将废弃 请使用segment.record
118
- * @param file - 语音URL或路径、Base64
119
- * @param magic - 是否魔法语音,默认为 false
120
- * @param md5 - 语音md5
121
- * @param name - 语音名称
122
- * @returns {VoiceElement} 语音元素
123
- * @deprecated 即将废弃 请使用segment.record
124
- */
125
- voice (file, magic = false, md5 = '', name = '') {
126
- return {
127
- type: 'record',
128
- file,
129
- magic,
130
- md5,
131
- name,
132
- }
133
- }
134
-
135
- /**
136
- * 视频
137
- * @param file - 视频URL或路径、Base64
138
- * @param md5 - 视频md5
139
- * @param name - 视频名称
140
- * @returns {VideoElement} 视频元素
141
- */
142
- video (file, md5 = '', name = '') {
143
- return {
144
- type: 'video',
145
- file,
146
- md5,
147
- name,
148
- }
149
- }
150
-
151
- /**
152
- * 篮球
153
- * @param id - 篮球ID
154
- * @returns {BasketballElement} 篮球元素
155
- */
156
- basketball (id) {
157
- return {
158
- type: 'basketball',
159
- id,
160
- }
161
- }
162
-
163
- /**
164
- * 骰子
165
- * @param id - 骰子ID
166
- * @returns {DiceElement} 骰子元素
167
- */
168
- dice (id) {
169
- return {
170
- type: 'dice',
171
- id,
172
- }
173
- }
174
-
175
- /**
176
- * 石头剪刀布
177
- * @param id - 石头剪刀布ID
178
- * @returns {RpsElement} 石头剪刀布元素
179
- */
180
- rps (id) {
181
- return {
182
- type: 'rps',
183
- id,
184
- }
185
- }
186
-
187
- /**
188
- * 戳一戳
189
- * @param id - 戳一戳ID
190
- * @param poke_type - 戳一戳类型
191
- * @param strength - 戳一戳强度(1-5 默认1)
192
- * @returns {PokeElement} 戳一戳元素
193
- */
194
- poke (id, poke_type, strength = 1) {
195
- return {
196
- type: 'poke',
197
- id,
198
- poke_type,
199
- strength,
200
- }
201
- }
202
-
203
- /**
204
- * 自定义音乐
205
- * @param url - 跳转链接
206
- * @param audio - 音乐音频链接
207
- * @param title - 标题
208
- * @param author - 歌手
209
- * @param pic - 封面
210
- * @returns {CustomMusicElemen} 自定义音乐元素
211
- */
212
- customMusic (url, audio, title, author, pic, id) {
213
- return {
214
- type: 'music',
215
- platform: 'custom',
216
- url,
217
- audio,
218
- title,
219
- author,
220
- pic,
221
- id,
222
- }
223
- }
224
-
225
- /**
226
- * 音乐
227
- * @param platform - 音乐平台
228
- * @param id - 音乐ID
229
- * @returns {MusicElement} 音乐元素
230
- */
231
- music (platform, id) {
232
- return {
233
- type: 'music',
234
- platform,
235
- id,
236
- }
237
- }
238
-
239
- /**
240
- * 天气
241
- * @param city - 城市名称
242
- * @param code - 城市代码
243
- * @returns {WeatherElement} 天气元素
244
- */
245
- weather (city, code) {
246
- return {
247
- type: 'weather',
248
- city,
249
- code,
250
- }
251
- }
252
-
253
- /**
254
- * 位置
255
- * @param lat - 纬度
256
- * @param lon - 经度
257
- * @param title - 标题
258
- * @param address - 地址
259
- * @returns {LocationElement} 位置元素
260
- */
261
- location (lat, lon, title, address) {
262
- return {
263
- type: 'location',
264
- lat,
265
- lon,
266
- title,
267
- address,
268
- }
269
- }
270
-
271
- /**
272
- * 分享
273
- * @param url - 分享链接
274
- * @param title - 分享标题
275
- * @param content - 分享内容
276
- * @param image - 分享图片
277
- * @returns {ShareElement} 分享元素
278
- */
279
- share (url, title, content, image) {
280
- return {
281
- type: 'share',
282
- url,
283
- title,
284
- content,
285
- image,
286
- }
287
- }
288
-
289
- /**
290
- * 礼物
291
- * @param qq - QQ 号
292
- * @param id - 礼物ID
293
- * @returns {GiftElement} 礼物元素
294
- */
295
- gift (qq, id) {
296
- return {
297
- type: 'gift',
298
- qq,
299
- id,
300
- }
301
- }
302
-
303
- /**
304
- * 商城表情
305
- * @param id - 表情ID
306
- * @returns {MarketFaceElement} 商城表情元素
307
- */
308
- marketFace (id) {
309
- return {
310
- type: 'market_face',
311
- id,
312
- }
313
- }
314
-
315
- /**
316
- * 转发
317
- * @param res_id - 资源ID
318
- * @param uniseq - 序列号(可能不对?)
319
- * @param summary - 摘要
320
- * @param description - 描述
321
- * @returns {ForwardElement} 转发元素
322
- */
323
- forward (res_id, uniseq, summary, description) {
324
- return {
325
- type: 'forward',
326
- res_id,
327
- uniseq: uniseq || '',
328
- summary: summary || '',
329
- description: description || '',
330
- }
331
- }
332
-
333
- /**
334
- * 分享名片
335
- * @param scene - 分享类型
336
- * @param peer - 被推荐人的QQ号或者被推荐群的群号
337
- * @returns {ContactElement} 分享名片元素
338
- */
339
- contact (scene, peer) {
340
- return {
341
- type: 'contact',
342
- scene,
343
- peer,
344
- }
345
- }
346
-
347
- /**
348
- * JSON
349
- * @param data - JSON序列化过的字符串
350
- * @returns {JsonElement} JSON元素
351
- */
352
- json (data) {
353
- return {
354
- type: 'json',
355
- data,
356
- }
357
- }
358
-
359
- /**
360
- * XML
361
- * @param data - XML字符串
362
- * @returns {XmlElement} XML元素
363
- */
364
- xml (data) {
365
- return {
366
- type: 'xml',
367
- data,
368
- }
369
- }
370
-
371
- /**
372
- * 文件
373
- */
374
- file (options) {
375
- return {
376
- type: 'file',
377
- file: options.url,
378
- name: options.name || '',
379
- size: options.size || 0,
380
- expire_time: options.expire_time || 0,
381
- id: options.id || '',
382
- url: options.url,
383
- biz: options.biz || 0,
384
- sub_id: options.sub_id || '',
385
- md5: options.md5 || '',
386
- }
387
- }
388
-
389
- /**
390
- * 长消息
391
- * @param id - ID
392
- */
393
- long_msg (id) {
394
- return {
395
- type: 'long_msg',
396
- id,
397
- }
398
- }
399
-
400
- /**
401
- * Markdown
402
- * @param content - 原生markdown内容
403
- * @param config - 未知的参数
404
- */
405
- markdown (content, config) {
406
- return {
407
- type: 'markdown',
408
- content,
409
- config,
410
- }
411
- }
412
-
413
- /**
414
- * 构建模板Markdown
415
- * @param custom_template_id - 模板ID
416
- * @param params - 模板markdown参数
417
- */
418
- markdown_tpl (
419
- /**
420
- * - 模板ID
421
- */
422
- custom_template_id,
423
- /**
424
- * - 模板markdown参数
425
- */
426
- params) {
427
- return {
428
- type: 'markdown_tpl',
429
- custom_template_id,
430
- params,
431
- }
432
- }
433
-
434
- /**
435
- * 按钮
436
- * @param data - 按钮数据
437
- * @returns {ButtonElement} 按钮元素
438
- */
439
- button (data) {
440
- return {
441
- type: 'button',
442
- data,
443
- }
444
- }
445
-
446
- rows (data) {
447
- const rows = []
448
- if (!Array.isArray(data)) { data = [data] }
449
- for (const i of data) {
450
- rows.push(this.button(i))
451
- continue
452
- }
453
- return { type: 'rows', rows }
454
- }
455
-
456
- /**
457
- * 转发自定义节点
458
- * @param user_id - 用户ID
459
- * @param nickname - 用户昵称
460
- * @param content - 节点内容
461
- */
462
- node (user_id, nickname, content) {
463
- return {
464
- type: 'node',
465
- user_id,
466
- nickname,
467
- content,
468
- }
469
- }
470
- })()
@@ -1,135 +0,0 @@
1
- import fs from 'fs'
2
- import exec from './exec.js'
3
- export const update = new (class Update {
4
- dir
5
- constructor () {
6
- this.dir = './plugins'
7
- }
8
-
9
- /**
10
- * 更新框架或插件
11
- * @param path - 插件相对路径
12
- * @param cmd - 更新命令 默认git pull
13
- * @param time - 超时时间 默认120s
14
- */
15
- async update (path, cmd = 'git pull', time = 120) {
16
- /** 检查一下路径是否存在 */
17
- if (!fs.existsSync(path)) { return { status: 'failed', data: '路径不存在' } }
18
- /** 检查是否有.git文件夹 */
19
- if (!fs.existsSync(`${path}/.git`)) { return { status: 'failed', data: '该路径不是一个git仓库' } }
20
- /** 设置超时时间 */
21
- const timer = setTimeout(() => {
22
- return { status: 'failed', data: '执行超时' }
23
- }, time * 1000)
24
- const options = { env: process.env, cwd: path, encoding: 'utf-8' }
25
- /** 记录当前短哈希 */
26
- const hash = await this.getHash(path)
27
- /** 执行更新 */
28
- const { status, error } = await exec(cmd, true, options)
29
- /** 执行成功 */
30
- if (status === 'ok') {
31
- clearTimeout(timer)
32
- /** 再次获取短哈希 查看是否有更新 */
33
- const newHash = await this.getHash(path)
34
- if (hash === newHash) {
35
- const time = await this.getTime(path)
36
- return {
37
- status: 'ok',
38
- data: ['\n当前版本已是最新版本', `Hash: ${hash}`, `最后更新:${await this.getCommit({ path, count: 1 })}`, `最后提交时间:${time}`].join('\n'),
39
- }
40
- }
41
- const Commit = await this.getCommit({ path, hash })
42
- return {
43
- status: 'ok',
44
- data: ['\n更新成功', `当前Hash: ${newHash}`, `更新日志:\n${Commit}`].join('\n'),
45
- }
46
- }
47
- const msg = ['\n更新失败', `当前Hash: ${hash}`, `错误信息:${error?.message?.toString() || error?.stack?.toString() || error?.toString()}`, '请解决错误后重试或执行【#强制更新】']
48
- return { status: 'failed', data: msg.join('\n') }
49
- }
50
-
51
- /**
52
- * 获取指定仓库最后一次提交时间日期
53
- * @param path - 插件相对路径
54
- */
55
- async getTime (path) {
56
- const cmd = 'git log -1 --format=%cd --date=format:"%Y-%m-%d %H:%M:%S"'
57
- const data = await exec(cmd, false, { cwd: path, encoding: 'utf-8' })
58
- if (data.status === 'failed') { return '获取时间失败,请重试或更新Git~' }
59
- return data.stdout.trim()
60
- }
61
-
62
- /**
63
- * 获取指定仓库最后一次提交哈希值
64
- * @param {string} path - 插件相对路径
65
- * @param {boolean} [short] - 是否获取短哈希 默认true
66
- * @returns {Promise<string>}
67
- */
68
- async getHash (path, short = true) {
69
- const cmd = short ? 'git rev-parse --short HEAD' : 'git rev-parse HEAD'
70
- const data = await exec(cmd, false, { cwd: path, encoding: 'utf-8' })
71
- if (data.status === 'failed') {
72
- const text = data.error
73
- throw new Error(text)
74
- }
75
- return data.stdout.trim()
76
- }
77
-
78
- /**
79
- * 获取指定仓库的提交记录
80
- * @param {{
81
- * path: string,
82
- * count?: number,
83
- * hash?: string
84
- * }} options - 参数
85
- * @param {string} options.path - 插件相对路径
86
- * @param {number} [options.count] - 获取日志条数 默认1条
87
- * @param {string} [options.hash] - 指定HEAD
88
- * @returns {Promise<string>}
89
- */
90
- async getCommit (options) {
91
- const { path, count = 1, hash, branch } = options
92
- let cmd = `git log -${count} --format="[%ad]%s %n" --date="format:%m-%d %H:%M"`
93
- /** 键入HEAD */
94
- if (hash) { cmd = `git log ${hash}..HEAD --format="[%ad] %s %n" --date="format:%m-%d %H:%M"` }
95
- /** 指定分支 */
96
- if (branch) { cmd = `git log -${count} ${branch} --format="[%ad] %s %n" --date="format:%m-%d %H:%M"` }
97
- const data = await exec(cmd, false, { cwd: path, encoding: 'utf-8' })
98
- if (data.status === 'failed') {
99
- const text = data.error
100
- throw new Error(text)
101
- }
102
- return data.stdout.trim()
103
- }
104
-
105
- /**
106
- * 检查插件是否有更新
107
- * @param {string} path - 插件相对路径
108
- * @param {number} [time] - 超时时间 默认120s
109
- * @returns {Promise<{status: 'ok'|'failed', data: string|boolean}>}
110
- */
111
- async checkUpdate (path, time = 120) {
112
- /** 检查一下路径是否存在 */
113
- if (!fs.existsSync(path)) { return { status: 'failed', data: '路径不存在' } }
114
- /** 检查是否有.git文件夹 */
115
- if (!fs.existsSync(`${path}/.git`)) { return { status: 'failed', data: '该路径不是一个git仓库' } }
116
- /** 设置超时时间 */
117
- const timer = setTimeout(() => {
118
- return { status: 'failed', data: '执行超时' }
119
- }, time * 1000)
120
- const options = { env: process.env, cwd: path, encoding: 'utf-8' }
121
- /** git fetch origin */
122
- const { status, error } = await exec('git fetch origin', false, options)
123
- if (status === 'failed') { return { status: 'failed', data: error?.message } }
124
- /** git status -uno */
125
- const { stdout } = await exec('git status -uno', false, options)
126
- clearTimeout(timer)
127
- /** 检查是否有更新 没更新直接返回 */
128
- if (stdout.includes('Your branch is up to date with')) { return { status: 'ok', data: false } }
129
- /** 获取落后几次更新 */
130
- const count = stdout.match(/Your branch is behind '.*' by (\d+) commits/)?.[1] || 1
131
- const data = await this.getCommit({ path, count, branch: 'origin' })
132
- return { status: 'ok', data, count }
133
- }
134
- })()
135
- export const Update = update