| export class ArchiveApiError extends Error { |
| constructor(message, status = 500, data = null) { |
| super(message); |
| this.name = 'ArchiveApiError'; |
| this.status = status; |
| this.data = data; |
| } |
| } |
|
|
| function withQuery(path, query = {}) { |
| const params = new URLSearchParams(); |
| Object.entries(query || {}).forEach(([key, value]) => { |
| if (value === undefined || value === null || value === '') return; |
| params.set(key, String(value)); |
| }); |
| const queryString = params.toString(); |
| return queryString ? `${path}?${queryString}` : path; |
| } |
|
|
| async function request(path, { token, method = 'GET', query = null, body = null } = {}) { |
| const headers = {}; |
|
|
| if (token) { |
| headers.Authorization = `Bearer ${token}`; |
| } |
|
|
| if (method !== 'GET' && method !== 'HEAD') { |
| headers['Content-Type'] = 'application/json'; |
| } |
|
|
| const response = await fetch(withQuery(path, query), { |
| method, |
| headers, |
| body: body ? JSON.stringify(body) : undefined, |
| }); |
|
|
| const payload = await response.json().catch(() => ({})); |
|
|
| if (!response.ok) { |
| throw new ArchiveApiError(payload?.message || 'Archive API error', response.status, payload); |
| } |
|
|
| return payload; |
| } |
|
|
| export function ingestArchive({ token, url, subscriptionTopic = null }) { |
| return request('/api/archive/ingest', { |
| token, |
| method: 'POST', |
| body: { |
| url, |
| subscription_topic: subscriptionTopic, |
| }, |
| }); |
| } |
|
|
| export function listArchive({ token, reviewState = null, subscriptionTopic = null, limit = 20, cursor = null } = {}) { |
| return request('/api/archive/list', { |
| token, |
| query: { |
| review_state: reviewState, |
| subscription_topic: subscriptionTopic, |
| limit, |
| cursor, |
| }, |
| }); |
| } |
|
|
| export function getArchiveByKey({ token, videoKey }) { |
| return request('/api/archive/get', { |
| token, |
| query: { |
| video_key: videoKey, |
| }, |
| }); |
| } |
|
|
| export function normalizeArchive({ token, videoKey }) { |
| return request('/api/archive/normalize', { |
| token, |
| method: 'POST', |
| body: { |
| video_key: videoKey, |
| }, |
| }); |
| } |
|
|
| export function segmentArchive({ token, videoKey }) { |
| return request('/api/archive/segments', { |
| token, |
| method: 'POST', |
| body: { |
| video_key: videoKey, |
| }, |
| }); |
| } |
|
|
| export function reviewArchive({ token, videoKey, reviewState, note = '' }) { |
| return request('/api/archive/review', { |
| token, |
| method: 'POST', |
| body: { |
| video_key: videoKey, |
| review_state: reviewState, |
| note, |
| }, |
| }); |
| } |
|
|
| export function noteArchive({ token, videoKey, noteType = 'quick-note', title = '', body = '', publicationSeed = false }) { |
| return request('/api/archive/note', { |
| token, |
| method: 'POST', |
| body: { |
| video_key: videoKey, |
| note_type: noteType, |
| title, |
| body, |
| publication_seed: Boolean(publicationSeed), |
| }, |
| }); |
| } |
|
|
| export function compileArchive({ token, videoKeys = [], segmentIds = [], titleWorking = '', editorialAngle = '', targetChannel = 'web' }) { |
| return request('/api/archive/compile', { |
| token, |
| method: 'POST', |
| body: { |
| video_keys: videoKeys, |
| segment_ids: segmentIds, |
| title_working: titleWorking, |
| editorial_angle: editorialAngle, |
| target_channel: targetChannel, |
| type: 'commentary', |
| }, |
| }); |
| } |
|
|