const OUTLINE_API_BASE = 'https://wiki.ghostguild.org/api' /** * Strip HTML tags and truncate to 200 characters at a word boundary. * If the stripped text is <= 200 chars, returns it as-is. */ export function extractSummary(text) { if (!text) return '' const stripped = text.replace(/<[^>]*>/g, '').trim() if (stripped.length <= 200) return stripped const truncated = stripped.slice(0, 200) const lastSpace = truncated.lastIndexOf(' ') // If no space found at all, return the full 200 chars (single long word) if (lastSpace <= 0) return truncated return truncated.slice(0, lastSpace) } /** * Fetch all documents from Outline wiki, paginating through all pages. * Throws on any page failure — caller is responsible for abort logic. */ export async function fetchAllDocuments() { const config = useRuntimeConfig() const apiKey = config.outlineApiKey if (!apiKey) { throw createError({ statusCode: 500, statusMessage: 'Outline API key not configured' }) } const documents = [] let offset = 0 const limit = 25 while (true) { const response = await fetch(`${OUTLINE_API_BASE}/documents.list`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` }, body: JSON.stringify({ offset, limit }) }) if (!response.ok) { const errorText = await response.text() console.error(`[outline] POST /documents.list offset=${offset} ${response.status} ${errorText}`) throw createError({ statusCode: response.status, statusMessage: 'Outline API error' }) } const data = await response.json() const page = data.data || [] documents.push(...page) if (page.length < limit) break offset += limit } return documents } export async function fetchCollections() { const config = useRuntimeConfig() const apiKey = config.outlineApiKey if (!apiKey) { throw createError({ statusCode: 500, statusMessage: 'Outline API key not configured' }) } const response = await fetch(`${OUTLINE_API_BASE}/collections.list`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${apiKey}` }, body: JSON.stringify({ limit: 100 }) }) if (!response.ok) { const errorText = await response.text() console.error(`[outline] POST /collections.list ${response.status} ${errorText}`) throw createError({ statusCode: response.status, statusMessage: 'Outline API error' }) } const data = await response.json() const collections = data.data || [] return new Map(collections.map(c => [c.id, c.name])) }