import { readFileSync, existsSync } from 'fs'; import { resolve } from 'path'; const CONFIG_PATH = resolve('config.json'); export function loadEmbyConfig() { if (!existsSync(CONFIG_PATH)) return {}; try { return JSON.parse(readFileSync(CONFIG_PATH, 'utf-8')); } catch { return {}; } } export function normalizeEmbyGuid(value) { return typeof value === 'string' ? value.replace(/-/g, '').trim().toLowerCase() : ''; } export function buildEmbyUrl(pathname, params = {}) { const { embyUrl, apiKey } = loadEmbyConfig(); if (!embyUrl || !apiKey) { throw new Error('Emby URL and API key not configured'); } const base = embyUrl.replace(/\/+$/, ''); const path = pathname.startsWith('/') ? pathname : `/${pathname}`; const url = new URL(`${base}${path}`); for (const [key, value] of Object.entries({ ...params, api_key: apiKey })) { if (value === undefined || value === null || value === '') continue; url.searchParams.set(key, String(value)); } return { url, apiKey }; } export async function fetchEmby(pathname, options = {}) { const { params = {}, method = 'GET', headers = {}, body } = options; const { url, apiKey } = buildEmbyUrl(pathname, params); const response = await fetch(url, { method, headers: { Accept: 'application/json', 'X-Emby-Token': apiKey, ...headers }, body }); if (!response.ok) { const text = await response.text().catch(() => response.statusText); throw new Error(text || `${response.status} ${response.statusText}`); } return response; } export async function fetchEmbyJson(pathname, options = {}) { const response = await fetchEmby(pathname, options); return response.json(); }