Files
OctoLauncher/src/main/api/routers/news.ts
T
OctoWoW 5dca94a3fc OctoLauncher 1.3.1
Manifest-based CDN updater and mod manager for the OctoWoW 1.12.1 client:
launcher-owned realmlist, torrent-backed content sync with bundled aria2c,
antivirus and Defender exclusion handling, hardware-aware render distance,
optional client tweaks and mods, and the in-launcher news feed.
2026-08-14 01:45:50 +00:00

50 lines
1.4 KiB
TypeScript

import { z } from 'zod';
import fetch from 'node-fetch';
import Logger from 'electron-log/main';
import { NewsFeedSchema, type NewsItem } from '~common/schemas';
import { createTRPCRouter, publicProcedure } from '../trpc';
const FETCH_TIMEOUT_MS = 8_000;
// Boards octonews.php exposes as a list: 2 = Announcements, 4 = Patch Notes.
const FEED_FORUMS = [2, 4];
const fetchNews = async (forum: number): Promise<NewsItem[]> => {
const f = FEED_FORUMS.includes(forum) ? forum : 2;
const url = `${
import.meta.env.MAIN_VITE_FORUM_URL || 'https://octowow.st'
}/forum/octonews.php?mode=list&forum=${f}&limit=5`;
const controller = new AbortController();
const t = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
try {
const res = await fetch(url, { signal: controller.signal });
if (!res.ok) throw Error(`HTTP ${res.status}`);
const parsed = NewsFeedSchema.safeParse(await res.json());
if (!parsed.success) {
Logger.error(
'News feed failed schema validation',
parsed.error.flatten()
);
throw Error('Malformed news feed');
}
return parsed.data.items;
} finally {
clearTimeout(t);
}
};
export const newsRouter = createTRPCRouter({
list: publicProcedure
.input(z.object({ forum: z.number() }).optional())
.query(async ({ input }) => {
try {
return await fetchNews(input?.forum ?? 2);
} catch (e) {
Logger.error('Failed to fetch news', e);
throw e;
}
})
});