// Arcadia digital objects API — minimal client covering the upload flow // used by the avatar uploader. The full digital-objects API is much // larger; add endpoints here as we wire more features. import type { ArcadiaClient } from "@crema/arcadia-client" export interface DigitalObject { id: string tenant_id?: string user_id?: string storage_config_id?: string filename?: string original_filename?: string content_type?: string size_bytes?: number key?: string object_key?: string status?: "active" | "archived" | "deleted" inserted_at?: string } interface UploadSession { id: string upload_url: string presigned_url?: string expires_at?: string } interface CreateUploadSessionInput { filename: string content_type: string size_bytes: number storage_config_id?: string metadata?: Record tags?: string[] } /** * Three-step upload: open a session, PUT the bytes to the presigned URL * the session returns, complete the session to land the digital_object. * * Returns the finalized DigitalObject record. */ export async function uploadFile( arcadia: ArcadiaClient, file: File, opts: { storage_config_id?: string; tags?: string[] } = {}, ): Promise { const sessionInput: CreateUploadSessionInput = { filename: file.name, content_type: file.type || "application/octet-stream", size_bytes: file.size, storage_config_id: opts.storage_config_id, tags: opts.tags, } const session = await arcadia.POST<{ data: UploadSession }>( "/api/v1/digital_objects/upload_sessions", { body: { upload_session: sessionInput } }, ) const uploadUrl = session.data.upload_url || session.data.presigned_url if (!uploadUrl) throw new Error("Upload session returned no upload URL") const putRes = await fetch(uploadUrl, { method: "PUT", headers: { "Content-Type": sessionInput.content_type }, body: file, }) if (!putRes.ok) { throw new Error( `Upload to storage failed: ${putRes.status} ${await putRes.text().catch(() => "")}`, ) } const completed = await arcadia.POST<{ data: DigitalObject }>( `/api/v1/digital_objects/upload_sessions/${encodeURIComponent(session.data.id)}/complete`, { body: {} }, ) return completed.data } export async function deleteDigitalObject( arcadia: ArcadiaClient, id: string, ): Promise { await arcadia.DELETE(`/api/v1/digital_objects/${encodeURIComponent(id)}`) }