foliko 1.0.28 → 1.0.30
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/.claude/settings.local.json +78 -74
- package/SPEC.md +2 -2
- package/cli/bin/foliko.js +1 -1
- package/docs/quick-reference.md +1 -1
- package/docs/user-manual.md +4 -4
- package/examples/basic.js +110 -110
- package/examples/bootstrap.js +93 -93
- package/examples/mcp-example.js +53 -53
- package/examples/skill-example.js +49 -49
- package/examples/test-chat.js +2 -2
- package/examples/test-mcp.js +79 -79
- package/examples/test-reload.js +61 -61
- package/package.json +2 -1
- package/plugins/default-plugins.js +25 -2
- package/plugins/email.js +113 -43
- package/plugins/telegram-plugin.js +18 -7
- package/plugins/weixin-plugin.js +17 -5
- package/skills/{vb-agent-dev → foliko-dev}/AGENTS.md +1 -1
- package/src/core/framework.js +28 -0
- package/src/executors/executor-base.js +58 -58
- package/src/index.js +1 -1
- /package/skills/{vb-agent-dev → foliko-dev}/SKILL.md +0 -0
package/plugins/email.js
CHANGED
|
@@ -13,7 +13,18 @@ class EmailPlugin extends Plugin {
|
|
|
13
13
|
this.version = '1.0.0'
|
|
14
14
|
this.description = '邮件收发插件 - 支持读取和发送电子邮件'
|
|
15
15
|
this.priority = 10
|
|
16
|
-
|
|
16
|
+
// 默认不启用,需要在 plugins.json 中设置 enabled: true
|
|
17
|
+
this.enabled = false
|
|
18
|
+
// IMAP ID 信息
|
|
19
|
+
this.config = {
|
|
20
|
+
...config,
|
|
21
|
+
clientId: config.clientId || {
|
|
22
|
+
name: 'FolikoAgent',
|
|
23
|
+
version: '1.0.0',
|
|
24
|
+
vendor: 'Foliko',
|
|
25
|
+
supportEmail: config.imap?.user || 'unknown@example.com'
|
|
26
|
+
}
|
|
27
|
+
}
|
|
17
28
|
}
|
|
18
29
|
|
|
19
30
|
install(framework) {
|
|
@@ -105,9 +116,26 @@ class EmailPlugin extends Plugin {
|
|
|
105
116
|
imap_port: z.number().optional().describe('IMAP端口'),
|
|
106
117
|
imap_user: z.string().optional().describe('IMAP用户名'),
|
|
107
118
|
imap_pass: z.string().optional().describe('IMAP密码'),
|
|
108
|
-
from_email: z.string().optional().describe('默认发件人地址')
|
|
119
|
+
from_email: z.string().optional().describe('默认发件人地址'),
|
|
120
|
+
client_id_name: z.string().optional().describe('IMAP客户端名称'),
|
|
121
|
+
client_id_version: z.string().optional().describe('IMAP客户端版本'),
|
|
122
|
+
client_id_vendor: z.string().optional().describe('IMAP客户端厂商'),
|
|
123
|
+
client_id_support_email: z.string().optional().describe('IMAP客户端支持邮箱')
|
|
109
124
|
}),
|
|
110
125
|
execute: async (args) => {
|
|
126
|
+
// 处理 clientId 字段
|
|
127
|
+
if (args.client_id_name || args.client_id_version || args.client_id_vendor || args.client_id_support_email) {
|
|
128
|
+
this.config.clientId = {
|
|
129
|
+
name: args.client_id_name || this.config.clientId?.name || 'FolikoAgent',
|
|
130
|
+
version: args.client_id_version || this.config.clientId?.version || '1.0.0',
|
|
131
|
+
vendor: args.client_id_vendor || this.config.clientId?.vendor || 'Foliko',
|
|
132
|
+
supportEmail: args.client_id_support_email || this.config.clientId?.supportEmail
|
|
133
|
+
}
|
|
134
|
+
delete args.client_id_name
|
|
135
|
+
delete args.client_id_version
|
|
136
|
+
delete args.client_id_vendor
|
|
137
|
+
delete args.client_id_support_email
|
|
138
|
+
}
|
|
111
139
|
Object.assign(this.config, args)
|
|
112
140
|
return {
|
|
113
141
|
success: true,
|
|
@@ -163,7 +191,7 @@ class EmailPlugin extends Plugin {
|
|
|
163
191
|
|
|
164
192
|
async _readEmails(args) {
|
|
165
193
|
try {
|
|
166
|
-
const Imap = require('imap')
|
|
194
|
+
const Imap = require('imap-mkl')
|
|
167
195
|
const { simpleParser } = require('mailparser')
|
|
168
196
|
|
|
169
197
|
const imapConfig = {
|
|
@@ -172,7 +200,12 @@ class EmailPlugin extends Plugin {
|
|
|
172
200
|
host: args.host || this.config.imap_host || process.env.IMAP_HOST,
|
|
173
201
|
port: args.port || this.config.imap_port || 993,
|
|
174
202
|
tls: true,
|
|
175
|
-
tlsOptions: { rejectUnauthorized: false }
|
|
203
|
+
tlsOptions: { rejectUnauthorized: false },
|
|
204
|
+
id: {
|
|
205
|
+
name: this.config.clientId?.name || 'FolikoAgent',
|
|
206
|
+
version: this.config.clientId?.version || '1.0.0',
|
|
207
|
+
vendor: this.config.clientId?.vendor || 'Foliko'
|
|
208
|
+
}
|
|
176
209
|
}
|
|
177
210
|
|
|
178
211
|
const box = args.box || 'INBOX'
|
|
@@ -197,7 +230,7 @@ class EmailPlugin extends Plugin {
|
|
|
197
230
|
|
|
198
231
|
async _getUnreadCount(args) {
|
|
199
232
|
try {
|
|
200
|
-
const Imap = require('imap')
|
|
233
|
+
const Imap = require('imap-mkl')
|
|
201
234
|
|
|
202
235
|
const imapConfig = {
|
|
203
236
|
user: args.user || this.config.imap_user || process.env.IMAP_USER,
|
|
@@ -205,7 +238,13 @@ class EmailPlugin extends Plugin {
|
|
|
205
238
|
host: args.host || this.config.imap_host || process.env.IMAP_HOST,
|
|
206
239
|
port: args.port || this.config.imap_port || 993,
|
|
207
240
|
tls: true,
|
|
208
|
-
tlsOptions: { rejectUnauthorized: false }
|
|
241
|
+
tlsOptions: { rejectUnauthorized: false },
|
|
242
|
+
id: {
|
|
243
|
+
name: this.config.clientId?.name || 'FolikoAgent',
|
|
244
|
+
version: this.config.clientId?.version || '1.0.0',
|
|
245
|
+
vendor: this.config.clientId?.vendor || 'Foliko',
|
|
246
|
+
'support-email': this.config.clientId?.supportEmail || 'unknown@example.com'
|
|
247
|
+
}
|
|
209
248
|
}
|
|
210
249
|
|
|
211
250
|
const box = args.box || 'INBOX'
|
|
@@ -226,7 +265,7 @@ class EmailPlugin extends Plugin {
|
|
|
226
265
|
|
|
227
266
|
async _markAsRead(args) {
|
|
228
267
|
try {
|
|
229
|
-
const Imap = require('imap')
|
|
268
|
+
const Imap = require('imap-mkl')
|
|
230
269
|
|
|
231
270
|
const imapConfig = {
|
|
232
271
|
user: args.user || this.config.imap_user || process.env.IMAP_USER,
|
|
@@ -234,7 +273,13 @@ class EmailPlugin extends Plugin {
|
|
|
234
273
|
host: args.host || this.config.imap_host || process.env.IMAP_HOST,
|
|
235
274
|
port: args.port || this.config.imap_port || 993,
|
|
236
275
|
tls: true,
|
|
237
|
-
tlsOptions: { rejectUnauthorized: false }
|
|
276
|
+
tlsOptions: { rejectUnauthorized: false },
|
|
277
|
+
id: {
|
|
278
|
+
name: this.config.clientId?.name || 'FolikoAgent',
|
|
279
|
+
version: this.config.clientId?.version || '1.0.0',
|
|
280
|
+
vendor: this.config.clientId?.vendor || 'Foliko',
|
|
281
|
+
'support-email': this.config.clientId?.supportEmail || 'unknown@example.com'
|
|
282
|
+
}
|
|
238
283
|
}
|
|
239
284
|
|
|
240
285
|
await this._markEmailAsRead(imapConfig, args.messageId)
|
|
@@ -253,13 +298,19 @@ class EmailPlugin extends Plugin {
|
|
|
253
298
|
|
|
254
299
|
_fetchEmails(imapConfig, box, limit, unreadOnly, searchCriteria) {
|
|
255
300
|
return new Promise((resolve, reject) => {
|
|
301
|
+
const Imap = require('imap-mkl')
|
|
302
|
+
const { simpleParser } = require('mailparser')
|
|
256
303
|
const imap = new Imap(imapConfig)
|
|
257
304
|
const emails = []
|
|
258
305
|
|
|
259
|
-
|
|
306
|
+
const cleanup = () => {
|
|
307
|
+
try { imap.end() } catch (e) {}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
imap.on('ready', () => {
|
|
260
311
|
imap.openBox(box, true, (err) => {
|
|
261
312
|
if (err) {
|
|
262
|
-
|
|
313
|
+
cleanup()
|
|
263
314
|
return reject(err)
|
|
264
315
|
}
|
|
265
316
|
|
|
@@ -270,106 +321,125 @@ class EmailPlugin extends Plugin {
|
|
|
270
321
|
|
|
271
322
|
imap.search(searchFilter, (err, results) => {
|
|
272
323
|
if (err) {
|
|
273
|
-
|
|
324
|
+
cleanup()
|
|
274
325
|
return reject(err)
|
|
275
326
|
}
|
|
276
327
|
|
|
277
|
-
if (results.length === 0) {
|
|
278
|
-
|
|
328
|
+
if (!results || results.length === 0) {
|
|
329
|
+
cleanup()
|
|
279
330
|
return resolve([])
|
|
280
331
|
}
|
|
281
332
|
|
|
282
333
|
const fetchIds = results.slice(-limit)
|
|
334
|
+
const f = imap.fetch(fetchIds, { bodies: '' })
|
|
283
335
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
struct: true
|
|
287
|
-
})
|
|
288
|
-
|
|
289
|
-
f.on('message', (msg, seqno) => {
|
|
290
|
-
const email = { seqno }
|
|
336
|
+
f.on('message', (msg) => {
|
|
337
|
+
const email = {}
|
|
291
338
|
|
|
292
339
|
msg.on('body', (stream) => {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
340
|
+
simpleParser(stream, (err, mail) => {
|
|
341
|
+
if (err) {
|
|
342
|
+
email.error = err.message
|
|
343
|
+
} else {
|
|
344
|
+
email.subject = mail.subject
|
|
345
|
+
email.from = mail.from?.text || ''
|
|
346
|
+
email.to = mail.to?.text || ''
|
|
347
|
+
email.date = mail.date?.toISOString() || ''
|
|
348
|
+
email.text = mail.text
|
|
349
|
+
email.html = mail.html
|
|
350
|
+
email.attachments = mail.attachments?.map(a => ({
|
|
351
|
+
filename: a.filename,
|
|
352
|
+
contentType: a.contentType
|
|
353
|
+
})) || []
|
|
354
|
+
}
|
|
301
355
|
})
|
|
302
356
|
})
|
|
303
357
|
|
|
304
|
-
msg.
|
|
358
|
+
msg.on('attributes', (attrs) => {
|
|
305
359
|
email.uid = attrs.uid
|
|
306
360
|
email.id = attrs.uid
|
|
307
361
|
email.flags = attrs.flags
|
|
308
362
|
})
|
|
309
363
|
|
|
310
|
-
msg.
|
|
364
|
+
msg.on('end', () => {
|
|
311
365
|
emails.push(email)
|
|
312
366
|
})
|
|
313
367
|
})
|
|
314
368
|
|
|
315
|
-
f.
|
|
316
|
-
|
|
369
|
+
f.on('error', (err) => {
|
|
370
|
+
cleanup()
|
|
317
371
|
reject(err)
|
|
318
372
|
})
|
|
319
373
|
|
|
320
|
-
f.
|
|
321
|
-
|
|
374
|
+
f.on('end', () => {
|
|
375
|
+
cleanup()
|
|
322
376
|
resolve(emails)
|
|
323
377
|
})
|
|
324
378
|
})
|
|
325
379
|
})
|
|
326
380
|
})
|
|
327
381
|
|
|
328
|
-
imap.
|
|
382
|
+
imap.on('error', (err) => reject(err))
|
|
383
|
+
imap.on('end', () => {})
|
|
384
|
+
|
|
329
385
|
imap.connect()
|
|
330
386
|
})
|
|
331
387
|
}
|
|
332
388
|
|
|
333
389
|
_fetchUnreadCount(imapConfig, box) {
|
|
334
390
|
return new Promise((resolve, reject) => {
|
|
391
|
+
const Imap = require('imap-mkl')
|
|
335
392
|
const imap = new Imap(imapConfig)
|
|
336
393
|
|
|
337
|
-
|
|
394
|
+
const cleanup = () => {
|
|
395
|
+
try { imap.end() } catch (e) {}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
imap.on('ready', () => {
|
|
338
399
|
imap.openBox(box, true, (err, box) => {
|
|
339
400
|
if (err) {
|
|
340
|
-
|
|
401
|
+
cleanup()
|
|
341
402
|
return reject(err)
|
|
342
403
|
}
|
|
343
404
|
const unreadCount = box.messages.unread
|
|
344
|
-
|
|
405
|
+
cleanup()
|
|
345
406
|
resolve(unreadCount)
|
|
346
407
|
})
|
|
347
408
|
})
|
|
348
409
|
|
|
349
|
-
imap.
|
|
410
|
+
imap.on('error', (err) => reject(err))
|
|
411
|
+
imap.on('end', () => {})
|
|
412
|
+
|
|
350
413
|
imap.connect()
|
|
351
414
|
})
|
|
352
415
|
}
|
|
353
416
|
|
|
354
417
|
_markEmailAsRead(imapConfig, messageId) {
|
|
355
418
|
return new Promise((resolve, reject) => {
|
|
419
|
+
const Imap = require('imap-mkl')
|
|
356
420
|
const imap = new Imap(imapConfig)
|
|
357
421
|
|
|
358
|
-
|
|
422
|
+
const cleanup = () => {
|
|
423
|
+
try { imap.end() } catch (e) {}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
imap.on('ready', () => {
|
|
359
427
|
imap.openBox('INBOX', true, (err) => {
|
|
360
428
|
if (err) {
|
|
361
|
-
|
|
429
|
+
cleanup()
|
|
362
430
|
return reject(err)
|
|
363
431
|
}
|
|
364
432
|
imap.addFlags(messageId, '\\Seen', (err) => {
|
|
365
|
-
|
|
433
|
+
cleanup()
|
|
366
434
|
if (err) reject(err)
|
|
367
435
|
else resolve()
|
|
368
436
|
})
|
|
369
437
|
})
|
|
370
438
|
})
|
|
371
439
|
|
|
372
|
-
imap.
|
|
440
|
+
imap.on('error', (err) => reject(err))
|
|
441
|
+
imap.on('end', () => {})
|
|
442
|
+
|
|
373
443
|
imap.connect()
|
|
374
444
|
})
|
|
375
445
|
}
|
|
@@ -42,6 +42,7 @@ module.exports = function(Plugin) {
|
|
|
42
42
|
this._bot = null
|
|
43
43
|
this._sessionPlugin = null
|
|
44
44
|
this._sessionDeleteHandler = null
|
|
45
|
+
this._sessionAgents = new Map() // chatId -> Agent
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
install(framework) {
|
|
@@ -203,18 +204,22 @@ module.exports = function(Plugin) {
|
|
|
203
204
|
_getSessionAgent(chatId) {
|
|
204
205
|
console.log('[Telegram] _getSessionAgent called for chatId:', chatId)
|
|
205
206
|
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
console.log('[Telegram]
|
|
211
|
-
return
|
|
207
|
+
// 检查缓存
|
|
208
|
+
if (this._sessionAgents.has(chatId)) {
|
|
209
|
+
const agent = this._sessionAgents.get(chatId)
|
|
210
|
+
const sessionId = `telegram_${chatId}`
|
|
211
|
+
console.log('[Telegram] Reusing cached session agent for chatId:', chatId)
|
|
212
|
+
return { agent, sessionId }
|
|
212
213
|
}
|
|
213
214
|
|
|
215
|
+
// 创建新 agent
|
|
216
|
+
const agent = this._framework.createSessionAgent(`telegram_${chatId}`)
|
|
217
|
+
this._sessionAgents.set(chatId, agent)
|
|
218
|
+
console.log('[Telegram] Created new session agent for chatId:', chatId)
|
|
219
|
+
|
|
214
220
|
// 使用 SessionPlugin 管理会话历史
|
|
215
221
|
if (this._sessionPlugin) {
|
|
216
222
|
const sessionId = `telegram_${chatId}`
|
|
217
|
-
// 确保会话存在(不会重复创建)
|
|
218
223
|
this._sessionPlugin.getOrCreateSession(sessionId, {
|
|
219
224
|
metadata: { platform: 'telegram', chatId }
|
|
220
225
|
})
|
|
@@ -604,6 +609,12 @@ module.exports = function(Plugin) {
|
|
|
604
609
|
}
|
|
605
610
|
|
|
606
611
|
uninstall(framework) {
|
|
612
|
+
// 销毁所有 session agents
|
|
613
|
+
for (const agent of this._sessionAgents.values()) {
|
|
614
|
+
agent.destroy()
|
|
615
|
+
}
|
|
616
|
+
this._sessionAgents.clear()
|
|
617
|
+
|
|
607
618
|
this.stopBot()
|
|
608
619
|
if (this._sessionPlugin && this._sessionDeleteHandler) {
|
|
609
620
|
this._sessionPlugin.off('session:deleted', this._sessionDeleteHandler)
|
package/plugins/weixin-plugin.js
CHANGED
|
@@ -32,6 +32,7 @@ module.exports = function(Plugin) {
|
|
|
32
32
|
this._bot = null
|
|
33
33
|
this._sessionPlugin = null
|
|
34
34
|
this._sessionDeleteHandler = null
|
|
35
|
+
this._sessionAgents = new Map() // userId -> Agent
|
|
35
36
|
this._qrcodeTerminal = null
|
|
36
37
|
this._origStderrWrite = null
|
|
37
38
|
this._initialized = false
|
|
@@ -150,13 +151,18 @@ module.exports = function(Plugin) {
|
|
|
150
151
|
* 使用 SessionPlugin 统一管理会话历史
|
|
151
152
|
*/
|
|
152
153
|
_getSessionAgent(userId) {
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
console.log('[WeChat]
|
|
157
|
-
return
|
|
154
|
+
// 检查缓存
|
|
155
|
+
if (this._sessionAgents.has(userId)) {
|
|
156
|
+
const agent = this._sessionAgents.get(userId)
|
|
157
|
+
console.log('[WeChat] Reusing cached session agent for userId:', userId)
|
|
158
|
+
return { agent, sessionId: `weixin_${userId}` }
|
|
158
159
|
}
|
|
159
160
|
|
|
161
|
+
// 创建新 agent
|
|
162
|
+
const agent = this._framework.createSessionAgent(`weixin_${userId}`)
|
|
163
|
+
this._sessionAgents.set(userId, agent)
|
|
164
|
+
console.log('[WeChat] Created new session agent for userId:', userId)
|
|
165
|
+
|
|
160
166
|
// 使用 SessionPlugin 管理会话历史
|
|
161
167
|
if (this._sessionPlugin) {
|
|
162
168
|
const sessionId = `weixin_${userId}`
|
|
@@ -319,6 +325,12 @@ module.exports = function(Plugin) {
|
|
|
319
325
|
}
|
|
320
326
|
|
|
321
327
|
uninstall(framework) {
|
|
328
|
+
// 销毁所有 session agents
|
|
329
|
+
for (const agent of this._sessionAgents.values()) {
|
|
330
|
+
agent.destroy()
|
|
331
|
+
}
|
|
332
|
+
this._sessionAgents.clear()
|
|
333
|
+
|
|
322
334
|
this.stopBot()
|
|
323
335
|
if (this._sessionPlugin && this._sessionDeleteHandler) {
|
|
324
336
|
this._sessionPlugin.off('session:deleted', this._sessionDeleteHandler)
|
package/src/core/framework.js
CHANGED
|
@@ -170,6 +170,34 @@ class Framework extends EventEmitter {
|
|
|
170
170
|
return agent
|
|
171
171
|
}
|
|
172
172
|
|
|
173
|
+
/**
|
|
174
|
+
* 为指定 session 创建独立的 Agent 实例
|
|
175
|
+
* @param {string} sessionId - session ID
|
|
176
|
+
* @param {Object} config - Agent 配置
|
|
177
|
+
*/
|
|
178
|
+
createSessionAgent(sessionId, config = {}) {
|
|
179
|
+
const agentConfig = {
|
|
180
|
+
name: `session_${sessionId}`,
|
|
181
|
+
...config
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// 如果没有提供 AI 相关参数,从 AI 插件获取
|
|
185
|
+
if (!agentConfig.apiKey) {
|
|
186
|
+
const aiPlugin = this.pluginManager.get('ai')
|
|
187
|
+
if (aiPlugin) {
|
|
188
|
+
agentConfig.apiKey = aiPlugin.config.apiKey
|
|
189
|
+
agentConfig.provider = agentConfig.provider || aiPlugin.config.provider
|
|
190
|
+
agentConfig.model = agentConfig.model || aiPlugin.config.model
|
|
191
|
+
agentConfig.baseURL = agentConfig.baseURL || aiPlugin.config.baseURL
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const agent = new Agent(this, agentConfig)
|
|
196
|
+
this._agents.push(agent)
|
|
197
|
+
this.emit('agent:created', agent)
|
|
198
|
+
return agent
|
|
199
|
+
}
|
|
200
|
+
|
|
173
201
|
/**
|
|
174
202
|
* 获取 AI 插件
|
|
175
203
|
* @returns {Object|undefined}
|
|
@@ -1,58 +1,58 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Executor 基类
|
|
3
|
-
* 执行器的基类,定义执行器接口
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
const { EventEmitter } = require('../utils/event-emitter')
|
|
7
|
-
|
|
8
|
-
class ExecutorBase extends EventEmitter {
|
|
9
|
-
/**
|
|
10
|
-
* @param {string} name - 执行器名称
|
|
11
|
-
*/
|
|
12
|
-
constructor(name) {
|
|
13
|
-
super()
|
|
14
|
-
this.name = name
|
|
15
|
-
this._enabled = true
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* 执行
|
|
20
|
-
* @param {Object} params - 执行参数
|
|
21
|
-
* @returns {Promise<any>}
|
|
22
|
-
*/
|
|
23
|
-
async execute(params) {
|
|
24
|
-
throw new Error('execute() must be implemented')
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* 启用执行器
|
|
29
|
-
*/
|
|
30
|
-
enable() {
|
|
31
|
-
this._enabled = true
|
|
32
|
-
return this
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* 禁用执行器
|
|
37
|
-
*/
|
|
38
|
-
disable() {
|
|
39
|
-
this._enabled = false
|
|
40
|
-
return this
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* 是否启用
|
|
45
|
-
*/
|
|
46
|
-
isEnabled() {
|
|
47
|
-
return this._enabled
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* 销毁
|
|
52
|
-
*/
|
|
53
|
-
destroy() {
|
|
54
|
-
this.removeAllListeners()
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
module.exports = { ExecutorBase }
|
|
1
|
+
/**
|
|
2
|
+
* Executor 基类
|
|
3
|
+
* 执行器的基类,定义执行器接口
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const { EventEmitter } = require('../utils/event-emitter')
|
|
7
|
+
|
|
8
|
+
class ExecutorBase extends EventEmitter {
|
|
9
|
+
/**
|
|
10
|
+
* @param {string} name - 执行器名称
|
|
11
|
+
*/
|
|
12
|
+
constructor(name) {
|
|
13
|
+
super()
|
|
14
|
+
this.name = name
|
|
15
|
+
this._enabled = true
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* 执行
|
|
20
|
+
* @param {Object} params - 执行参数
|
|
21
|
+
* @returns {Promise<any>}
|
|
22
|
+
*/
|
|
23
|
+
async execute(params) {
|
|
24
|
+
throw new Error('execute() must be implemented')
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 启用执行器
|
|
29
|
+
*/
|
|
30
|
+
enable() {
|
|
31
|
+
this._enabled = true
|
|
32
|
+
return this
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* 禁用执行器
|
|
37
|
+
*/
|
|
38
|
+
disable() {
|
|
39
|
+
this._enabled = false
|
|
40
|
+
return this
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* 是否启用
|
|
45
|
+
*/
|
|
46
|
+
isEnabled() {
|
|
47
|
+
return this._enabled
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* 销毁
|
|
52
|
+
*/
|
|
53
|
+
destroy() {
|
|
54
|
+
this.removeAllListeners()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
module.exports = { ExecutorBase }
|
package/src/index.js
CHANGED
|
File without changes
|