feat: Typesafe Settings Definitions (#403)

Co-authored-by: Ven <vendicated@riseup.net>
This commit is contained in:
Justice Almanzar 2023-01-13 17:15:45 -05:00 committed by GitHub
parent 6c5fcc4119
commit ea748dfb60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
15 changed files with 288 additions and 180 deletions

View file

@ -19,7 +19,7 @@
import IpcEvents from "@utils/IpcEvents";
import Logger from "@utils/Logger";
import { mergeDefaults } from "@utils/misc";
import { OptionType } from "@utils/types";
import { DefinedSettings, OptionType, SettingsChecks, SettingsDefinition } from "@utils/types";
import { React } from "@webpack/common";
import plugins from "~plugins";
@ -146,6 +146,7 @@ export const Settings = makeProxy(settings);
* @param paths An optional list of paths to whitelist for rerenders
* @returns Settings
*/
// TODO: Representing paths as essentially "string[].join('.')" wont allow dots in paths, change to "paths?: string[][]" later
export function useSettings(paths?: string[]) {
const [, forceUpdate] = React.useReducer(() => ({}), {});
@ -200,3 +201,19 @@ export function migratePluginSettings(name: string, ...oldNames: string[]) {
}
}
}
export function definePluginSettings<D extends SettingsDefinition, C extends SettingsChecks<D>>(def: D, checks?: C) {
const definedSettings: DefinedSettings<D> = {
get store() {
if (!definedSettings.pluginName) throw new Error("Cannot access settings before plugin is initialized");
return Settings.plugins[definedSettings.pluginName] as any;
},
use: settings => useSettings(
settings?.map(name => `plugins.${definedSettings.pluginName}.${name}`)
).plugins[definedSettings.pluginName] as any,
def,
checks: checks ?? {},
pluginName: "",
};
return definedSettings;
}