@kotori-bot/loader 1.6.0 → 1.6.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.
- package/lib/class/loader.js +68 -467
- package/lib/class/runner.js +72 -157
- package/lib/constants.js +15 -17
- package/lib/decorators/index.js +22 -118
- package/lib/decorators/plugin.js +4 -6
- package/lib/decorators/utils.js +6 -7
- package/lib/index.js +10 -807
- package/lib/service/adapter.js +2 -4
- package/lib/service/database.js +2 -4
- package/lib/service/file.js +5 -7
- package/lib/service/server.js +5 -7
- package/lib/types/index.js +8 -4
- package/lib/types/internal.js +2 -2
- package/lib/types/server.js +2 -4
- package/lib/utils/log.js +2 -4
- package/lib/utils/logger.js +4 -6
- package/package.json +3 -3
package/lib/class/loader.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
|
|
2
2
|
/**
|
|
3
3
|
* @Package @kotori-bot/loader
|
|
4
|
-
* @Version 1.6.0
|
|
4
|
+
* @Version 1.6.0
|
|
5
5
|
* @Author Hotaru <biyuehuya@gmail.com>
|
|
6
6
|
* @Copyright 2024 Hotaru. All rights reserved.
|
|
7
7
|
* @License GPL-3.0
|
|
8
8
|
* @Link https://github.com/kotorijs/kotori
|
|
9
|
-
* @Date 2024/6/
|
|
9
|
+
* @Date 2024/6/7 11:22:23
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
"use strict";
|
|
@@ -37,442 +37,43 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
37
37
|
mod
|
|
38
38
|
));
|
|
39
39
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
40
|
-
|
|
41
|
-
// src/class/loader.ts
|
|
42
40
|
var loader_exports = {};
|
|
43
41
|
__export(loader_exports, {
|
|
44
42
|
Loader: () => Loader,
|
|
45
43
|
default: () => loader_default
|
|
46
44
|
});
|
|
47
45
|
module.exports = __toCommonJS(loader_exports);
|
|
48
|
-
var import_core4 = require("@kotori-bot/core");
|
|
49
|
-
var import_node_path3 = __toESM(require("path"));
|
|
50
|
-
var import_node_fs2 = __toESM(require("fs"));
|
|
51
|
-
var import_logger4 = __toESM(require("@kotori-bot/logger"));
|
|
52
|
-
|
|
53
|
-
// src/class/runner.ts
|
|
54
|
-
var import_node_fs = __toESM(require("fs"));
|
|
55
|
-
var import_node_path = __toESM(require("path"));
|
|
56
46
|
var import_core = require("@kotori-bot/core");
|
|
57
|
-
var
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
var
|
|
61
|
-
var
|
|
62
|
-
var
|
|
63
|
-
var
|
|
64
|
-
var
|
|
65
|
-
var
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
var DEV_MODE = "dev";
|
|
71
|
-
var DEV_SOURCE_MODE = "dev-source";
|
|
72
|
-
var CORE_MODULES = [
|
|
73
|
-
"@kotori-bot/kotori-plugin-core",
|
|
74
|
-
"@kotori-bot/kotori-plugin-i18n-command",
|
|
75
|
-
"@kotori-bot/kotori-plugin-filter"
|
|
76
|
-
// '@kotori-bot/kotori-plugin-webui'
|
|
77
|
-
];
|
|
78
|
-
|
|
79
|
-
// src/utils/logger.ts
|
|
80
|
-
var import_logger = require("@kotori-bot/logger");
|
|
81
|
-
var KotoriLogger = class extends import_logger.Logger {
|
|
82
|
-
constructor(optionsSelf, ctx) {
|
|
83
|
-
super(optionsSelf);
|
|
84
|
-
this.optionsSelf = optionsSelf;
|
|
85
|
-
this.ctx = ctx;
|
|
86
|
-
}
|
|
87
|
-
setLabel() {
|
|
88
|
-
const origin = Object.create(this.optionsSelf.label);
|
|
89
|
-
const label = this.ctx.identity ? [this.ctx.identity, ...this.optionsSelf.label] : this.optionsSelf.label;
|
|
90
|
-
this[/* @__PURE__ */ (() => "options")()].label = label;
|
|
91
|
-
return () => {
|
|
92
|
-
this[/* @__PURE__ */ (() => "options")()].label = origin;
|
|
93
|
-
};
|
|
94
|
-
}
|
|
95
|
-
fatal(...args) {
|
|
96
|
-
const dispose = this.setLabel();
|
|
97
|
-
super.fatal(...args);
|
|
98
|
-
dispose();
|
|
99
|
-
}
|
|
100
|
-
error(...args) {
|
|
101
|
-
const dispose = this.setLabel();
|
|
102
|
-
super.error(...args);
|
|
103
|
-
dispose();
|
|
104
|
-
}
|
|
105
|
-
warn(...args) {
|
|
106
|
-
const dispose = this.setLabel();
|
|
107
|
-
super.warn(...args);
|
|
108
|
-
dispose();
|
|
109
|
-
}
|
|
110
|
-
info(...args) {
|
|
111
|
-
const dispose = this.setLabel();
|
|
112
|
-
super.info(...args);
|
|
113
|
-
dispose();
|
|
114
|
-
}
|
|
115
|
-
record(...args) {
|
|
116
|
-
const dispose = this.setLabel();
|
|
117
|
-
super.record(...args);
|
|
118
|
-
dispose();
|
|
119
|
-
}
|
|
120
|
-
debug(...args) {
|
|
121
|
-
const dispose = this.setLabel();
|
|
122
|
-
super.debug(...args);
|
|
123
|
-
dispose();
|
|
124
|
-
}
|
|
125
|
-
trace(...args) {
|
|
126
|
-
const dispose = this.setLabel();
|
|
127
|
-
super.trace(...args);
|
|
128
|
-
dispose();
|
|
129
|
-
}
|
|
130
|
-
};
|
|
131
|
-
var logger_default = KotoriLogger;
|
|
132
|
-
|
|
133
|
-
// src/class/runner.ts
|
|
134
|
-
var localeTypeSchema = import_core.Tsu.Union([
|
|
135
|
-
import_core.Tsu.Union([import_core.Tsu.Literal("en_US"), import_core.Tsu.Literal("ja_JP")]),
|
|
136
|
-
import_core.Tsu.Union([import_core.Tsu.Literal("zh_TW"), import_core.Tsu.Any()])
|
|
137
|
-
]);
|
|
138
|
-
var modulePackageSchema = import_core.Tsu.Object({
|
|
139
|
-
name: import_core.Tsu.String().regexp(/kotori-plugin-[a-z]([a-z,0-9]{2,13})\b/),
|
|
140
|
-
version: import_core.Tsu.String(),
|
|
141
|
-
description: import_core.Tsu.String(),
|
|
142
|
-
main: import_core.Tsu.String(),
|
|
143
|
-
license: import_core.Tsu.Literal("GPL-3.0"),
|
|
144
|
-
keywords: import_core.Tsu.Custom(
|
|
145
|
-
(val) => Array.isArray(val) && val.includes("kotori") && val.includes("chatbot") && val.includes("kotori-plugin")
|
|
146
|
-
),
|
|
147
|
-
author: import_core.Tsu.Union([import_core.Tsu.String(), import_core.Tsu.Array(import_core.Tsu.String())]),
|
|
148
|
-
peerDependencies: import_core.Tsu.Object({
|
|
149
|
-
"kotori-bot": import_core.Tsu.String()
|
|
150
|
-
}),
|
|
151
|
-
kotori: import_core.Tsu.Object({
|
|
152
|
-
enforce: import_core.Tsu.Union([import_core.Tsu.Literal("pre"), import_core.Tsu.Literal("post")]).optional(),
|
|
153
|
-
meta: import_core.Tsu.Object({
|
|
154
|
-
language: import_core.Tsu.Array(localeTypeSchema).default([])
|
|
155
|
-
}).default({ language: [] })
|
|
156
|
-
}).default({
|
|
157
|
-
enforce: void 0,
|
|
158
|
-
meta: { language: [] }
|
|
159
|
-
})
|
|
160
|
-
});
|
|
161
|
-
function moduleLoadOrder(pkg) {
|
|
162
|
-
if (CORE_MODULES.includes(pkg.name)) return 1;
|
|
163
|
-
if (pkg.name.includes(import_core.DATABASE_PREFIX)) return 2;
|
|
164
|
-
if (pkg.name.includes(import_core.ADAPTER_PREFIX)) return 3;
|
|
165
|
-
if (pkg.kotori.enforce === "pre") return 4;
|
|
166
|
-
if (!pkg.kotori.enforce) return 5;
|
|
167
|
-
return 6;
|
|
168
|
-
}
|
|
169
|
-
var Runner = class {
|
|
170
|
-
baseDir;
|
|
171
|
-
options;
|
|
172
|
-
ctx;
|
|
173
|
-
isDev;
|
|
174
|
-
isSourceDev;
|
|
175
|
-
[import_core.Symbols.modules] = /* @__PURE__ */ new Map();
|
|
176
|
-
constructor(ctx, config) {
|
|
177
|
-
this.ctx = ctx;
|
|
178
|
-
this.baseDir = config.baseDir;
|
|
179
|
-
this.options = config.options;
|
|
180
|
-
this.isDev = this.options.mode.startsWith(DEV_MODE);
|
|
181
|
-
this.isSourceDev = this.options.mode === DEV_SOURCE_MODE;
|
|
182
|
-
const loggerOptions = {
|
|
183
|
-
level: this.ctx.config.global.level ?? config.level,
|
|
184
|
-
label: [],
|
|
185
|
-
transports: [
|
|
186
|
-
new import_logger2.ConsoleTransport({
|
|
187
|
-
template: "<blue>%time%</blue> %level% (<bold>%pid%</bold>) %labels%: %msg%",
|
|
188
|
-
time: "M/D H:m:s"
|
|
189
|
-
}),
|
|
190
|
-
new import_logger2.FileTransport({ dir: this.baseDir.logs, filter: (data) => data.level >= import_logger2.LoggerLevel.WARN })
|
|
191
|
-
]
|
|
192
|
-
};
|
|
193
|
-
ctx.provide("logger", new logger_default(loggerOptions, this.ctx));
|
|
194
|
-
ctx.inject("logger");
|
|
195
|
-
}
|
|
196
|
-
getDirFiles(rootDir) {
|
|
197
|
-
const files = import_node_fs.default.readdirSync(rootDir);
|
|
198
|
-
const list = [];
|
|
199
|
-
files.forEach((fileName) => {
|
|
200
|
-
const file = import_node_path.default.join(rootDir, fileName);
|
|
201
|
-
if (import_node_fs.default.statSync(file).isDirectory()) {
|
|
202
|
-
list.push(...this.getDirFiles(file));
|
|
203
|
-
}
|
|
204
|
-
if (import_node_path.default.parse(file).ext !== (this.isSourceDev ? DEV_FILE : BUILD_FILE)) return;
|
|
205
|
-
list.push(import_node_path.default.resolve(file));
|
|
206
|
-
});
|
|
207
|
-
return list;
|
|
208
|
-
}
|
|
209
|
-
getModuleRootDir() {
|
|
210
|
-
const moduleRootDir = [];
|
|
211
|
-
[
|
|
212
|
-
...this.ctx.config.global.dirs.map((dir) => import_node_path.default.resolve(this.ctx.baseDir.root, dir)),
|
|
213
|
-
this.ctx.baseDir.modules
|
|
214
|
-
].forEach((dir) => {
|
|
215
|
-
if (import_node_fs.default.existsSync(dir) && import_node_fs.default.statSync(dir).isDirectory()) moduleRootDir.push(dir);
|
|
216
|
-
});
|
|
217
|
-
return moduleRootDir;
|
|
218
|
-
}
|
|
219
|
-
async checkModuleFiles(rootDir, filename) {
|
|
220
|
-
const dir = import_node_path.default.join(rootDir, filename);
|
|
221
|
-
if (!import_node_fs.default.statSync(dir).isDirectory()) return;
|
|
222
|
-
if (rootDir !== this.ctx.baseDir.modules && !filename.startsWith(import_core.PLUGIN_PREFIX)) return;
|
|
223
|
-
const packagePath = import_node_path.default.join(dir, "package.json");
|
|
224
|
-
let pkg;
|
|
225
|
-
if (!import_node_fs.default.existsSync(packagePath)) return;
|
|
226
|
-
try {
|
|
227
|
-
pkg = JSON.parse(import_node_fs.default.readFileSync(packagePath).toString());
|
|
228
|
-
} catch {
|
|
229
|
-
throw new import_core.DevError(this.ctx.format("error.dev.package.illegal", [packagePath]));
|
|
230
|
-
}
|
|
231
|
-
const result = modulePackageSchema.parseSafe(pkg);
|
|
232
|
-
if (!result.value) {
|
|
233
|
-
if (rootDir !== this.ctx.baseDir.modules) return;
|
|
234
|
-
throw new import_core.DevError(this.ctx.format("error.dev.package.missing", [packagePath, result.error.message]));
|
|
235
|
-
}
|
|
236
|
-
pkg = result.data;
|
|
237
|
-
const devMode = this.isSourceDev && (0, import_node_fs.existsSync)(import_node_path.default.resolve(dir, DEV_IMPORT));
|
|
238
|
-
const main = import_node_path.default.resolve(dir, devMode ? DEV_IMPORT : pkg.main);
|
|
239
|
-
if (!import_node_fs.default.existsSync(main)) throw new import_core.DevError(this.ctx.format("error.dev.main_file", [main]));
|
|
240
|
-
const dirs = import_node_path.default.join(dir, devMode ? DEV_CODE_DIRS : import_node_path.default.dirname(pkg.main));
|
|
241
|
-
const files = import_node_fs.default.statSync(dirs).isDirectory() ? this.getDirFiles(dirs) : [];
|
|
242
|
-
this[import_core.Symbols.modules].set(pkg.name, [
|
|
243
|
-
{ pkg, files, main },
|
|
244
|
-
this.ctx.config.plugin[(0, import_core.stringRightSplit)(pkg.name, import_core.PLUGIN_PREFIX)] || {}
|
|
245
|
-
]);
|
|
246
|
-
}
|
|
247
|
-
getModuleList(rootDir) {
|
|
248
|
-
this.ctx.logger.trace("load dirs:", rootDir);
|
|
249
|
-
import_node_fs.default.readdirSync(rootDir).forEach(async (filename) => {
|
|
250
|
-
await this.checkModuleFiles(rootDir, filename);
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
loadLang(lang) {
|
|
254
|
-
if (lang) this.ctx.i18n.use((0, import_node_path.resolve)(...Array.isArray(lang) ? lang : [lang]));
|
|
255
|
-
}
|
|
256
|
-
loadEx(instance, origin) {
|
|
257
|
-
this.ctx.logger.trace("module:", instance, origin);
|
|
258
|
-
if (!instance.main) return;
|
|
259
|
-
const parsed = (schema) => {
|
|
260
|
-
const result = schema.parseSafe(config);
|
|
261
|
-
if (!result.value)
|
|
262
|
-
throw new import_core.ModuleError(this.ctx.format("error.module.config", [pkg.name, result.error.message]));
|
|
263
|
-
return result.data;
|
|
264
|
-
};
|
|
265
|
-
const { main, pkg } = instance;
|
|
266
|
-
let obj = require(main);
|
|
267
|
-
let config = origin;
|
|
268
|
-
const adapterName = pkg.name.split(import_core.ADAPTER_PREFIX)[1];
|
|
269
|
-
if (this.ctx.get("decorators")?.registers.includes(pkg.name)) {
|
|
270
|
-
this.ctx.emit("ready_module_decorators", pkg.name);
|
|
271
|
-
return;
|
|
272
|
-
}
|
|
273
|
-
if (import_core.Adapter.isPrototypeOf.call(import_core.Adapter, obj.default) && adapterName && (!obj.config || obj.config instanceof import_core.Parser)) {
|
|
274
|
-
this.ctx[import_core.Symbols.adapter].set(adapterName, [obj.default, obj.config]);
|
|
275
|
-
obj = {};
|
|
276
|
-
} else if (import_core.Service.isPrototypeOf.call(import_core.Service, obj.default)) {
|
|
277
|
-
obj = {};
|
|
278
|
-
} else if (obj.config instanceof import_core.Parser) {
|
|
279
|
-
config = parsed(obj.config);
|
|
280
|
-
}
|
|
281
|
-
if (obj.lang) this.loadLang(obj.lang);
|
|
282
|
-
if (obj.default) {
|
|
283
|
-
if (obj.default.lang) this.loadLang(obj.default.lang);
|
|
284
|
-
if (obj.default.config instanceof import_core.Parser) config = parsed(obj.default.config);
|
|
285
|
-
} else if (obj.Main) {
|
|
286
|
-
if (obj.Main.lang) this.loadLang(obj.Main.lang);
|
|
287
|
-
if (obj.Main.config instanceof import_core.Parser) config = parsed(obj.Main.config);
|
|
288
|
-
}
|
|
289
|
-
this.ctx.load({ name: pkg.name, ...obj, config });
|
|
290
|
-
}
|
|
291
|
-
unloadEx(instance) {
|
|
292
|
-
instance.files.forEach((file) => delete require.cache[require.resolve(file)]);
|
|
293
|
-
this.ctx.load({ name: instance.pkg.name });
|
|
294
|
-
}
|
|
295
|
-
loadAll() {
|
|
296
|
-
this.getModuleRootDir().forEach((dir) => this.getModuleList(dir));
|
|
297
|
-
const modules = [];
|
|
298
|
-
this[import_core.Symbols.modules].forEach((val) => modules.push(val));
|
|
299
|
-
modules.sort(([{ pkg: pkg1 }], [{ pkg: pkg2 }]) => moduleLoadOrder(pkg1) - moduleLoadOrder(pkg2)).forEach((el) => this.loadEx(...el));
|
|
300
|
-
if (this.isDev) this.watcher();
|
|
301
|
-
}
|
|
302
|
-
watcher() {
|
|
303
|
-
this[import_core.Symbols.modules].forEach(
|
|
304
|
-
(data) => data[0].files.forEach(
|
|
305
|
-
(file) => import_node_fs.default.watchFile(file, async () => {
|
|
306
|
-
this.ctx.logger.debug(this.ctx.format("loader.debug.reload", [data[0].pkg.name]));
|
|
307
|
-
this.unloadEx(data[0]);
|
|
308
|
-
this.loadEx(...data);
|
|
309
|
-
})
|
|
310
|
-
)
|
|
311
|
-
);
|
|
312
|
-
}
|
|
313
|
-
};
|
|
314
|
-
var runner_default = Runner;
|
|
315
|
-
|
|
316
|
-
// src/utils/log.ts
|
|
317
|
-
function loadInfo(info, ctx) {
|
|
318
|
-
process.stdout.write("Kotori Bot is loading...");
|
|
319
|
-
process.stdout.write(`
|
|
320
|
-
\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557
|
|
321
|
-
\u2588\u2588\u2551 \u2588\u2588\u2554\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2588\u2588\u2554\u2550\u2550\u255D\u2588\u2588\u2554\u2550\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551
|
|
322
|
-
\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551
|
|
323
|
-
\u2588\u2588\u2554\u2550\u2588\u2588\u2557 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551
|
|
324
|
-
\u2588\u2588\u2551 \u2588\u2588\u2557\u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551 \u255A\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2551
|
|
325
|
-
\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D
|
|
326
|
-
`);
|
|
327
|
-
ctx.logger.record("loader base dir:", ctx.baseDir.root);
|
|
328
|
-
ctx.logger.info(`Kotori Bot Version: ${info.version} License: ${info.license}`);
|
|
329
|
-
ctx.logger.info(`Kotori Bot By ${info.author}`);
|
|
330
|
-
ctx.logger.info(`Copyright \xA9 2023 - 2024 ${info.author} All rights reserved`);
|
|
331
|
-
}
|
|
332
|
-
var log_default = loadInfo;
|
|
333
|
-
|
|
334
|
-
// src/service/server.ts
|
|
335
|
-
var import_core2 = require("@kotori-bot/core");
|
|
336
|
-
var import_node_http = require("http");
|
|
337
|
-
var import_path_to_regexp = require("path-to-regexp");
|
|
338
|
-
var import_express = __toESM(require("express"));
|
|
339
|
-
var import_ws = __toESM(require("ws"));
|
|
340
|
-
var Server = class extends import_core2.Service {
|
|
341
|
-
app;
|
|
342
|
-
server;
|
|
343
|
-
wsServer;
|
|
344
|
-
wsRoutes = /* @__PURE__ */ new Map();
|
|
345
|
-
constructor(ctx, config) {
|
|
346
|
-
super(ctx, config, "server");
|
|
347
|
-
this.app = (0, import_express.default)();
|
|
348
|
-
this.app.use(import_express.default.json());
|
|
349
|
-
this.app.use("/", (req, res, next) => {
|
|
350
|
-
let isWebui = false;
|
|
351
|
-
ctx[import_core2.Symbols.modules].forEach((module2) => {
|
|
352
|
-
if (isWebui) return;
|
|
353
|
-
if (module2[0].pkg.name === "@kotori-bot/kotori-plugin-webui") isWebui = true;
|
|
354
|
-
});
|
|
355
|
-
if (isWebui || req.url !== "/") {
|
|
356
|
-
next();
|
|
357
|
-
return;
|
|
358
|
-
}
|
|
359
|
-
res.setHeader("Content-type", "text/html");
|
|
360
|
-
res.send(
|
|
361
|
-
/* html */
|
|
362
|
-
`<h1>Welcome to kotori!</h1>`
|
|
363
|
-
);
|
|
364
|
-
});
|
|
365
|
-
this.server = (0, import_node_http.createServer)(this.app);
|
|
366
|
-
this.wsServer = new import_ws.default.Server({ noServer: true });
|
|
367
|
-
this.server.on("upgrade", (req, socket, head) => {
|
|
368
|
-
this.wsServer.handleUpgrade(req, socket, head, (ws) => {
|
|
369
|
-
this.wsServer.emit("connection", ws, req);
|
|
370
|
-
});
|
|
371
|
-
});
|
|
372
|
-
this.wsServer.on("connection", (ws, req) => {
|
|
373
|
-
let triggered = false;
|
|
374
|
-
for (const [template, list] of this.wsRoutes.entries()) {
|
|
375
|
-
if (!req.url) continue;
|
|
376
|
-
const result = (0, import_path_to_regexp.match)(template, { decode: decodeURIComponent })(req.url);
|
|
377
|
-
if (!result) continue;
|
|
378
|
-
if (!triggered) triggered = true;
|
|
379
|
-
list.forEach((callback) => {
|
|
380
|
-
callback(ws, Object.assign(req, { params: result.params }));
|
|
381
|
-
});
|
|
382
|
-
}
|
|
383
|
-
if (!triggered) ws.close(1002);
|
|
384
|
-
});
|
|
385
|
-
}
|
|
386
|
-
start() {
|
|
387
|
-
this.server.listen(this.config.port, () => {
|
|
388
|
-
this.ctx.logger.label("server").info(`http server start at http://127.0.0.1:${this.config.port}`);
|
|
389
|
-
this.ctx.logger.label("server").info(`websocket server start at ws://127.0.0.1:${this.config.port}`);
|
|
390
|
-
});
|
|
391
|
-
}
|
|
392
|
-
stop() {
|
|
393
|
-
this.wsServer.close();
|
|
394
|
-
this.server.close();
|
|
395
|
-
}
|
|
396
|
-
get(path3, ...callback) {
|
|
397
|
-
this.app.get(path3, ...callback);
|
|
398
|
-
}
|
|
399
|
-
post(path3, ...callback) {
|
|
400
|
-
this.app.post(path3, ...callback);
|
|
401
|
-
}
|
|
402
|
-
patch(path3, ...callback) {
|
|
403
|
-
this.app.patch(path3, ...callback);
|
|
404
|
-
}
|
|
405
|
-
put(path3, ...callback) {
|
|
406
|
-
this.app.put(path3, ...callback);
|
|
407
|
-
}
|
|
408
|
-
delete(path3, ...callback) {
|
|
409
|
-
this.app.delete(path3, ...callback);
|
|
410
|
-
}
|
|
411
|
-
all(path3, ...callback) {
|
|
412
|
-
this.app.all(path3, ...callback);
|
|
413
|
-
}
|
|
414
|
-
use(path3, ...callback) {
|
|
415
|
-
if (typeof path3 === "string") this.app.use(path3, ...callback);
|
|
416
|
-
else this.app.use("/", path3, ...callback);
|
|
417
|
-
}
|
|
418
|
-
router = import_express.default.Router;
|
|
419
|
-
json = import_express.default.json;
|
|
420
|
-
static = import_express.default.static;
|
|
421
|
-
urlencoded = import_express.default.urlencoded;
|
|
422
|
-
wss(path3, callback) {
|
|
423
|
-
const list = this.wsRoutes.get(path3) || /* @__PURE__ */ new Set();
|
|
424
|
-
list.add(callback);
|
|
425
|
-
this.wsRoutes.set(path3, list);
|
|
426
|
-
return () => list.delete(callback);
|
|
427
|
-
}
|
|
428
|
-
};
|
|
429
|
-
var server_default = Server;
|
|
430
|
-
|
|
431
|
-
// src/service/file.ts
|
|
432
|
-
var import_core3 = require("@kotori-bot/core");
|
|
433
|
-
var import_node_path2 = require("path");
|
|
434
|
-
var File = class extends import_core3.Service {
|
|
435
|
-
constructor(ctx) {
|
|
436
|
-
super(ctx, {}, "file");
|
|
437
|
-
}
|
|
438
|
-
getDir() {
|
|
439
|
-
return (0, import_node_path2.join)(this.ctx.baseDir.data, ...this.ctx.identity ? this.ctx.identity.split("/") : []);
|
|
440
|
-
}
|
|
441
|
-
getFile(filename) {
|
|
442
|
-
return (0, import_node_path2.join)(this.getDir(), filename);
|
|
443
|
-
}
|
|
444
|
-
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
445
|
-
load(filename, type, init) {
|
|
446
|
-
return (0, import_core3.loadConfig)(this.getFile(filename), type, init);
|
|
447
|
-
}
|
|
448
|
-
/* eslint-enable @typescript-eslint/no-explicit-any */
|
|
449
|
-
save(filename, data, type) {
|
|
450
|
-
(0, import_core3.saveConfig)(this.getFile(filename), data, type);
|
|
451
|
-
}
|
|
452
|
-
create(filename, data, type) {
|
|
453
|
-
(0, import_core3.createConfig)(this.getFile(filename), data, type);
|
|
454
|
-
}
|
|
455
|
-
};
|
|
456
|
-
var file_default = File;
|
|
457
|
-
|
|
458
|
-
// src/class/loader.ts
|
|
47
|
+
var import_node_path = __toESM(require("node:path"));
|
|
48
|
+
var import_node_fs = __toESM(require("node:fs"));
|
|
49
|
+
var import_logger = __toESM(require("@kotori-bot/logger"));
|
|
50
|
+
var import_runner = __toESM(require("./runner"));
|
|
51
|
+
var import_log = __toESM(require("../utils/log"));
|
|
52
|
+
var import_constants = require("../constants");
|
|
53
|
+
var import_server = __toESM(require("../service/server"));
|
|
54
|
+
var import_file = __toESM(require("../service/file"));
|
|
55
|
+
var GLOBAL = /* @__PURE__ */ ((GLOBAL2) => {
|
|
56
|
+
GLOBAL2["REPO"] = "https://github.com/kotorijs/kotori";
|
|
57
|
+
GLOBAL2["UPDATE"] = "https://hotaru.icu/api/agent/?url=https://raw.githubusercontent.com/kotorijs/kotori/master/packages/core/package.json";
|
|
58
|
+
return GLOBAL2;
|
|
59
|
+
})(GLOBAL || {});
|
|
459
60
|
function getBaseDir(filename, dir) {
|
|
460
|
-
let root = dir ?
|
|
61
|
+
let root = dir ? import_node_path.default.resolve(dir) : import_node_path.default.resolve(__dirname, "..").replace("loader", "kotori");
|
|
461
62
|
let filenameFull;
|
|
462
63
|
let count = 0;
|
|
463
64
|
let index = 0;
|
|
464
65
|
while (!filenameFull) {
|
|
465
66
|
if (count > 5) {
|
|
466
|
-
|
|
67
|
+
import_logger.default.fatal(`cannot find file ${filename} `);
|
|
467
68
|
process.exit();
|
|
468
69
|
}
|
|
469
|
-
const fullName = `${filename}${CONFIG_EXT[index]}`;
|
|
470
|
-
if (
|
|
70
|
+
const fullName = `${filename}${import_constants.CONFIG_EXT[index]}`;
|
|
71
|
+
if (import_node_fs.default.existsSync(import_node_path.default.join(root, fullName))) {
|
|
471
72
|
filenameFull = fullName;
|
|
472
73
|
break;
|
|
473
74
|
}
|
|
474
|
-
if (index === CONFIG_EXT.length - 1) {
|
|
475
|
-
root =
|
|
75
|
+
if (index === import_constants.CONFIG_EXT.length - 1) {
|
|
76
|
+
root = import_node_path.default.join(root, "..");
|
|
476
77
|
index = 0;
|
|
477
78
|
count += 1;
|
|
478
79
|
} else {
|
|
@@ -481,66 +82,66 @@ function getBaseDir(filename, dir) {
|
|
|
481
82
|
}
|
|
482
83
|
const baseDir = {
|
|
483
84
|
root,
|
|
484
|
-
modules:
|
|
485
|
-
data:
|
|
486
|
-
logs:
|
|
85
|
+
modules: import_node_path.default.join(root, "modules"),
|
|
86
|
+
data: import_node_path.default.join(root, "data"),
|
|
87
|
+
logs: import_node_path.default.join(root, "logs"),
|
|
487
88
|
config: filenameFull
|
|
488
89
|
};
|
|
489
90
|
Object.entries(baseDir).filter(([key]) => !["modules", "config"].includes(key)).forEach(([, val]) => {
|
|
490
|
-
if (!
|
|
91
|
+
if (!import_node_fs.default.existsSync(val)) import_node_fs.default.mkdirSync(val);
|
|
491
92
|
});
|
|
492
93
|
return baseDir;
|
|
493
94
|
}
|
|
494
95
|
function getCoreConfig(baseDir) {
|
|
495
96
|
try {
|
|
496
|
-
const result1 =
|
|
497
|
-
global:
|
|
498
|
-
dirs:
|
|
499
|
-
port:
|
|
500
|
-
lang: localeTypeSchema.default(
|
|
501
|
-
"command-prefix":
|
|
97
|
+
const result1 = import_core.Tsu.Object({
|
|
98
|
+
global: import_core.Tsu.Object({
|
|
99
|
+
dirs: import_core.Tsu.Array(import_core.Tsu.String()).default([]),
|
|
100
|
+
port: import_core.Tsu.Number().default(import_core.DEFAULT_PORT),
|
|
101
|
+
lang: import_runner.localeTypeSchema.default(import_core.DEFAULT_CORE_CONFIG.global.lang),
|
|
102
|
+
"command-prefix": import_core.Tsu.String().default(import_core.DEFAULT_CORE_CONFIG.global["command-prefix"])
|
|
502
103
|
}),
|
|
503
|
-
plugin:
|
|
504
|
-
|
|
505
|
-
filter:
|
|
104
|
+
plugin: import_core.Tsu.Object({}).index(
|
|
105
|
+
import_core.Tsu.Object({
|
|
106
|
+
filter: import_core.Tsu.Object({}).default({})
|
|
506
107
|
}).default({ filter: {} })
|
|
507
|
-
).default(
|
|
508
|
-
}).default({ global: Object.assign(
|
|
509
|
-
return
|
|
510
|
-
adapter:
|
|
511
|
-
|
|
512
|
-
extends:
|
|
513
|
-
master:
|
|
514
|
-
lang: localeTypeSchema.default(result1.global.lang),
|
|
515
|
-
"command-prefix":
|
|
108
|
+
).default(import_core.DEFAULT_CORE_CONFIG.plugin)
|
|
109
|
+
}).default({ global: Object.assign(import_core.DEFAULT_CORE_CONFIG.global), plugin: import_core.DEFAULT_CORE_CONFIG.plugin }).parse((0, import_core.loadConfig)(import_node_path.default.join(baseDir.root, baseDir.config), baseDir.config.split(".").pop()));
|
|
110
|
+
return import_core.Tsu.Object({
|
|
111
|
+
adapter: import_core.Tsu.Object({}).index(
|
|
112
|
+
import_core.Tsu.Object({
|
|
113
|
+
extends: import_core.Tsu.String(),
|
|
114
|
+
master: import_core.Tsu.Union([import_core.Tsu.Number(), import_core.Tsu.String()]),
|
|
115
|
+
lang: import_runner.localeTypeSchema.default(result1.global.lang),
|
|
116
|
+
"command-prefix": import_core.Tsu.String().default(result1.global["command-prefix"])
|
|
516
117
|
})
|
|
517
|
-
).default(
|
|
118
|
+
).default(import_core.DEFAULT_CORE_CONFIG.adapter)
|
|
518
119
|
}).parse(result1);
|
|
519
120
|
} catch (err) {
|
|
520
|
-
if (!(err instanceof
|
|
521
|
-
|
|
121
|
+
if (!(err instanceof import_core.TsuError)) throw err;
|
|
122
|
+
import_logger.default.fatal(`file ${baseDir.config} format error: ${err.message}`);
|
|
522
123
|
process.exit();
|
|
523
124
|
}
|
|
524
125
|
}
|
|
525
|
-
|
|
126
|
+
class Loader extends import_core.Container {
|
|
526
127
|
ctx;
|
|
527
128
|
loadCount = 0;
|
|
528
129
|
constructor(options) {
|
|
529
130
|
super();
|
|
530
|
-
const filename = options && options.mode?.startsWith(DEV_MODE) ? DEV_CONFIG_NAME : BUILD_CONFIG_NAME;
|
|
131
|
+
const filename = options && options.mode?.startsWith(import_constants.DEV_MODE) ? import_constants.DEV_CONFIG_NAME : import_constants.BUILD_CONFIG_NAME;
|
|
531
132
|
const runnerConfig = {
|
|
532
133
|
baseDir: getBaseDir(filename, options?.dir),
|
|
533
|
-
options: { mode: options?.mode || BUILD_MODE },
|
|
534
|
-
level: options?.level || options?.mode?.startsWith(DEV_MODE) ?
|
|
134
|
+
options: { mode: options?.mode || import_constants.BUILD_MODE },
|
|
135
|
+
level: options?.level || options?.mode?.startsWith(import_constants.DEV_MODE) ? import_logger.LoggerLevel.DEBUG : import_logger.LoggerLevel.INFO
|
|
535
136
|
};
|
|
536
|
-
const ctx = new
|
|
537
|
-
ctx.provide("runner", new
|
|
137
|
+
const ctx = new import_core.Core(getCoreConfig(runnerConfig.baseDir));
|
|
138
|
+
ctx.provide("runner", new import_runner.default(ctx, runnerConfig));
|
|
538
139
|
ctx.mixin("runner", ["baseDir", "options"]);
|
|
539
|
-
|
|
540
|
-
ctx.provide("loader-tools", { format: (0,
|
|
140
|
+
import_core.Container.setInstance(ctx);
|
|
141
|
+
ctx.provide("loader-tools", { format: (0, import_core.formatFactory)(ctx.i18n), locale: ctx.i18n.locale.bind(ctx.i18n) });
|
|
541
142
|
ctx.mixin("loader-tools", ["locale", "format"]);
|
|
542
|
-
ctx.i18n.use(
|
|
543
|
-
this.ctx =
|
|
143
|
+
ctx.i18n.use(import_node_path.default.resolve(__dirname, "../../locales"));
|
|
144
|
+
this.ctx = import_core.Container.getInstance();
|
|
544
145
|
this.ctx.logger.trace(`options:`, options);
|
|
545
146
|
this.ctx.logger.trace(`runnerConfig:`, runnerConfig);
|
|
546
147
|
this.ctx.logger.trace(`baseDir:`, this.ctx.baseDir);
|
|
@@ -550,7 +151,7 @@ var Loader = class extends import_core4.Container {
|
|
|
550
151
|
this.ctx.logger.trace(`running:`, process.cwd());
|
|
551
152
|
}
|
|
552
153
|
run() {
|
|
553
|
-
|
|
154
|
+
(0, import_log.default)(this.ctx.pkg, this.ctx);
|
|
554
155
|
this.catchError();
|
|
555
156
|
this.listenMessage();
|
|
556
157
|
this.setPreService();
|
|
@@ -558,7 +159,7 @@ var Loader = class extends import_core4.Container {
|
|
|
558
159
|
this.checkUpdate();
|
|
559
160
|
}
|
|
560
161
|
handleError(err, prefix) {
|
|
561
|
-
if (!(err instanceof
|
|
162
|
+
if (!(err instanceof import_core.KotoriError)) {
|
|
562
163
|
if (err instanceof Error) {
|
|
563
164
|
this.ctx.logger.label(prefix).error(err.message, err.stack);
|
|
564
165
|
} else {
|
|
@@ -612,7 +213,7 @@ var Loader = class extends import_core4.Container {
|
|
|
612
213
|
this.ctx.on("status", ({ status, adapter }) => adapter.ctx.logger.info(status));
|
|
613
214
|
this.ctx.on("ready_module", (data) => {
|
|
614
215
|
if (typeof data.instance !== "object") return;
|
|
615
|
-
const pkg = data.instance.name ? this.ctx.get("runner")[
|
|
216
|
+
const pkg = data.instance.name ? this.ctx.get("runner")[import_core.Symbols.modules].get(data.instance.name) : void 0;
|
|
616
217
|
if (!pkg) return;
|
|
617
218
|
this.loadCount += 1;
|
|
618
219
|
const { name, version, author, peerDependencies } = pkg[0].pkg;
|
|
@@ -620,9 +221,9 @@ var Loader = class extends import_core4.Container {
|
|
|
620
221
|
this.ctx.format("loader.modules.load", [name, version, Array.isArray(author) ? author.join(",") : author])
|
|
621
222
|
);
|
|
622
223
|
const requiredVersion = peerDependencies["kotori-bot"];
|
|
623
|
-
if (requiredVersion.includes("workspace") || SUPPORTS_VERSION.exec(requiredVersion) || requiredVersion.includes(this.ctx.pkg.version))
|
|
224
|
+
if (requiredVersion.includes("workspace") || import_constants.SUPPORTS_VERSION.exec(requiredVersion) || requiredVersion.includes(this.ctx.pkg.version))
|
|
624
225
|
return;
|
|
625
|
-
if (SUPPORTS_HALF_VERSION.exec(requiredVersion)) {
|
|
226
|
+
if (import_constants.SUPPORTS_HALF_VERSION.exec(requiredVersion)) {
|
|
626
227
|
this.ctx.logger.warn(this.ctx.format("loader.modules.incomplete", [requiredVersion]));
|
|
627
228
|
} else {
|
|
628
229
|
this.ctx.logger.error(this.ctx.format("loader.modules.unsupported", [requiredVersion]));
|
|
@@ -630,12 +231,12 @@ var Loader = class extends import_core4.Container {
|
|
|
630
231
|
});
|
|
631
232
|
}
|
|
632
233
|
setPreService() {
|
|
633
|
-
this.ctx.service("server", new
|
|
634
|
-
this.ctx.service("file", new
|
|
234
|
+
this.ctx.service("server", new import_server.default(this.ctx.extends(), { port: this.ctx.config.global.port }));
|
|
235
|
+
this.ctx.service("file", new import_file.default(this.ctx.extends()));
|
|
635
236
|
}
|
|
636
237
|
loadAllModules() {
|
|
637
238
|
this.ctx.get("runner").loadAll();
|
|
638
|
-
const failLoadCount = this.ctx.get("runner")[
|
|
239
|
+
const failLoadCount = this.ctx.get("runner")[import_core.Symbols.modules].size - this.loadCount;
|
|
639
240
|
this.ctx.logger.info(
|
|
640
241
|
this.ctx.format(`loader.modules.all${failLoadCount > 0 ? ".failed" : ""}`, [this.loadCount, failLoadCount])
|
|
641
242
|
);
|
|
@@ -643,7 +244,7 @@ var Loader = class extends import_core4.Container {
|
|
|
643
244
|
this.ctx.emit("ready");
|
|
644
245
|
}
|
|
645
246
|
loadAllAdapter() {
|
|
646
|
-
const adapters = this.ctx[
|
|
247
|
+
const adapters = this.ctx[import_core.Symbols.adapter];
|
|
647
248
|
Object.keys(this.ctx.config.adapter).forEach((botName) => {
|
|
648
249
|
const botConfig = this.ctx.config.adapter[botName];
|
|
649
250
|
const array = adapters.get(botConfig.extends);
|
|
@@ -651,7 +252,7 @@ var Loader = class extends import_core4.Container {
|
|
|
651
252
|
return this.ctx.logger.warn(this.ctx.format("loader.adapters.notfound", [botConfig.extends, botName]));
|
|
652
253
|
const result = array[1]?.parseSafe(botConfig);
|
|
653
254
|
if (result && !result.value)
|
|
654
|
-
throw new
|
|
255
|
+
throw new import_core.ModuleError(this.ctx.format("error.module.config_bot", [botName, result.error.message]));
|
|
655
256
|
const bot = new array[0](
|
|
656
257
|
this.ctx.extends({}, `${botConfig.extends}/${botName}`),
|
|
657
258
|
result ? result.data : botConfig,
|
|
@@ -664,7 +265,7 @@ var Loader = class extends import_core4.Container {
|
|
|
664
265
|
async checkUpdate() {
|
|
665
266
|
const { version } = this.ctx.pkg;
|
|
666
267
|
const res = await this.ctx.http.get("https://hotaru.icu/api/agent/?url=https://raw.githubusercontent.com/kotorijs/kotori/master/packages/core/package.json" /* UPDATE */).catch(() => this.ctx.logger.error(this.ctx.locale("loader.tips.update.failed")));
|
|
667
|
-
if (!res || !
|
|
268
|
+
if (!res || !import_core.Tsu.Object({ version: import_core.Tsu.String() }).check(res)) {
|
|
668
269
|
this.ctx.logger.warn(this.ctx.locale("loader.tips.update.failed"));
|
|
669
270
|
} else if (version === res.version) {
|
|
670
271
|
this.ctx.logger.info(this.ctx.locale("loader.tips.update.latest"));
|
|
@@ -672,7 +273,7 @@ var Loader = class extends import_core4.Container {
|
|
|
672
273
|
this.ctx.logger.warn(this.ctx.format("loader.tips.update.available", [version, res.version, "https://github.com/kotorijs/kotori" /* REPO */]));
|
|
673
274
|
}
|
|
674
275
|
}
|
|
675
|
-
}
|
|
276
|
+
}
|
|
676
277
|
var loader_default = Loader;
|
|
677
278
|
// Annotate the CommonJS export names for ESM import in node:
|
|
678
279
|
0 && (module.exports = {
|