chore: initial commit
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import type {Socket} from 'socket.io-client';
|
||||
import {get_bot_context} from '../bot/instance/index.ts';
|
||||
import {PluginError, type PluginErrorReason} from '../bot/plugins/error.ts';
|
||||
import {plain_plugin_object, valid_plugin_config, valid_plugin_name, valid_plugin_path} from './plugin_validation.ts';
|
||||
import {validate_code_map} from './validate_code_map.ts';
|
||||
|
||||
const codes = validate_code_map.plugin;
|
||||
const errors: Record<PluginErrorReason, number> = {
|
||||
INVALID_CONFIG: codes.invalid_config, ALREADY_INSTALLED: codes.already_installed,
|
||||
NOT_INSTALLED: codes.not_installed, MANAGER_DISPOSED: codes.manager_disposed,
|
||||
LOAD_FAILED: codes.load_failed, INIT_FAILED: codes.init_failed, DISPOSE_FAILED: codes.dispose_failed,
|
||||
};
|
||||
|
||||
export async function plugin_event_handler(operation: 'inject' | 'uninject' | 'update_config', socket: Socket, data: unknown, callback: unknown) {
|
||||
if (typeof callback !== 'function') {
|
||||
socket.emit('error', {error: validate_code_map.web.method_not_allowed});
|
||||
return;
|
||||
}
|
||||
let code: number = validate_code_map.web.invalid_parameter;
|
||||
try {
|
||||
const fields = operation === 'inject' ? ['bot_id', 'path', 'name', 'config']
|
||||
: operation === 'update_config' ? ['bot_id', 'name', 'config'] : ['bot_id', 'name'];
|
||||
if (plain_plugin_object(data) && Object.keys(data).length === fields.length
|
||||
&& fields.every(field => Object.hasOwn(data, field))
|
||||
&& typeof data.bot_id === 'number' && Number.isSafeInteger(data.bot_id) && data.bot_id > 0
|
||||
&& valid_plugin_name(data.name)
|
||||
&& (operation !== 'inject' || valid_plugin_path(data.path))
|
||||
&& (operation === 'uninject' || valid_plugin_config(data.config))) {
|
||||
const context = get_bot_context(data.bot_id);
|
||||
const manager = context?.plugin_manager;
|
||||
if (!context) code = codes.context_missing;
|
||||
else if (!manager) code = codes.manager_missing;
|
||||
else {
|
||||
if (operation === 'inject') await manager.inject({name: data.name, path: data.path as string, config: data.config});
|
||||
else if (operation === 'uninject') await manager.uninject(data.name);
|
||||
else await manager.update_config(data.name, data.config as Record<string, unknown>);
|
||||
code = codes.ok;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
code = error instanceof PluginError ? errors[error.reason] ?? codes.error : codes.error;
|
||||
}
|
||||
// A transport callback can throw; never retry it or expose its exception to the dispatcher.
|
||||
try { callback({status: code === codes.ok ? 'success' : 'error', data: code}); }
|
||||
catch {}
|
||||
}
|
||||
Reference in New Issue
Block a user