official.js•2.07 kB
import { fetchWithRetry } from './sharedFetch.js';
const BASE_URL = 'https://official-joke-api.appspot.com';
const CATEGORY_ENDPOINT = {
programming: 'programming',
general: 'general',
pun: 'general',
spooky: 'general',
christmas: 'general',
};
export async function getJoke(preferences, context = {}) {
const { category, lang } = preferences;
const { timeoutMs = 2000, retries = 0, fetchImpl, allowNet = true } = context;
if (!allowNet) {
throw new Error('Network access disabled for Official Joke API');
}
if (lang && lang !== 'en') {
throw new Error('Official Joke API only provides English jokes');
}
const endpoint = CATEGORY_ENDPOINT[category] ?? 'random';
const url = buildUrl(endpoint);
const response = await fetchWithRetry(url, { headers: { Accept: 'application/json' } }, { timeoutMs, retries, fetchImpl });
const payload = await response.json();
const joke = Array.isArray(payload) ? payload[0] : payload;
if (!joke) {
throw new Error('Official Joke API returned an empty response');
}
const text = buildText(joke);
const normalizedCategory = toInternalCategory(joke.type) ?? category ?? 'general';
return {
text,
category: normalizedCategory,
source: 'official',
};
}
function buildUrl(endpoint) {
if (endpoint === 'random') {
return `${BASE_URL}/random_joke`;
}
return `${BASE_URL}/jokes/${endpoint}/random`;
}
function buildText(joke) {
const setup = joke.setup ?? '';
const punchline = joke.punchline ?? '';
if (!setup && !punchline) {
throw new Error('Official Joke API response missing joke text');
}
if (!setup) return punchline;
if (!punchline) return setup;
return `${setup}\n${punchline}`;
}
function toInternalCategory(category) {
if (!category) return undefined;
const normalized = String(category).trim().toLowerCase();
switch (normalized) {
case 'programming':
return 'programming';
case 'general':
return 'general';
case 'knock-knock':
return 'general';
default:
return undefined;
}
}