Something went wrong. Try again.
Starship Simulator Controls thoriumsim.com
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189import path from "node:path";
import ThemePlugin from "@thorium/.server/classes/Plugins/Theme";import { pubsub } from "@thorium/.server/init/pubsub";import { t } from "@thorium/.server/init/t";import inputAuth from "@thorium/utils/.server/inputAuth";import z from "zod";
import { getPlugin } from "./utils";
export const theme = t.router({ all: t.procedure .input(z.object({ pluginId: z.string() })) .filter((publish: { pluginId: string } | null, { input }) => { if (!input) return false; if (publish && input.pluginId !== publish.pluginId) return false; return true; }) .request(({ ctx, input }) => { const plugin = getPlugin(ctx, input.pluginId); return Promise.all( plugin.aspects.themes.map(async (theme) => { const assetPath = await theme.getAssetUrl(); let rawCSS = ""; try { rawCSS = await ctx.readFile.call(theme, path.join(assetPath, theme.assets.rawCSS)); } catch { await ctx.uploadFile.call(theme, new Blob([""], { type: "text/css" }), "raw.css"); }
return { ...theme.toJSON(), rawCSS, }; }), ); }), get: t.procedure .input(z.object({ pluginId: z.string(), themeId: z.string() })) .filter((publish: { pluginId: string; themeId: string } | null, { input }) => { if (publish && (input.pluginId !== publish.pluginId || input.themeId !== publish.themeId)) return false; return true; }) .request(async ({ ctx, input }) => { const plugin = getPlugin(ctx, input.pluginId); const theme = plugin.aspects.themes.find((theme) => theme.name === input.themeId); if (!theme) throw new Error("Theme not found"); const assetPath = await theme.getAssetUrl();
let rawCSS = ""; try { rawCSS = await ctx.readFile.call(theme, path.join(assetPath, theme.assets.rawCSS)); } catch { await ctx.uploadFile.call(theme, new Blob([""], { type: "text/css" }), "raw.css"); }
return { ...theme.toJSON(), rawCSS, }; }), available: t.procedure.request(({ ctx }) => { return ctx.server.plugins.reduce((themes: { themeId: string; pluginId: string }[], plugin) => { return themes.concat( plugin.aspects.themes.map((theme) => ({ themeId: theme.name, pluginId: plugin.id, })), ); }, []); }), create: t.procedure .input(z.object({ pluginId: z.string(), name: z.string() })) .send(async ({ ctx, input }) => { inputAuth(ctx); const plugin = getPlugin(ctx, input.pluginId); const theme = await ThemePlugin.create({ name: input.name }, plugin); plugin.aspects.themes.push(theme);
pubsub.publish.plugin.theme.all({ pluginId: input.pluginId }); return { themeId: theme.name }; }), delete: t.procedure .input(z.object({ pluginId: z.string(), themeId: z.string() })) .send(async ({ ctx, input }) => { inputAuth(ctx); const plugin = getPlugin(ctx, input.pluginId); const theme = plugin.aspects.themes.find((theme) => theme.name === input.themeId); if (!theme) throw new Error("Theme not found."); plugin.aspects.themes.splice(plugin.aspects.themes.indexOf(theme), 1);
pubsub.publish.plugin.theme.all({ pluginId: input.pluginId });
await theme?.remove(); }), update: t.procedure .input( z.intersection( z.object({ pluginId: z.string(), themeId: z.string() }), z.union([z.object({ name: z.string() }), z.object({ rawCSS: z.string() })]), ), ) .send(async ({ ctx, input }) => { inputAuth(ctx); const plugin = getPlugin(ctx, input.pluginId); const theme = plugin.aspects.themes.find((theme) => theme.name === input.themeId); if (!theme) throw new Error("Theme not found."); if ("rawCSS" in input) { theme.assets.rawCSS = await ctx.uploadFile.call( theme, new Blob([input.rawCSS], { type: "text/css" }), "raw.css", ); } if ("name" in input) { await theme.rename(input.name); } pubsub.publish.plugin.theme.all({ pluginId: input.pluginId }); pubsub.publish.plugin.theme.get({ pluginId: input.pluginId, themeId: theme.name, }); return { themeId: theme.name, ...("rawCSS" in input ? { rawCSS: input.rawCSS } : {}), }; }), duplicate: t.procedure .input(z.object({ pluginId: z.string(), themeId: z.string(), name: z.string() })) .send(async ({ ctx, input }) => { inputAuth(ctx); const plugin = getPlugin(ctx, input.pluginId); const theme = plugin.aspects.themes.find((theme) => theme.name === input.themeId); if (!theme) throw new Error("Theme not found."); const themeCopy = await theme.duplicate(input.name); pubsub.publish.plugin.theme.all({ pluginId: input.pluginId }); return { themeId: themeCopy.name }; }), uploadFile: t.procedure .input( z.object({ pluginId: z.string(), themeId: z.string(), file: z.instanceof(File), fileName: z.string(), }), ) .send(async ({ ctx, input }) => { inputAuth(ctx); const plugin = getPlugin(ctx, input.pluginId); const theme = plugin.aspects.themes.find((theme) => theme.name === input.themeId); if (!theme) throw new Error("Theme not found.");
theme.assets.files.push(await ctx.uploadFile.call(theme, input.file, input.fileName));
pubsub.publish.plugin.theme.all({ pluginId: input.pluginId }); pubsub.publish.plugin.theme.get({ pluginId: input.pluginId, themeId: theme.name, }); return { themeId: theme.name }; }), removeFile: t.procedure .input( z.object({ pluginId: z.string(), themeId: z.string(), file: z.string(), }), ) .send(async ({ ctx, input }) => { inputAuth(ctx); const plugin = getPlugin(ctx, input.pluginId); const theme = plugin.aspects.themes.find((theme) => theme.name === input.themeId); if (!theme) throw new Error("Theme not found."); if (typeof input.file !== "string") throw new Error("Invalid file."); await theme.removeAsset(input.file);
pubsub.publish.plugin.theme.all({ pluginId: input.pluginId }); pubsub.publish.plugin.theme.get({ pluginId: input.pluginId, themeId: theme.name, });
return { themeId: theme.name }; }),});