5dca94a3fc
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.
50 lines
1.4 KiB
TypeScript
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;
|
|
}
|
|
})
|
|
});
|