Fix addon errors, improve plugin loading

This commit is contained in:
Zack Rauen 2022-06-25 01:57:35 -04:00
parent 569a94f99f
commit ac5d2baf57
4 changed files with 29 additions and 5 deletions

View File

@ -20,7 +20,7 @@ const DiscordClassModules = Utilities.memoizeObject({
); );
}, },
get EmptyImage() {return WebpackModules.getByProps("emptyImage", "emptyHeader");}, get EmptyImage() {return WebpackModules.getByProps("emptyImage", "emptyHeader");},
get Modal() {return WebpackModules.getByProps("content", "root", "header");}, get Modal() {return WebpackModules.getByProps("content", "root", "header", "close");},
get Scrollers() {return WebpackModules.getByProps("thin", "scrollerBase", "content");}, get Scrollers() {return WebpackModules.getByProps("thin", "scrollerBase", "content");},
get Margins() {return WebpackModules.getByProps("marginXSmall", "marginBottom8");}, get Margins() {return WebpackModules.getByProps("marginXSmall", "marginBottom8");},
get Integrations() {return WebpackModules.getByProps("secondaryHeader", "detailsWrapper");}, get Integrations() {return WebpackModules.getByProps("secondaryHeader", "detailsWrapper");},

View File

@ -9,10 +9,20 @@ import Events from "./emitter";
import Toasts from "../ui/toasts"; import Toasts from "../ui/toasts";
import Modals from "../ui/modals"; import Modals from "../ui/modals";
import SettingsRenderer from "../ui/settings"; import SettingsRenderer from "../ui/settings";
import Utilities from "./utilities";
const path = require("path"); const path = require("path");
const vm = require("vm"); const vm = require("vm");
const fileModification = name => `
if (module.exports.default) {
module.exports = module.exports.default;
}
if (typeof(module.exports) !== "function") {
module.exports = eval("${name};")
}`;
export default new class PluginManager extends AddonManager { export default new class PluginManager extends AddonManager {
get name() {return "PluginManager";} get name() {return "PluginManager";}
get moduleExtension() {return ".js";} get moduleExtension() {return ".js";}
@ -78,8 +88,16 @@ export default new class PluginManager extends AddonManager {
if (!addon.exports || !addon.name) return new AddonError(addon.name || addon.filename, addon.filename, "Plugin had no exports or @name property", {message: "Plugin had no exports or no @name property. @name property is required for all addons.", stack: ""}, this.prefix); if (!addon.exports || !addon.name) return new AddonError(addon.name || addon.filename, addon.filename, "Plugin had no exports or @name property", {message: "Plugin had no exports or no @name property. @name property is required for all addons.", stack: ""}, this.prefix);
try { try {
const isValid = typeof(addon.exports) === "function";
if (!isValid) return new AddonError(addon.name || addon.filename, addon.filename, "Plugin not a valid format.", {message: "Plugins should be either a function or a class", stack: ""}, this.prefix);
const isClass = Utilities.isClass(addon.exports);
const PluginClass = addon.exports; const PluginClass = addon.exports;
const thePlugin = new PluginClass(); const meta = Object.assign({}, addon);
delete meta.exports;
const thePlugin = isClass ? new PluginClass(meta) : addon.exports(meta);
if (!thePlugin.start || !thePlugin.stop) return new AddonError(addon.name || addon.filename, addon.filename, "Missing start or stop function.", {message: "Plugins must have both a start and stop function.", stack: ""}, this.prefix);;
addon.instance = thePlugin; addon.instance = thePlugin;
addon.name = thePlugin.getName ? thePlugin.getName() : addon.name; addon.name = thePlugin.getName ? thePlugin.getName() : addon.name;
addon.author = thePlugin.getAuthor ? thePlugin.getAuthor() : addon.author || "No author"; addon.author = thePlugin.getAuthor ? thePlugin.getAuthor() : addon.author || "No author";
@ -93,11 +111,13 @@ export default new class PluginManager extends AddonManager {
return new AddonError(addon.name, addon.filename, "load() could not be fired.", {message: error.message, stack: error.stack}, this.prefix); return new AddonError(addon.name, addon.filename, "load() could not be fired.", {message: error.message, stack: error.stack}, this.prefix);
} }
} }
catch (error) {return new AddonError(addon.name, addon.filename, "Could not be constructed.", {message: error.message, stack: error.stack}, this.prefix);} catch (error) {
return new AddonError(addon.name, addon.filename, "Could not be constructed.", {message: error.message, stack: error.stack}, this.prefix);
}
} }
getFileModification(module, fileContent, meta) { getFileModification(module, fileContent, meta) {
fileContent += `\nif (module.exports.default) {module.exports = module.exports.default;}\nif (!module.exports.prototype || !module.exports.prototype.start) {module.exports = ${meta.exports || meta.name};}`; fileContent += fileModification(meta.exports || meta.name);
window.global = window; window.global = window;
window.module = module; window.module = module;

View File

@ -113,6 +113,10 @@ export default class Utilities {
return true; return true;
} }
static isClass(obj) {
return typeof(obj) === "function" && /^\s*class\s+/.test(obj.toString());
}
/** /**
* Generates an automatically memoizing version of an object. * Generates an automatically memoizing version of an object.
* @author Zerebos * @author Zerebos

View File

@ -19,7 +19,7 @@ class AddonError extends React.Component {
this.setState({expanded: !this.state.expanded}); this.setState({expanded: !this.state.expanded});
} }
renderErrorBody(err) { renderErrorBody(err) {
const stack = err.error && err.stack; const stack = err?.error?.stack ?? err.stack;
if (!this.state.expanded || !stack) return null; if (!this.state.expanded || !stack) return null;
return <div className="bd-addon-error-body"> return <div className="bd-addon-error-body">
<Divider /> <Divider />