ghostguild-org/server/utils/outline.js
Jennie Robinson Faber 59d6e97787
Some checks failed
Test / vitest (push) Failing after 7m23s
Test / playwright (push) Has been skipped
Test / visual (push) Has been skipped
Test / Notify on failure (push) Successful in 2s
Member/Ecology revamp.
2026-04-14 09:25:09 +01:00

104 lines
2.7 KiB
JavaScript

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]))
}