From 237de91dce2032330d655b89a01332d243e99bc9 Mon Sep 17 00:00:00 2001 From: pylixonly <82711525+pylixonly@users.noreply.github.com> Date: Sat, 23 Nov 2024 11:31:19 +0800 Subject: [PATCH] refactor!: update spec 3 changes --- src/lib/addons/plugins/types.ts | 2 ++ src/lib/addons/themes/colors/parser.ts | 8 ++++--- src/lib/addons/themes/colors/types.ts | 11 +++++---- src/lib/addons/themes/index.ts | 31 +++++++++++++++++--------- src/lib/addons/types.ts | 2 ++ 5 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/lib/addons/plugins/types.ts b/src/lib/addons/plugins/types.ts index c490a23..0b6baea 100644 --- a/src/lib/addons/plugins/types.ts +++ b/src/lib/addons/plugins/types.ts @@ -24,6 +24,8 @@ export interface PluginSettingsStorage { } export interface BunnyPluginManifest extends BunnyManifest { + readonly type: "plugin"; + readonly spec: 3; readonly main: string; } diff --git a/src/lib/addons/themes/colors/parser.ts b/src/lib/addons/themes/colors/parser.ts index fd32653..fe33570 100644 --- a/src/lib/addons/themes/colors/parser.ts +++ b/src/lib/addons/themes/colors/parser.ts @@ -14,7 +14,7 @@ export function parseColorManifest(manifest: ColorManifest): InternalColorDefini if (manifest.spec === 3) { const semanticColorDefinitions: InternalColorDefinition["semantic"] = {}; - for (const [semanticColorKey, semanticColorValue] of Object.entries(manifest.semantic ?? {})) { + for (const [semanticColorKey, semanticColorValue] of Object.entries(manifest.main.semantic ?? {})) { if (typeof semanticColorValue === "object") { const { type, value, opacity: semanticColorOpacity } = semanticColorValue; @@ -47,12 +47,14 @@ export function parseColorManifest(manifest: ColorManifest): InternalColorDefini } } + if (Platform.OS === "android") applyAndroidAlphaKeys(manifest.main.raw); + return { spec: 3, reference: resolveType(manifest.type), semantic: semanticColorDefinitions, - raw: manifest.raw ?? {}, - background: manifest.background, + raw: manifest.main.raw ?? {}, + background: manifest.main.background, }; } else if (manifest.spec === 2) { // is Vendetta theme const semanticDefinitions: InternalColorDefinition["semantic"] = {}; diff --git a/src/lib/addons/themes/colors/types.ts b/src/lib/addons/themes/colors/types.ts index be87a53..99b6e39 100644 --- a/src/lib/addons/themes/colors/types.ts +++ b/src/lib/addons/themes/colors/types.ts @@ -13,11 +13,14 @@ interface BackgroundDefinition { } export interface BunnyColorManifest extends BunnyManifest { + type: "color"; spec: 3; - type: "dark" | "light"; - semantic?: Record; - raw?: Record; - background?: BackgroundDefinition; + main: { + type: "dark" | "light"; + semantic?: Record; + raw?: Record; + background?: BackgroundDefinition; + } } export interface VendettaThemeManifest { diff --git a/src/lib/addons/themes/index.ts b/src/lib/addons/themes/index.ts index 5028e2b..995d74a 100644 --- a/src/lib/addons/themes/index.ts +++ b/src/lib/addons/themes/index.ts @@ -60,30 +60,41 @@ function processData(data: VendettaThemeManifest) { return data; } -export async function fetchTheme(id: string, selected = false) { +function validateTheme(themeJSON: any): boolean { + if (typeof themeJSON !== "object" || themeJSON === null) return false; + if (themeJSON.spec !== 2 && themeJSON.spec !== 3) return false; + if (!themeJSON.main) return false; + + return true; +} + +export async function fetchTheme(url: string, selected = false) { let themeJSON: any; try { - themeJSON = await (await safeFetch(id, { cache: "no-store" })).json(); + themeJSON = await (await safeFetch(url, { cache: "no-store" })).json(); } catch { - throw new Error(`Failed to fetch theme at ${id}`); + throw new Error(`Failed to fetch theme at ${url}`); } - themes[id] = { - id: id, + // Validate theme + if (!validateTheme(themeJSON)) throw new Error(`Invalid theme at ${url}`); + + themes[url] = { + id: url, selected: selected, data: processData(themeJSON), }; if (selected) { - writeThemeToNative(themes[id]); - updateBunnyColor(themes[id].data, { update: true }); + writeThemeToNative(themes[url]); + updateBunnyColor(themes[url].data, { update: true }); } } -export async function installTheme(id: string) { - if (typeof id !== "string" || id in themes) throw new Error("Theme already installed"); - await fetchTheme(id); +export async function installTheme(url: string) { + if (typeof url !== "string" || url in themes) throw new Error("Theme already installed"); + await fetchTheme(url); } export function selectTheme(theme: VdThemeInfo | null, write = true) { diff --git a/src/lib/addons/types.ts b/src/lib/addons/types.ts index d38615f..447cdeb 100644 --- a/src/lib/addons/types.ts +++ b/src/lib/addons/types.ts @@ -2,6 +2,7 @@ export type Author = { name: string, id?: `${bigint}`; }; export interface BunnyManifest { readonly id: string; + readonly spec: number; readonly version: string; readonly type: string; readonly display: { @@ -9,6 +10,7 @@ export interface BunnyManifest { readonly description?: string; readonly authors?: Author[]; }; + readonly main: unknown; readonly extras?: { readonly [key: string]: any; };