@kotori-bot/loader 1.5.0 → 1.5.2-beta.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/runner.js DELETED
@@ -1,205 +0,0 @@
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.Runner = exports.localeTypeSchema = void 0;
30
- const fs_1 = __importStar(require("fs"));
31
- const path_1 = __importDefault(require("path"));
32
- const core_1 = require("@kotori-bot/core");
33
- const logger_1 = require("@kotori-bot/logger");
34
- const constants_1 = require("./constants");
35
- const logger_2 = __importDefault(require("./utils/logger"));
36
- exports.localeTypeSchema = core_1.Tsu.Union([
37
- core_1.Tsu.Union([core_1.Tsu.Literal('en_US'), core_1.Tsu.Literal('ja_JP')]),
38
- core_1.Tsu.Union([core_1.Tsu.Literal('zh_TW'), core_1.Tsu.Any()])
39
- ]);
40
- const modulePackageSchema = core_1.Tsu.Object({
41
- name: core_1.Tsu.String().regexp(/kotori-plugin-[a-z]([a-z,0-9]{2,13})\b/),
42
- version: core_1.Tsu.String(),
43
- description: core_1.Tsu.String(),
44
- main: core_1.Tsu.String(),
45
- license: core_1.Tsu.Literal('GPL-3.0'),
46
- keywords: core_1.Tsu.Custom((val) => Array.isArray(val) && val.includes('kotori') && val.includes('chatbot') && val.includes('kotori-plugin')),
47
- author: core_1.Tsu.Union([core_1.Tsu.String(), core_1.Tsu.Array(core_1.Tsu.String())]),
48
- peerDependencies: core_1.Tsu.Object({
49
- 'kotori-bot': core_1.Tsu.String()
50
- }),
51
- kotori: core_1.Tsu.Object({
52
- enforce: core_1.Tsu.Union([core_1.Tsu.Literal('pre'), core_1.Tsu.Literal('post')]).optional(),
53
- meta: core_1.Tsu.Object({
54
- language: core_1.Tsu.Array(exports.localeTypeSchema).default([])
55
- }).default({ language: [] })
56
- }).default({
57
- enforce: undefined,
58
- meta: { language: [] }
59
- })
60
- });
61
- function moduleLoadOrder(pkg) {
62
- if (pkg.name.includes(core_1.DATABASE_PREFIX))
63
- return 1;
64
- if (pkg.name.includes(core_1.ADAPTER_PREFIX))
65
- return 2;
66
- // if (CORE_MODULES.includes(pkg.name)) return 3;
67
- if (pkg.kotori.enforce === 'pre')
68
- return 4;
69
- if (!pkg.kotori.enforce)
70
- return 5;
71
- return 6;
72
- }
73
- class Runner {
74
- baseDir;
75
- options;
76
- ctx;
77
- isDev;
78
- [core_1.Symbols.modules] = new Map();
79
- constructor(ctx, config) {
80
- this.ctx = ctx;
81
- /* handle config */
82
- this.baseDir = config.baseDir;
83
- this.options = config.options;
84
- this.isDev = this.options.mode === 'dev';
85
- const loggerOptions = {
86
- level: this.isDev ? logger_1.LoggerLevel.TRACE : logger_1.LoggerLevel.INFO,
87
- label: [],
88
- transports: [
89
- new logger_1.ConsoleTransport(),
90
- new logger_1.FileTransport({ dir: this.baseDir.logs, filter: (data) => data.level >= logger_1.LoggerLevel.WARN })
91
- ]
92
- };
93
- ctx.provide('logger', new logger_2.default(loggerOptions, this.ctx));
94
- ctx.inject('logger');
95
- }
96
- getDirFiles(rootDir) {
97
- const files = fs_1.default.readdirSync(rootDir);
98
- const list = [];
99
- files.forEach((fileName) => {
100
- const file = path_1.default.join(rootDir, fileName);
101
- if (fs_1.default.statSync(file).isDirectory()) {
102
- list.push(...this.getDirFiles(file));
103
- }
104
- if (path_1.default.parse(file).ext !== (this.isDev ? constants_1.DEV_FILE : constants_1.BUILD_FILE))
105
- return;
106
- list.push(path_1.default.resolve(file));
107
- });
108
- return list;
109
- }
110
- getModuleRootDir() {
111
- const moduleRootDir = [];
112
- [
113
- ...this.ctx.config.global.dirs.map((dir) => path_1.default.resolve(this.ctx.baseDir.root, dir)),
114
- this.ctx.baseDir.modules
115
- ].forEach((dir) => {
116
- if (fs_1.default.existsSync(dir) && fs_1.default.statSync(dir).isDirectory())
117
- moduleRootDir.push(dir);
118
- });
119
- return moduleRootDir;
120
- }
121
- getModuleList(rootDir) {
122
- fs_1.default.readdirSync(rootDir).forEach(async (fileName) => {
123
- const dir = path_1.default.join(rootDir, fileName);
124
- if (!fs_1.default.statSync(dir).isDirectory())
125
- return;
126
- if (rootDir !== this.ctx.baseDir.modules && !fileName.startsWith(core_1.PLUGIN_PREFIX))
127
- return;
128
- const packagePath = path_1.default.join(dir, 'package.json');
129
- let pkg;
130
- if (!fs_1.default.existsSync(packagePath))
131
- return;
132
- try {
133
- pkg = JSON.parse(fs_1.default.readFileSync(packagePath).toString());
134
- }
135
- catch {
136
- throw new core_1.DevError(`illegal package.json ${packagePath}`);
137
- }
138
- const result = modulePackageSchema.parseSafe(pkg);
139
- if (!result.value) {
140
- if (rootDir !== this.ctx.baseDir.modules)
141
- return;
142
- throw new core_1.DevError(`package.json format error ${packagePath}: ${result.error.message}`);
143
- }
144
- pkg = result.data;
145
- const devMode = this.isDev && (0, fs_1.existsSync)(path_1.default.resolve(dir, constants_1.DEV_IMPORT));
146
- const main = path_1.default.resolve(dir, devMode ? constants_1.DEV_IMPORT : pkg.main);
147
- if (!fs_1.default.existsSync(main))
148
- throw new core_1.DevError(`cannot find ${main}`);
149
- const dirs = path_1.default.join(dir, devMode ? constants_1.DEV_CODE_DIRS : path_1.default.dirname(pkg.main));
150
- const files = fs_1.default.statSync(dirs).isDirectory() ? this.getDirFiles(dirs) : [];
151
- this[core_1.Symbols.modules].set(pkg.name, [
152
- { pkg, files, main },
153
- this.ctx.config.plugin[(0, core_1.stringRightSplit)(pkg.name, core_1.PLUGIN_PREFIX)] || {}
154
- ]);
155
- });
156
- }
157
- loadEx(instance, config) {
158
- const { main, pkg } = instance;
159
- /* eslint-disable-next-line import/no-dynamic-require, global-require, @typescript-eslint/no-var-requires */
160
- let obj = require(main);
161
- let handle = config;
162
- const adapterName = pkg.name.split(core_1.ADAPTER_PREFIX)[1];
163
- if (core_1.Adapter.isPrototypeOf.call(core_1.Adapter, obj.default) &&
164
- adapterName &&
165
- (!obj.config || obj.config instanceof core_1.Parser)) {
166
- this.ctx[core_1.Symbols.adapter].set(adapterName, [obj.default, obj.config]);
167
- obj = {};
168
- }
169
- else if (core_1.Service.isPrototypeOf.call(core_1.Service, obj.default)) {
170
- obj = {};
171
- }
172
- else if (obj.config instanceof core_1.Parser) {
173
- const result = obj.config.parseSafe(handle);
174
- if (!result.value)
175
- throw new core_1.ModuleError(`Config format of module ${pkg.name} is error: ${result.error.message}`);
176
- handle = result.data;
177
- }
178
- if (obj.lang)
179
- this.ctx.i18n.use(Array.isArray(obj.lang) ? path_1.default.resolve(...obj.lang) : path_1.default.resolve(obj.lang));
180
- this.ctx.load({ name: pkg.name, ...obj, config: handle });
181
- }
182
- unloadEx(instance) {
183
- instance.files.forEach((file) => delete require.cache[require.resolve(file)]);
184
- this.ctx.load({ name: instance.pkg.name });
185
- }
186
- loadAll() {
187
- this.getModuleRootDir().forEach((dir) => this.getModuleList(dir));
188
- const modules = [];
189
- this[core_1.Symbols.modules].forEach((val) => modules.push(val));
190
- modules
191
- .sort((el1, el2) => moduleLoadOrder(el1[0].pkg) - moduleLoadOrder(el2[0].pkg))
192
- .forEach((el) => this.loadEx(...el));
193
- if (this.isDev)
194
- this.watcher();
195
- }
196
- watcher() {
197
- this[core_1.Symbols.modules].forEach((data) => data[0].files.forEach((file) => fs_1.default.watchFile(file, async () => {
198
- this.ctx.logger.debug(`file happen changed, module ${data[0].pkg.name} is reloading...`);
199
- this.unloadEx(data[0]);
200
- this.loadEx(...data);
201
- })));
202
- }
203
- }
204
- exports.Runner = Runner;
205
- exports.default = Runner;