This commit is contained in:
Josh 2026-01-09 00:16:46 +02:00
commit d69342b2e9
160 changed files with 28681 additions and 0 deletions

77
studio/src/api.ts Normal file
View file

@ -0,0 +1,77 @@
import type { Post, Settings, InteractionConfig, Asset, APIKey, AnalyticsSummary } from './types'
const BASE = '/api/studio'
async function request<T>(path: string, options?: RequestInit): Promise<T> {
const res = await fetch(`${BASE}${path}`, {
...options,
headers: {
'Content-Type': 'application/json',
...options?.headers,
},
})
if (!res.ok) {
const error = await res.json().catch(() => ({ error: res.statusText }))
throw new Error(error.error || 'Request failed')
}
if (res.status === 204) return undefined as T
return res.json()
}
export const api = {
posts: {
list: () => request<Post[]>('/posts'),
get: (slug: string) => request<Post>(`/posts/${slug}`),
create: (data: Partial<Post>) => request<Post>('/posts', {
method: 'POST',
body: JSON.stringify(data),
}),
update: (slug: string, data: Partial<Post>) => request<Post>(`/posts/${slug}`, {
method: 'PUT',
body: JSON.stringify(data),
}),
delete: (slug: string) => request<void>(`/posts/${slug}`, { method: 'DELETE' }),
},
settings: {
get: () => request<Settings>('/settings'),
update: (data: Settings) => request<{ success: boolean }>('/settings', {
method: 'PUT',
body: JSON.stringify(data),
}),
},
interactions: {
get: () => request<InteractionConfig>('/interaction-config'),
update: (data: Partial<InteractionConfig>) => request<InteractionConfig>('/interaction-config', {
method: 'PUT',
body: JSON.stringify(data),
}),
},
assets: {
list: () => request<Asset[]>('/assets'),
upload: async (file: File): Promise<Asset> => {
const form = new FormData()
form.append('file', file)
const res = await fetch(`${BASE}/assets`, { method: 'POST', body: form })
if (!res.ok) throw new Error('Upload failed')
return res.json()
},
delete: (id: string) => request<void>(`/assets/${id}`, { method: 'DELETE' }),
},
apiKeys: {
list: () => request<APIKey[]>('/api-keys'),
create: (name: string) => request<APIKey>('/api-keys', {
method: 'POST',
body: JSON.stringify({ name }),
}),
delete: (key: string) => request<void>(`/api-keys/${key}`, { method: 'DELETE' }),
},
analytics: {
get: (days = 30) => request<AnalyticsSummary>(`/analytics?days=${days}`),
getPost: (slug: string, days = 30) => request<AnalyticsSummary>(`/analytics/posts/${slug}?days=${days}`),
},
}