import type { Project } from '../model/Project'; import { apiRequest } from './http'; import { type LoadedProject, type ProjectStore, type ProjectSummary, StaleRevisionError, } from './ProjectStore'; import { deserializeProject, serializeProject } from './serialize'; export class HttpProjectStore implements ProjectStore { constructor(private readonly endpoint: string) {} async list(): Promise { return this.request('GET', 'projects'); } async load(id: string): Promise { const body = await this.request<{ revision: number; project: unknown }>( 'GET', `projects/${encodeURIComponent(id)}`, ); return { project: deserializeProject(body.project, id), revision: body.revision }; } async save(project: Project, revision: number): Promise { const body = await this.request<{ revision: number }>( 'PUT', `projects/${encodeURIComponent(project.id)}`, { revision, project: serializeProject(project), }, ); return body.revision; } async create(name: string): Promise { const body = await this.request<{ revision: number; project: unknown }>('POST', 'projects', { name }); const project = deserializeProject(body.project); return { project, revision: body.revision }; } async delete(id: string): Promise { await this.request('DELETE', `projects/${encodeURIComponent(id)}`); } private async request(method: string, route: string, payload?: unknown): Promise { return apiRequest( this.endpoint, method, route, { headers: payload !== undefined ? { 'Content-Type': 'application/json' } : {}, body: payload !== undefined ? JSON.stringify(payload) : undefined, }, (status, data) => status === 409 ? new StaleRevisionError((data as { revision?: number } | null)?.revision ?? -1) : undefined, ); } }