this repo has no description

Merge branch 'develop' of github.com:moonlight-mod/moonlight into develop

Changed files
+91 -64
packages
browser
src
core
src
util
core-extensions
src
moonbase
webpackModules
node-preload
src
types
web-preload
src
+20 -16
packages/browser/src/index.ts
··· 4 4 import { getExtensions } from "@moonlight-mod/core/extension"; 5 5 import { loadExtensions } from "@moonlight-mod/core/extension/loader"; 6 6 import { MoonlightBranch, MoonlightNode } from "@moonlight-mod/types"; 7 + import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config"; 7 8 import { IndexedDB } from "@zenfs/dom"; 8 9 import { configure } from "@zenfs/core"; 9 10 import * as fs from "@zenfs/core/promises"; ··· 99 100 }; 100 101 101 102 // Actual loading begins here 102 - const config = await readConfig(); 103 + let config = await readConfig(); 103 104 initLogger(config); 104 105 105 106 const extensions = await getExtensions(); 106 107 const processedExtensions = await loadExtensions(extensions); 107 108 108 - function getConfig(ext: string) { 109 - const val = config.extensions[ext]; 110 - if (val == null || typeof val === "boolean") return undefined; 111 - return val.config; 112 - } 113 - 114 109 const moonlightNode: MoonlightNode = { 115 - config, 110 + get config() { 111 + return config; 112 + }, 116 113 extensions, 117 114 processedExtensions, 118 115 nativesCache: {}, ··· 121 118 version: MOONLIGHT_VERSION, 122 119 branch: MOONLIGHT_BRANCH as MoonlightBranch, 123 120 124 - getConfig, 125 - getConfigOption: <T>(ext: string, name: string) => { 126 - const config = getConfig(ext); 127 - if (config == null) return undefined; 128 - const option = config[name]; 129 - if (option == null) return undefined; 130 - return option as T; 121 + getConfig(ext) { 122 + return getConfig(ext, config); 123 + }, 124 + getConfigOption(ext, name) { 125 + const manifest = getManifest(extensions, ext); 126 + return getConfigOption(ext, name, config, manifest); 131 127 }, 128 + setConfigOption(ext, name, value) { 129 + setConfigOption(config, ext, name, value); 130 + this.writeConfig(config); 131 + }, 132 + 132 133 getNatives: () => {}, 133 134 getLogger: (id: string) => { 134 135 return new Logger(id); ··· 141 142 return `/extensions/${ext}`; 142 143 }, 143 144 144 - writeConfig 145 + async writeConfig(newConfig) { 146 + await writeConfig(newConfig); 147 + config = newConfig; 148 + } 145 149 }; 146 150 147 151 Object.assign(window, {
-9
packages/core-extensions/src/moonbase/native.ts
··· 178 178 async deleteExtension(id) { 179 179 const dir = moonlightNode.getExtensionDir(id); 180 180 await moonlightNodeSandboxed.fs.rmdir(dir); 181 - }, 182 - 183 - getExtensionConfig(id, key) { 184 - const config = moonlightNode.config.extensions[id]; 185 - if (typeof config === "object") { 186 - return config.config?.[key]; 187 - } 188 - 189 - return undefined; 190 181 } 191 182 }; 192 183 }
-1
packages/core-extensions/src/moonbase/types.ts
··· 8 8 fetchRepositories(repos: string[]): Promise<Record<string, RepositoryManifest[]>>; 9 9 installExtension(manifest: RepositoryManifest, url: string, repo: string): Promise<void>; 10 10 deleteExtension(id: string): Promise<void>; 11 - getExtensionConfig(id: string, key: string): any; 12 11 }; 13 12 14 13 export type RepositoryManifest = ExtensionManifest & {
+3 -20
packages/core-extensions/src/moonbase/webpackModules/stores.ts
··· 6 6 import { mainRepo } from "@moonlight-mod/types/constants"; 7 7 import { checkExtensionCompat, ExtensionCompat } from "@moonlight-mod/core/extension/loader"; 8 8 import { CustomComponent } from "@moonlight-mod/types/coreExtensions/moonbase"; 9 + import { getConfigOption, setConfigOption } from "@moonlight-mod/core/util/config"; 9 10 10 11 const logger = moonlight.getLogger("moonbase"); 11 12 ··· 191 192 192 193 getExtensionConfig<T>(uniqueId: number, key: string): T | undefined { 193 194 const ext = this.getExtension(uniqueId); 194 - const defaultValue = ext.manifest.settings?.[key]?.default; 195 - const clonedDefaultValue = this.clone(defaultValue); 196 - const cfg = this.config.extensions[ext.id]; 197 - 198 - if (cfg == null || typeof cfg === "boolean") return clonedDefaultValue; 199 - return cfg.config?.[key] ?? clonedDefaultValue; 195 + return getConfigOption(ext.id, key, this.config, ext.manifest); 200 196 } 201 197 202 198 getExtensionConfigRaw<T>(id: string, key: string, defaultValue: T | undefined): T | undefined { 203 199 const cfg = this.config.extensions[id]; 204 - 205 200 if (cfg == null || typeof cfg === "boolean") return defaultValue; 206 201 return cfg.config?.[key] ?? defaultValue; 207 202 } ··· 217 212 } 218 213 219 214 setExtensionConfig(id: string, key: string, value: any) { 220 - const oldConfig = this.config.extensions[id]; 221 - const newConfig = 222 - typeof oldConfig === "boolean" 223 - ? { 224 - enabled: oldConfig, 225 - config: { [key]: value } 226 - } 227 - : { 228 - ...oldConfig, 229 - config: { ...(oldConfig?.config ?? {}), [key]: value } 230 - }; 231 - 232 - this.config.extensions[id] = newConfig; 215 + setConfigOption(this.config, id, key, value); 233 216 this.modified = this.isModified(); 234 217 this.emitChange(); 235 218 }
+39
packages/core/src/util/config.ts
··· 1 + import type { Config, DetectedExtension, ExtensionManifest } from "@moonlight-mod/types"; 2 + 3 + export function getManifest(extensions: DetectedExtension[], ext: string) { 4 + return extensions.find((x) => x.id === ext)?.manifest; 5 + } 6 + 7 + export function getConfig(ext: string, config: Config) { 8 + const val = config.extensions[ext]; 9 + if (val == null || typeof val === "boolean") return undefined; 10 + return val.config; 11 + } 12 + 13 + export function getConfigOption<T>( 14 + ext: string, 15 + key: string, 16 + config: Config, 17 + manifest?: ExtensionManifest 18 + ): T | undefined { 19 + const defaultValue: T | undefined = structuredClone(manifest?.settings?.[key]?.default); 20 + const cfg = getConfig(ext, config); 21 + if (cfg == null || typeof cfg === "boolean") return defaultValue; 22 + return cfg?.[key] ?? defaultValue; 23 + } 24 + 25 + export function setConfigOption<T>(config: Config, ext: string, key: string, value: T) { 26 + const oldConfig = config.extensions[ext]; 27 + const newConfig = 28 + typeof oldConfig === "boolean" 29 + ? { 30 + enabled: oldConfig, 31 + config: { [key]: value } 32 + } 33 + : { 34 + ...oldConfig, 35 + config: { ...(oldConfig?.config ?? {}), [key]: value } 36 + }; 37 + 38 + config.extensions[ext] = newConfig; 39 + }
+20 -16
packages/node-preload/src/index.ts
··· 10 10 import { loadExtensions, loadProcessedExtensions } from "@moonlight-mod/core/extension/loader"; 11 11 import createFS from "@moonlight-mod/core/fs"; 12 12 import { registerCors, registerBlocked, getDynamicCors } from "@moonlight-mod/core/cors"; 13 + import { getConfig, getConfigOption, getManifest, setConfigOption } from "@moonlight-mod/core/util/config"; 13 14 14 15 let initialized = false; 15 16 ··· 32 33 } 33 34 }; 34 35 35 - const config = await readConfig(); 36 + let config = await readConfig(); 36 37 initLogger(config); 37 38 const extensions = await getExtensions(); 38 39 const processedExtensions = await loadExtensions(extensions); 39 40 const moonlightDir = await getMoonlightDir(); 40 41 const extensionsPath = await getExtensionsPath(); 41 - 42 - function getConfig(ext: string) { 43 - const val = config.extensions[ext]; 44 - if (val == null || typeof val === "boolean") return undefined; 45 - return val.config; 46 - } 47 42 48 43 global.moonlightNode = { 49 - config, 44 + get config() { 45 + return config; 46 + }, 50 47 extensions, 51 48 processedExtensions, 52 49 nativesCache: {}, ··· 55 52 version: MOONLIGHT_VERSION, 56 53 branch: MOONLIGHT_BRANCH as MoonlightBranch, 57 54 58 - getConfig, 59 - getConfigOption: <T>(ext: string, name: string) => { 60 - const config = getConfig(ext); 61 - if (config == null) return undefined; 62 - const option = config[name]; 63 - if (option == null) return undefined; 64 - return option as T; 55 + getConfig(ext) { 56 + return getConfig(ext, config); 57 + }, 58 + getConfigOption(ext, name) { 59 + const manifest = getManifest(extensions, ext); 60 + return getConfigOption(ext, name, config, manifest); 65 61 }, 62 + setConfigOption(ext, name, value) { 63 + setConfigOption(config, ext, name, value); 64 + this.writeConfig(config); 65 + }, 66 + 66 67 getNatives: (ext: string) => global.moonlightNode.nativesCache[ext], 67 68 getLogger: (id: string) => { 68 69 return new Logger(id); ··· 74 75 getExtensionDir: (ext: string) => { 75 76 return path.join(extensionsPath, ext); 76 77 }, 77 - writeConfig 78 + async writeConfig(newConfig) { 79 + await writeConfig(newConfig); 80 + config = newConfig; 81 + } 78 82 }; 79 83 80 84 await loadProcessedExtensions(processedExtensions);
+7 -2
packages/types/src/globals.ts
··· 34 34 35 35 getConfig: (ext: string) => ConfigExtension["config"]; 36 36 getConfigOption: <T>(ext: string, name: string) => T | undefined; 37 + setConfigOption: <T>(ext: string, name: string, value: T) => void; 38 + 37 39 getNatives: (ext: string) => any | undefined; 38 40 getLogger: (id: string) => Logger; 39 41 ··· 63 65 version: string; 64 66 branch: MoonlightBranch; 65 67 66 - getConfig: (ext: string) => ConfigExtension["config"]; 67 - getConfigOption: <T>(ext: string, name: string) => T | undefined; 68 + // Re-exports for ease of use 69 + getConfig: MoonlightNode["getConfig"]; 70 + getConfigOption: MoonlightNode["getConfigOption"]; 71 + setConfigOption: MoonlightNode["setConfigOption"]; 72 + 68 73 getNatives: (ext: string) => any | undefined; 69 74 getLogger: (id: string) => Logger; 70 75 lunast: LunAST;
+2
packages/web-preload/src/index.ts
··· 30 30 31 31 getConfig: moonlightNode.getConfig.bind(moonlightNode), 32 32 getConfigOption: moonlightNode.getConfigOption.bind(moonlightNode), 33 + setConfigOption: moonlightNode.setConfigOption.bind(moonlightNode), 34 + 33 35 getNatives: moonlightNode.getNatives.bind(moonlightNode), 34 36 getLogger(id) { 35 37 return new Logger(id);