// @flow import { get, set } from 'idb-keyval'; import logger from './utils/logger.js' async function init(obj: Object): Promise { //TODO: check for enabled plugins in the idb, start them let globalSettings = await get("demoncord") if (globalSettings === undefined) { await set("demoncord", {plugin: {}}) globalSettings = await get("demoncord") } obj.demon.__plugins = {} for (let plug: Object in globalSettings.plugin) { plug = globalSettings.plugin[plug] if (plug.enabled) { startPlugin(plug.metadata.name) } } return true } async function addPlugin(iife: string, metadata: Object): Promise { // expected metadata: {name: "name", desc: "description", author: "author"} const obj: Object = { // whether the plugin is started or stopped isn't going to be stored in the iDB, so it can be accessed more easily by all components metadata: metadata, iife: iife, enabled: false // should plugins be enabled by default? not sure } const globalSettings: Object = await get("demoncord"); /*try { if (globalSettings["plugin"][metadata.name] !== undefined) { log("Cannot add plugin that already exists!", "error", "Plugins") return false } } catch (error) {*/ globalSettings["plugin"][metadata.name] = obj //} //Disabling checking for previous plugins for now as it is breaking literally fucking everything await set("demoncord", globalSettings) return true } async function delPlugin(name: string): Promise { const globalSettings = await get("demoncord") if (globalSettings["plugin"][name] === undefined) { logger.error("Cannot remove non-existant plugin!", ["Plugins"]) return false } else { globalSettings["plugin"][name] = undefined delete globalSettings["plugin"][name] } await set("demoncord", globalSettings) return true } async function startPlugin(name: string): Promise { const globalSettings = await get("demoncord") if (globalSettings["plugin"][name] === undefined) { logger.error("Cannot start non-existant plugin!", ["Plugins"]) return false } else { logger.log(`Starting ${name}...`, ["Plugins"]) const plug = globalSettings["plugin"][name] const exports: Object = (0, eval)(plug.iife) const onStart: (ctx: Object)=>void = exports.onStart let ctx = {} // ctx is how you're going to store things that need to be accessed in both onStart and onStop. dumb, i know onStart(ctx) logger.log(`Started ${name}!`, ["Plugins"]) window.demon.__plugins[name] = {status: 1, ctx: ctx} return true } } async function stopPlugin(name: string): Promise { const globalSettings = await get("demoncord") if (globalSettings["plugin"][name] === undefined ) { logger.error("Cannot stop non-existant or non-running plugin!", ["Plugins"]) return false } else { logger.log(`Stopping ${name}...`, ["Plugins"]) const plug = globalSettings["plugin"][name] const exports: Object = (0, eval)(plug.iife) const onStop: (ctx: Object)=>void = exports.onStop onStop(window.demon.__plugins[name].ctx) logger.log(`Stopped ${name}!`, ["Plugins"]) return true } } async function togglePlugin(name: string): Promise { const globalSettings = await get("demoncord") if (globalSettings["plugin"][name] === undefined) { logger.error("Cannot toggle non-existant plugin!", ["Plugins"]) return false } else { globalSettings["plugin"][name].enabled = !globalSettings["plugin"][name].enabled await set("demoncord", globalSettings) return true } } export default { init, addPlugin, delPlugin, startPlugin, stopPlugin, togglePlugin }