import {
SESSIONIZE_API_ORIGIN,
SESSIONIZE_VIEWS,
type SessionizeView,
} from './types.ts'
const ENDPOINT_ID_RE = /^[a-z0-9]{4,32}$/i
export function assertEndpointId(endpointId: string): string {
const id = endpointId.trim()
if (!ENDPOINT_ID_RE.test(id)) {
throw new Error(
`Invalid Sessionize endpointId "${endpointId}". Create a JSON endpoint on the event API / Embed page, then copy the id from https://sessionize.com/api/v2/<id>/view/All.`,
)
}
return id
}
export function isSessionizeView(value: string): value is SessionizeView {
return (SESSIONIZE_VIEWS as readonly string[]).includes(value)
}
export function requireSessionizeView(value: string): SessionizeView {
if (isSessionizeView(value)) return value
throw new Error(
`Unsupported Sessionize view "${value}". Use one of: ${SESSIONIZE_VIEWS.join(', ')}.`,
)
}
export function sessionizeViewUrl(
endpointId: string,
view: SessionizeView,
): string {
const id = assertEndpointId(endpointId)
const resolvedView = requireSessionizeView(view)
switch (resolvedView) {
case 'All':
case 'Sessions':
case 'Speakers':
case 'GridSmart':
return `${SESSIONIZE_API_ORIGIN}/api/v2/${id}/view/${resolvedView}`
default: {
const exhaustive: never = resolvedView
throw new Error(`Unhandled Sessionize view: ${String(exhaustive)}`)
}
}
}
export async function fetchSessionizeView<T>(params: {
endpointId: string
view: SessionizeView
}): Promise<T> {
const url = sessionizeViewUrl(params.endpointId, params.view)
const response = await fetch(url, {
headers: { Accept: 'application/json' },
})
const text = await response.text()
if (!response.ok) {
throw new Error(
`Sessionize ${params.view} failed (${response.status}) for ${url}.`,
)
}
try {
return JSON.parse(text) as T
} catch {
throw new Error(`Sessionize ${params.view} returned non-JSON for ${url}.`)
}
}
export function normalizeId(value: string | number): string {
return String(value)
}