@kotori-bot/core 1.1.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/LICENSE +674 -0
- package/lib/base/command.d.ts +20 -0
- package/lib/base/command.js +217 -0
- package/lib/base/core.d.ts +30 -0
- package/lib/base/core.js +52 -0
- package/lib/base/events.d.ts +13 -0
- package/lib/base/events.js +41 -0
- package/lib/base/filter.d.ts +1 -0
- package/lib/base/filter.js +2 -0
- package/lib/base/internal.d.ts +34 -0
- package/lib/base/internal.js +89 -0
- package/lib/base/message.d.ts +18 -0
- package/lib/base/message.js +177 -0
- package/lib/base/modules.d.ts +15 -0
- package/lib/base/modules.js +205 -0
- package/lib/components/adapter.d.ts +38 -0
- package/lib/components/adapter.js +128 -0
- package/lib/components/api.d.ts +35 -0
- package/lib/components/api.js +47 -0
- package/lib/components/elements.d.ts +12 -0
- package/lib/components/elements.js +28 -0
- package/lib/components/service.d.ts +13 -0
- package/lib/components/service.js +7 -0
- package/lib/consts.d.ts +11 -0
- package/lib/consts.js +13 -0
- package/lib/context.d.ts +13 -0
- package/lib/context.js +35 -0
- package/lib/index.d.ts +17 -0
- package/lib/index.js +43 -0
- package/lib/types.d.ts +417 -0
- package/lib/types.js +81 -0
- package/lib/utils/commandExtra.d.ts +6 -0
- package/lib/utils/commandExtra.js +11 -0
- package/lib/utils/errror.d.ts +41 -0
- package/lib/utils/errror.js +34 -0
- package/lib/utils/i18n.d.ts +13 -0
- package/lib/utils/i18n.js +65 -0
- package/lib/utils/jsxFactory.d.ts +6 -0
- package/lib/utils/jsxFactory.js +2 -0
- package/package.json +30 -0
|
@@ -0,0 +1,177 @@
|
|
|
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.Message = void 0;
|
|
7
|
+
const tsukiko_1 = __importDefault(require("tsukiko"));
|
|
8
|
+
const tools_1 = require("@kotori-bot/tools");
|
|
9
|
+
const modules_1 = __importDefault(require("./modules"));
|
|
10
|
+
const command_1 = __importDefault(require("./command"));
|
|
11
|
+
const errror_1 = require("../utils/errror");
|
|
12
|
+
const commandExtra_1 = __importDefault(require("../utils/commandExtra"));
|
|
13
|
+
class Message extends modules_1.default {
|
|
14
|
+
midwareStack = [];
|
|
15
|
+
/* two commands data array kill them! */
|
|
16
|
+
commandStack = [];
|
|
17
|
+
regexpStack = [];
|
|
18
|
+
handleMessageEvent(session) {
|
|
19
|
+
/* Handle middle wares */
|
|
20
|
+
let isPass = true;
|
|
21
|
+
const midwareStack = Object.create(this.midwareStack);
|
|
22
|
+
let lastMidwareNum = -1;
|
|
23
|
+
while (midwareStack.length > 0) {
|
|
24
|
+
if (lastMidwareNum === midwareStack.length) {
|
|
25
|
+
isPass = false;
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
lastMidwareNum = midwareStack.length;
|
|
29
|
+
session.quick(midwareStack[0].callback(() => midwareStack.shift(), session));
|
|
30
|
+
}
|
|
31
|
+
this.emit('midwares', { isPass, event: session });
|
|
32
|
+
}
|
|
33
|
+
async handleMidwaresEvent(session) {
|
|
34
|
+
const { isPass, event } = session;
|
|
35
|
+
event.api.adapter.status.receivedMsg += 1;
|
|
36
|
+
if (!isPass)
|
|
37
|
+
return;
|
|
38
|
+
/* Handle regexp */
|
|
39
|
+
this.regexpStack.forEach(element => {
|
|
40
|
+
const match = event.message.match(element.match);
|
|
41
|
+
if (!match)
|
|
42
|
+
return;
|
|
43
|
+
event.quick(element.callback(match, event));
|
|
44
|
+
});
|
|
45
|
+
/* Handle command */
|
|
46
|
+
const params = [event.message, event.api.adapter.config['command-prefix']];
|
|
47
|
+
if (!params[0].startsWith(params[1]))
|
|
48
|
+
return;
|
|
49
|
+
const commonParams = {
|
|
50
|
+
event,
|
|
51
|
+
command: (0, tools_1.stringRightSplit)(params[0], params[1]),
|
|
52
|
+
};
|
|
53
|
+
this.emit('before_parse', commonParams);
|
|
54
|
+
let isCancel = false;
|
|
55
|
+
const cancel = () => {
|
|
56
|
+
isCancel = true;
|
|
57
|
+
};
|
|
58
|
+
const commandParams = {
|
|
59
|
+
scope: event.type === 'group_msg' ? 'group' : 'private',
|
|
60
|
+
access: event.userId === event.api.adapter.config.master ? 2 /* CommandAccess.ADMIN */ : 0 /* CommandAccess.MEMBER */,
|
|
61
|
+
};
|
|
62
|
+
this.emit('before_command', { cancel, ...commonParams, ...commandParams });
|
|
63
|
+
if (isCancel)
|
|
64
|
+
return;
|
|
65
|
+
try {
|
|
66
|
+
command_1.default.parse(commonParams.command);
|
|
67
|
+
}
|
|
68
|
+
catch (err) {
|
|
69
|
+
if (!(err instanceof errror_1.CommandError) || !(err.extra instanceof commandExtra_1.default))
|
|
70
|
+
throw err;
|
|
71
|
+
const parseResult = err.extra.value;
|
|
72
|
+
const isSuccessParsed = parseResult.type === 'parsed';
|
|
73
|
+
this.emit('parse', { result: parseResult, ...commonParams, cancel });
|
|
74
|
+
if (isCancel)
|
|
75
|
+
return;
|
|
76
|
+
if (!isSuccessParsed)
|
|
77
|
+
throw err;
|
|
78
|
+
try {
|
|
79
|
+
const executedResult = await parseResult.action({ args: parseResult.args, options: parseResult.options }, event);
|
|
80
|
+
if (tsukiko_1.default.Object({}).index(tsukiko_1.default.Unknown()).check(executedResult)) {
|
|
81
|
+
this.emit('command', { result: executedResult, ...commonParams, ...commandParams });
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const objectTemp = (obj) => {
|
|
85
|
+
const result = obj;
|
|
86
|
+
Object.keys(result).forEach(key => {
|
|
87
|
+
if (!result[key] || typeof result[key] !== 'string')
|
|
88
|
+
return;
|
|
89
|
+
result[key] = event.locale(result[key]);
|
|
90
|
+
});
|
|
91
|
+
return result;
|
|
92
|
+
};
|
|
93
|
+
const returnHandle = Array.isArray(executedResult)
|
|
94
|
+
? (0, tools_1.stringTemp)(event.locale(executedResult[0]), objectTemp(executedResult[1]))
|
|
95
|
+
: event.locale(executedResult ?? '');
|
|
96
|
+
this.emit('command', {
|
|
97
|
+
result: { type: 'success', return: returnHandle ?? undefined },
|
|
98
|
+
...commonParams,
|
|
99
|
+
...commandParams,
|
|
100
|
+
});
|
|
101
|
+
if (returnHandle)
|
|
102
|
+
event.send(returnHandle);
|
|
103
|
+
}
|
|
104
|
+
catch (executeErr) {
|
|
105
|
+
this.emit('command', {
|
|
106
|
+
result: { type: 'error', error: executeErr },
|
|
107
|
+
...commonParams,
|
|
108
|
+
...commandParams,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
handleUnloadModuleEvent(session) {
|
|
114
|
+
if (!session.module)
|
|
115
|
+
return;
|
|
116
|
+
const superArr = [...this.midwareStack, ...this.commandStack, ...this.regexpStack];
|
|
117
|
+
Object.keys(superArr).forEach(indexTemp => {
|
|
118
|
+
if (!session.module)
|
|
119
|
+
return;
|
|
120
|
+
const index = parseInt(indexTemp, 10);
|
|
121
|
+
const element = superArr[index];
|
|
122
|
+
if (element.extend === session.module.mainPath)
|
|
123
|
+
delete superArr[index];
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
registeMessageEvent() {
|
|
127
|
+
this.on('midwares', session => this.handleMidwaresEvent(session));
|
|
128
|
+
this.on('group_msg', session => this.handleMessageEvent(session));
|
|
129
|
+
this.on('private_msg', session => this.handleMessageEvent(session));
|
|
130
|
+
this.before('send', session => {
|
|
131
|
+
const { api } = session;
|
|
132
|
+
api.adapter.status.sentMsg += 1;
|
|
133
|
+
});
|
|
134
|
+
this.on('unload_module', session => this.handleUnloadModuleEvent(session));
|
|
135
|
+
}
|
|
136
|
+
midware(callback, priority = 100) {
|
|
137
|
+
if (this.midwareStack.filter(Element => Element.callback === callback).length)
|
|
138
|
+
return false;
|
|
139
|
+
this.midwareStack.push({ callback, priority, extend: this.getCurrent() });
|
|
140
|
+
this.midwareStack.sort((first, second) => first.priority - second.priority);
|
|
141
|
+
return true;
|
|
142
|
+
}
|
|
143
|
+
command(template, config) {
|
|
144
|
+
const result = new command_1.default(template, config);
|
|
145
|
+
this.commandStack.push({
|
|
146
|
+
extend: this.getCurrent(),
|
|
147
|
+
data: command_1.default.dataList[command_1.default.dataList.length - 1],
|
|
148
|
+
});
|
|
149
|
+
return result;
|
|
150
|
+
}
|
|
151
|
+
regexp(match, callback) {
|
|
152
|
+
if (this.regexpStack.filter(Element => Element.match === match).length)
|
|
153
|
+
return false;
|
|
154
|
+
this.regexpStack.push({ extend: this.getCurrent(), match, callback });
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
boardcast(type, message) {
|
|
158
|
+
const send = type === 'private'
|
|
159
|
+
? (api) => api.send_private_msg(message, 1)
|
|
160
|
+
: (api) => api.send_group_msg(message, 1);
|
|
161
|
+
/* this need support of database... */
|
|
162
|
+
Object.values(this.botStack).forEach(apis => {
|
|
163
|
+
/* feating... */
|
|
164
|
+
apis.forEach(api => send(api));
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
notify(message) {
|
|
168
|
+
const mainAdapterIdentity = Object.keys(this.config.adapter)[0];
|
|
169
|
+
Object.values(this.botStack).forEach(apis => apis.forEach(api => {
|
|
170
|
+
if (api.adapter.identity !== mainAdapterIdentity)
|
|
171
|
+
return;
|
|
172
|
+
api.send_private_msg(message, api.adapter.config.master);
|
|
173
|
+
}));
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
exports.Message = Message;
|
|
177
|
+
exports.default = Message;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import Events from './events';
|
|
2
|
+
import Context from '../context';
|
|
3
|
+
import { type ModuleData, type ModuleInstanceConstructor, type ModuleInstanceFunction } from '../types';
|
|
4
|
+
export declare class Modules extends Events {
|
|
5
|
+
private current;
|
|
6
|
+
private failedLoadCount;
|
|
7
|
+
protected getCurrent(): string;
|
|
8
|
+
private setCureent;
|
|
9
|
+
private runInstance;
|
|
10
|
+
private moduleAllHandle;
|
|
11
|
+
protected readonly moduleStack: ModuleData[];
|
|
12
|
+
use(summary: string | ModuleData | ModuleInstanceFunction | ModuleInstanceConstructor, ctx: Context, config: object): Promise<void>;
|
|
13
|
+
dispose(module: string | ModuleData): void;
|
|
14
|
+
}
|
|
15
|
+
export default Modules;
|
|
@@ -0,0 +1,205 @@
|
|
|
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
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.Modules = void 0;
|
|
30
|
+
const tools_1 = require("@kotori-bot/tools");
|
|
31
|
+
const fs_1 = __importDefault(require("fs"));
|
|
32
|
+
const tsukiko_1 = __importStar(require("tsukiko"));
|
|
33
|
+
const path_1 = require("path");
|
|
34
|
+
const events_1 = __importDefault(require("./events"));
|
|
35
|
+
const adapter_1 = __importDefault(require("../components/adapter"));
|
|
36
|
+
const errror_1 = require("../utils/errror");
|
|
37
|
+
const consts_1 = require("../consts");
|
|
38
|
+
function getTypeInfo(Instance, moduleName) {
|
|
39
|
+
let type = 'plugin';
|
|
40
|
+
let instanceType = 'none';
|
|
41
|
+
if ((0, tools_1.isClass)(Instance)) {
|
|
42
|
+
instanceType = 'constructor';
|
|
43
|
+
const func = (Obj) => adapter_1.default.isPrototypeOf.call(adapter_1.default, Obj);
|
|
44
|
+
const adapterName = moduleName.split(consts_1.ADAPTER_PREFIX)[1];
|
|
45
|
+
if (adapterName && func(Instance)) {
|
|
46
|
+
type = 'adapter';
|
|
47
|
+
return { type, instanceType, moduleName, adapterName };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else if (Instance instanceof Function) {
|
|
51
|
+
instanceType = 'function';
|
|
52
|
+
return { type, instanceType, moduleName };
|
|
53
|
+
}
|
|
54
|
+
return { type, instanceType, moduleName };
|
|
55
|
+
}
|
|
56
|
+
class Modules extends events_1.default {
|
|
57
|
+
current = 'core';
|
|
58
|
+
failedLoadCount = 0;
|
|
59
|
+
getCurrent() {
|
|
60
|
+
return this.current;
|
|
61
|
+
}
|
|
62
|
+
setCureent(value) {
|
|
63
|
+
const defaultValue = 'core';
|
|
64
|
+
return new Promise((resolve, reject) => {
|
|
65
|
+
if (!value) {
|
|
66
|
+
this.current = defaultValue;
|
|
67
|
+
resolve(null);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const failTime = setTimeout(() => {
|
|
71
|
+
clearTimeout(failTime);
|
|
72
|
+
clearInterval(sleepTime);
|
|
73
|
+
reject(new errror_1.ModuleError(`Module loading timeout ${value}`));
|
|
74
|
+
}, consts_1.LOAD_MODULE_MAX_TIME);
|
|
75
|
+
const sleepTime = setInterval(() => {
|
|
76
|
+
if (this.current === defaultValue) {
|
|
77
|
+
this.current = value;
|
|
78
|
+
clearTimeout(failTime);
|
|
79
|
+
clearInterval(sleepTime);
|
|
80
|
+
resolve(null);
|
|
81
|
+
}
|
|
82
|
+
}, consts_1.LOAD_MODULE_SLEEP_TIME);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
runInstance(typeInfo, Instances, data) {
|
|
86
|
+
/* before handle */
|
|
87
|
+
if (data.langDir)
|
|
88
|
+
data.ctx.i18n.use(typeof data.langDir === 'string' ? (0, path_1.resolve)(data.langDir) : (0, path_1.resolve)(...data.langDir)); /* here need */
|
|
89
|
+
/* after handle */
|
|
90
|
+
if (typeInfo.type === 'adapter') {
|
|
91
|
+
this.adapterStack[typeInfo.adapterName] = [Instances[0], Instances[1]];
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (typeInfo.instanceType === 'none')
|
|
95
|
+
return;
|
|
96
|
+
/* Check config */
|
|
97
|
+
const isSchema = Instances[1]?.parseSafe(data.config);
|
|
98
|
+
if (isSchema && !isSchema.value) {
|
|
99
|
+
throw new errror_1.ModuleError(`Config format of module ${typeInfo.moduleName} is error`);
|
|
100
|
+
}
|
|
101
|
+
if (typeInfo.instanceType === 'constructor') {
|
|
102
|
+
(0, tools_1.none)(new Instances[0](data.ctx, data.config));
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
Instances[0](data.ctx, data.config);
|
|
106
|
+
}
|
|
107
|
+
moduleAllHandle() {
|
|
108
|
+
this.emit('load_all_module', {
|
|
109
|
+
reality: this.moduleStack.length - this.failedLoadCount,
|
|
110
|
+
expected: this.moduleStack.length,
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
moduleStack = [];
|
|
114
|
+
async use(summary, ctx, config) {
|
|
115
|
+
const isString = typeof summary === 'string';
|
|
116
|
+
const isFunc = summary instanceof Function;
|
|
117
|
+
let Instance;
|
|
118
|
+
let typeInfo;
|
|
119
|
+
let exportObj;
|
|
120
|
+
const isLast = !isString && !isFunc && summary === this.moduleStack[this.moduleStack.length - 1];
|
|
121
|
+
try {
|
|
122
|
+
if (isFunc) {
|
|
123
|
+
typeInfo = getTypeInfo(summary, '');
|
|
124
|
+
Instance = summary;
|
|
125
|
+
exportObj = null;
|
|
126
|
+
}
|
|
127
|
+
else {
|
|
128
|
+
const moduleName = isString ? summary : summary.package.name;
|
|
129
|
+
const modulePath = `file://${isString ? summary : summary.mainPath}`;
|
|
130
|
+
if (isString && !fs_1.default.existsSync(summary))
|
|
131
|
+
throw new errror_1.ModuleError(`Cannot find ${modulePath}`);
|
|
132
|
+
await this.setCureent(modulePath);
|
|
133
|
+
exportObj = await import(modulePath);
|
|
134
|
+
if (!tsukiko_1.default.Object({}).index(tsukiko_1.default.Unknown()).check(exportObj)) {
|
|
135
|
+
throw new errror_1.DevError(`Not a valid module at ${modulePath}`);
|
|
136
|
+
}
|
|
137
|
+
exportObj = tsukiko_1.default.Object({}).index(tsukiko_1.default.Unknown()).check(exportObj.default) ? exportObj.default : exportObj;
|
|
138
|
+
if (exportObj.default instanceof Function) {
|
|
139
|
+
typeInfo = getTypeInfo(exportObj.default, moduleName);
|
|
140
|
+
Instance = exportObj.default;
|
|
141
|
+
}
|
|
142
|
+
else if (exportObj.main instanceof Function && !(0, tools_1.isClass)(exportObj.main)) {
|
|
143
|
+
typeInfo = getTypeInfo(exportObj.main, moduleName);
|
|
144
|
+
Instance = exportObj.main;
|
|
145
|
+
if (typeInfo.instanceType !== 'function') {
|
|
146
|
+
throw new errror_1.DevError(`Module instance is function,export name should be 'main' at ${modulePath}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
else if (exportObj.Main instanceof Function && (0, tools_1.isClass)(exportObj.Main)) {
|
|
150
|
+
typeInfo = getTypeInfo(exportObj.Main, moduleName);
|
|
151
|
+
Instance = exportObj.Main;
|
|
152
|
+
if (typeInfo.instanceType !== 'constructor') {
|
|
153
|
+
throw new errror_1.DevError(`Module instance is constructor,export name should be 'Main' at ${modulePath}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
typeInfo = getTypeInfo(null, moduleName);
|
|
158
|
+
Instance = null;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
const schema = exportObj && exportObj.config instanceof tsukiko_1.Parser ? exportObj.config : undefined;
|
|
162
|
+
this.runInstance(typeInfo, [Instance, schema], {
|
|
163
|
+
/* wait for logger updated after hered need new 功能 about print module of name */
|
|
164
|
+
/* Object.assign(ctx, {
|
|
165
|
+
logger: ctx.logger.tag(stringRightSplit(typeInfo.moduleName, PLUGIN_PREFIX), 'italic', 'white'),
|
|
166
|
+
}) */ ctx,
|
|
167
|
+
config,
|
|
168
|
+
langDir: exportObj && (typeof exportObj.lang === 'string' || Array.isArray(exportObj.lang))
|
|
169
|
+
? exportObj.lang
|
|
170
|
+
: undefined,
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
catch (err) {
|
|
174
|
+
this.setCureent();
|
|
175
|
+
this.failedLoadCount += 1;
|
|
176
|
+
if (isLast)
|
|
177
|
+
this.moduleAllHandle();
|
|
178
|
+
throw err;
|
|
179
|
+
}
|
|
180
|
+
this.setCureent();
|
|
181
|
+
this.emit('load_module', {
|
|
182
|
+
module: isString || isFunc ? null : summary,
|
|
183
|
+
moduleType: typeInfo.type,
|
|
184
|
+
instanceType: typeInfo.instanceType,
|
|
185
|
+
});
|
|
186
|
+
if (isLast)
|
|
187
|
+
this.moduleAllHandle();
|
|
188
|
+
}
|
|
189
|
+
dispose(module) {
|
|
190
|
+
/* need more... */
|
|
191
|
+
const isString = typeof module === 'string';
|
|
192
|
+
const modulePath = isString ? module : module.mainPath;
|
|
193
|
+
this.emit('unload_module', { module: isString ? null : module });
|
|
194
|
+
if (!isString) {
|
|
195
|
+
module.fileList.forEach(file => delete require.cache[require.resolve(file)]);
|
|
196
|
+
for (let index = 0; index < this.moduleStack.length; index += 1) {
|
|
197
|
+
if (this.moduleStack[index] === module)
|
|
198
|
+
delete this.moduleStack[index];
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
delete require.cache[require.resolve(modulePath)];
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
exports.Modules = Modules;
|
|
205
|
+
exports.default = Modules;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type Api from './api';
|
|
2
|
+
import type Context from '../context';
|
|
3
|
+
import type { EventDataApiBase, AdapterConfig, EventType, EventDataTargetId, ApiConstructor, ElementsParam, MessageScope } from '../types';
|
|
4
|
+
import Service from './service';
|
|
5
|
+
interface Status {
|
|
6
|
+
value: 'online' | 'offline';
|
|
7
|
+
createTime: Date;
|
|
8
|
+
lastMsgTime: Date | null;
|
|
9
|
+
receivedMsg: number;
|
|
10
|
+
sentMsg: number;
|
|
11
|
+
offlineTimes: number;
|
|
12
|
+
}
|
|
13
|
+
interface AdapterImpl<T extends Api> {
|
|
14
|
+
readonly platform: string;
|
|
15
|
+
readonly selfId: EventDataTargetId;
|
|
16
|
+
readonly identity: string;
|
|
17
|
+
readonly api: T;
|
|
18
|
+
readonly status: Status;
|
|
19
|
+
}
|
|
20
|
+
export declare function ApiProxy<T extends Api>(api: T, ctx: Context): T;
|
|
21
|
+
type EventApiType = {
|
|
22
|
+
[K in Extract<EventType[keyof EventType], EventDataApiBase<keyof EventType, MessageScope>>['type']]: EventType[K];
|
|
23
|
+
};
|
|
24
|
+
export declare abstract class Adapter<T extends Api = Api> extends Service implements AdapterImpl<T> {
|
|
25
|
+
constructor(ctx: Context, config: AdapterConfig, identity: string, ApiConstructor: ApiConstructor<T>, el?: ElementsParam);
|
|
26
|
+
abstract send(action: string, params?: object): void | object | Promise<unknown> | null | undefined;
|
|
27
|
+
protected online(): void;
|
|
28
|
+
protected offline(): void;
|
|
29
|
+
protected emit<N extends keyof EventApiType>(type: N, data: Omit<EventApiType[N], 'type' | 'api' | 'send' | 'locale' | 'quick' | 'error' | 'el' | 'messageType'>): void;
|
|
30
|
+
readonly ctx: Context;
|
|
31
|
+
readonly config: AdapterConfig;
|
|
32
|
+
readonly identity: string;
|
|
33
|
+
readonly platform: string;
|
|
34
|
+
readonly api: T;
|
|
35
|
+
readonly status: Status;
|
|
36
|
+
selfId: EventDataTargetId;
|
|
37
|
+
}
|
|
38
|
+
export default Adapter;
|
|
@@ -0,0 +1,128 @@
|
|
|
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.Adapter = exports.ApiProxy = void 0;
|
|
7
|
+
const tools_1 = require("@kotori-bot/tools");
|
|
8
|
+
const service_1 = __importDefault(require("./service"));
|
|
9
|
+
const elements_1 = __importDefault(require("./elements"));
|
|
10
|
+
// type AdapterSend = (...args: any[]) => void;
|
|
11
|
+
function ApiProxy(api, ctx) {
|
|
12
|
+
const apiProxy = Object.create(api);
|
|
13
|
+
apiProxy.send_private_msg = new Proxy(api.send_private_msg, {
|
|
14
|
+
apply(_, __, argArray) {
|
|
15
|
+
const { '0': message, '1': targetId } = argArray;
|
|
16
|
+
let isCancel = false;
|
|
17
|
+
const cancel = () => {
|
|
18
|
+
isCancel = true;
|
|
19
|
+
};
|
|
20
|
+
ctx.emit('before_send', { api, message, messageType: 'private', targetId, cancel });
|
|
21
|
+
if (isCancel)
|
|
22
|
+
return;
|
|
23
|
+
api.send_private_msg(message, targetId, argArray[2]);
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
apiProxy.send_group_msg = new Proxy(api.send_group_msg, {
|
|
27
|
+
apply(_, __, argArray) {
|
|
28
|
+
const { '0': message, '1': targetId } = argArray;
|
|
29
|
+
let isCancel = false;
|
|
30
|
+
const cancel = () => {
|
|
31
|
+
isCancel = true;
|
|
32
|
+
};
|
|
33
|
+
ctx.emit('before_send', { api, message, messageType: 'group', targetId, cancel });
|
|
34
|
+
if (isCancel)
|
|
35
|
+
return;
|
|
36
|
+
api.send_group_msg(message, targetId, argArray[2]);
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
return apiProxy;
|
|
40
|
+
}
|
|
41
|
+
exports.ApiProxy = ApiProxy;
|
|
42
|
+
class Adapter extends service_1.default {
|
|
43
|
+
constructor(ctx, config, identity, ApiConstructor, el = {}) {
|
|
44
|
+
super();
|
|
45
|
+
this.config = config;
|
|
46
|
+
this.identity = identity;
|
|
47
|
+
this.platform = config.extends;
|
|
48
|
+
this.ctx = ctx;
|
|
49
|
+
this.api = ApiProxy(new ApiConstructor(this, new elements_1.default(el)), this.ctx);
|
|
50
|
+
if (!this.ctx.internal.getBots()[this.platform])
|
|
51
|
+
this.ctx.internal.setBots(this.platform, []);
|
|
52
|
+
this.ctx.internal.getBots()[this.platform].push(this.api);
|
|
53
|
+
}
|
|
54
|
+
online() {
|
|
55
|
+
if (this.status.value !== 'offline')
|
|
56
|
+
return;
|
|
57
|
+
if (this.status.offlineTimes <= 0) {
|
|
58
|
+
this.ctx.emit('ready', { adapter: this });
|
|
59
|
+
}
|
|
60
|
+
this.ctx.emit('online', { adapter: this });
|
|
61
|
+
this.status.value = 'online';
|
|
62
|
+
}
|
|
63
|
+
offline() {
|
|
64
|
+
if (this.status.value !== 'online')
|
|
65
|
+
return;
|
|
66
|
+
this.ctx.emit('offline', { adapter: this });
|
|
67
|
+
this.status.value = 'offline';
|
|
68
|
+
this.status.offlineTimes += 1;
|
|
69
|
+
}
|
|
70
|
+
emit(type, data) {
|
|
71
|
+
const messageType = type.includes('group') ? 'group' : 'private';
|
|
72
|
+
const send = (message) => {
|
|
73
|
+
if (messageType === 'group') {
|
|
74
|
+
this.api.send_group_msg(message, data.groupId, data.extra);
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
this.api.send_private_msg(message, data.userId, data.extra);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
const locale = (val) => this.ctx.i18n.locale(val, this.config.lang);
|
|
81
|
+
const quick = async (message) => {
|
|
82
|
+
const msg = await message;
|
|
83
|
+
if (!msg)
|
|
84
|
+
return;
|
|
85
|
+
if (typeof msg === 'string') {
|
|
86
|
+
send(locale(msg));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const params = msg[1];
|
|
90
|
+
Object.keys(params).forEach(key => {
|
|
91
|
+
if (typeof params[key] !== 'string')
|
|
92
|
+
return;
|
|
93
|
+
params[key] = locale(params[key]);
|
|
94
|
+
});
|
|
95
|
+
send((0, tools_1.stringTemp)(locale(msg[0]), params));
|
|
96
|
+
};
|
|
97
|
+
const error = (type, data) => ({
|
|
98
|
+
type,
|
|
99
|
+
...data,
|
|
100
|
+
});
|
|
101
|
+
this.ctx.emit(type, {
|
|
102
|
+
...data,
|
|
103
|
+
api: this.api,
|
|
104
|
+
send,
|
|
105
|
+
locale,
|
|
106
|
+
quick,
|
|
107
|
+
error,
|
|
108
|
+
el: this.api.elements,
|
|
109
|
+
messageType,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
ctx;
|
|
113
|
+
config;
|
|
114
|
+
identity;
|
|
115
|
+
platform;
|
|
116
|
+
api;
|
|
117
|
+
status = {
|
|
118
|
+
value: 'offline',
|
|
119
|
+
createTime: new Date(),
|
|
120
|
+
lastMsgTime: null,
|
|
121
|
+
receivedMsg: 0,
|
|
122
|
+
sentMsg: 0,
|
|
123
|
+
offlineTimes: 0,
|
|
124
|
+
};
|
|
125
|
+
selfId = -1;
|
|
126
|
+
}
|
|
127
|
+
exports.Adapter = Adapter;
|
|
128
|
+
exports.default = Adapter;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type Adapter from './adapter';
|
|
2
|
+
import type { EventDataTargetId, MessageRaw } from '../types';
|
|
3
|
+
import Elements from './elements';
|
|
4
|
+
interface ApiImpl {
|
|
5
|
+
readonly adapter: Adapter<this>;
|
|
6
|
+
send_private_msg(message: MessageRaw, userId: EventDataTargetId): void;
|
|
7
|
+
send_group_msg(message: MessageRaw, groupId: EventDataTargetId): void;
|
|
8
|
+
delete_msg(messageId: EventDataTargetId): void;
|
|
9
|
+
set_group_name(groupId: EventDataTargetId, groupName: string): void;
|
|
10
|
+
set_group_avatar(groupId: EventDataTargetId, image: string): void;
|
|
11
|
+
set_group_admin(groupId: EventDataTargetId, userId: EventDataTargetId, enable: boolean): void;
|
|
12
|
+
set_group_card(groupId: EventDataTargetId, userId: EventDataTargetId, card: string): void;
|
|
13
|
+
set_group_ban(groupId: EventDataTargetId, userId?: EventDataTargetId, time?: number): void;
|
|
14
|
+
send_group_notice(groupId: EventDataTargetId, content: string, image?: string): void;
|
|
15
|
+
set_group_kick(groupId: EventDataTargetId, userId: EventDataTargetId): void;
|
|
16
|
+
set_group_leave(groupId: EventDataTargetId): void;
|
|
17
|
+
elements: Elements;
|
|
18
|
+
}
|
|
19
|
+
export declare abstract class Api implements ApiImpl {
|
|
20
|
+
readonly adapter: Adapter<this>;
|
|
21
|
+
elements: Elements;
|
|
22
|
+
constructor(adapter: Adapter, el: Elements);
|
|
23
|
+
send_private_msg(message: MessageRaw, userId: EventDataTargetId, extra?: unknown): void;
|
|
24
|
+
send_group_msg(message: MessageRaw, groupId: EventDataTargetId, extra?: unknown): void;
|
|
25
|
+
delete_msg(messageId: EventDataTargetId, extra?: unknown): void;
|
|
26
|
+
set_group_name(groupId: EventDataTargetId, groupName: string, extra?: unknown): void;
|
|
27
|
+
set_group_avatar(groupId: EventDataTargetId, image: string, extra?: unknown): void;
|
|
28
|
+
set_group_admin(groupId: EventDataTargetId, userId: EventDataTargetId, enable: boolean, extra?: unknown): void;
|
|
29
|
+
set_group_card(groupId: EventDataTargetId, userId: EventDataTargetId, card: string, extra?: unknown): void;
|
|
30
|
+
set_group_ban(groupId: EventDataTargetId, userId?: EventDataTargetId, time?: number, extra?: unknown): void;
|
|
31
|
+
send_group_notice(groupId: EventDataTargetId, content: string, image?: string, extra?: unknown): void;
|
|
32
|
+
set_group_kick(groupId: EventDataTargetId, userId: EventDataTargetId, extra?: unknown): void;
|
|
33
|
+
set_group_leave(groupId: EventDataTargetId, extra?: unknown): void;
|
|
34
|
+
}
|
|
35
|
+
export default Api;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Api = void 0;
|
|
4
|
+
const tools_1 = require("@kotori-bot/tools");
|
|
5
|
+
class Api {
|
|
6
|
+
adapter;
|
|
7
|
+
elements;
|
|
8
|
+
constructor(adapter, el) {
|
|
9
|
+
this.adapter = adapter;
|
|
10
|
+
this.elements = el;
|
|
11
|
+
}
|
|
12
|
+
send_private_msg(message, userId, extra) {
|
|
13
|
+
(0, tools_1.none)(this, message, userId, extra);
|
|
14
|
+
}
|
|
15
|
+
send_group_msg(message, groupId, extra) {
|
|
16
|
+
(0, tools_1.none)(this, message, groupId, extra, extra);
|
|
17
|
+
}
|
|
18
|
+
delete_msg(messageId, extra) {
|
|
19
|
+
(0, tools_1.none)(this, messageId, extra);
|
|
20
|
+
}
|
|
21
|
+
set_group_name(groupId, groupName, extra) {
|
|
22
|
+
(0, tools_1.none)(this, groupId, groupName, extra);
|
|
23
|
+
}
|
|
24
|
+
set_group_avatar(groupId, image, extra) {
|
|
25
|
+
(0, tools_1.none)(this, groupId, image, extra);
|
|
26
|
+
}
|
|
27
|
+
set_group_admin(groupId, userId, enable, extra) {
|
|
28
|
+
(0, tools_1.none)(this, groupId, userId, enable, extra);
|
|
29
|
+
}
|
|
30
|
+
set_group_card(groupId, userId, card, extra) {
|
|
31
|
+
(0, tools_1.none)(this, groupId, userId, card, extra);
|
|
32
|
+
}
|
|
33
|
+
set_group_ban(groupId, userId, time, extra) {
|
|
34
|
+
(0, tools_1.none)(this, groupId, userId, time, extra);
|
|
35
|
+
}
|
|
36
|
+
send_group_notice(groupId, content, image, extra) {
|
|
37
|
+
(0, tools_1.none)(this, groupId, content, image, extra);
|
|
38
|
+
}
|
|
39
|
+
set_group_kick(groupId, userId, extra) {
|
|
40
|
+
(0, tools_1.none)(this, groupId, userId, extra);
|
|
41
|
+
}
|
|
42
|
+
set_group_leave(groupId, extra) {
|
|
43
|
+
(0, tools_1.none)(this, groupId, groupId, extra);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.Api = Api;
|
|
47
|
+
exports.default = Api;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ElementsParam, EventDataTargetId } from '../types';
|
|
2
|
+
export declare class Elements {
|
|
3
|
+
constructor(data: ElementsParam);
|
|
4
|
+
at: (target: EventDataTargetId, extra?: unknown) => string;
|
|
5
|
+
image: (url: string, extra?: unknown) => string;
|
|
6
|
+
voice: (url: string, extra?: unknown) => string;
|
|
7
|
+
video: (url: string, extra?: unknown) => string;
|
|
8
|
+
face: (id: number | string, extra?: unknown) => string;
|
|
9
|
+
file: (data: ArrayBuffer, extra?: unknown) => string;
|
|
10
|
+
supports: string[];
|
|
11
|
+
}
|
|
12
|
+
export default Elements;
|