feat: implement drives, backend and frontend

This commit is contained in:
Shivering Ocelot committed 2026-09-22 10:58:08 -05:00
1 parent 6ad0a461e4
commit 3283b77ab9
12 files changed
+781 -93

No files matched your search

+50
View File
@@ -137,6 +137,23 @@ export async function newToken () {
// --- Communication ---
export async function webFetch (path, options = {}) {
const tk = loginToken || await loginTokenDeferred.promise;
const response = await fetch(`${backendUrl}${path}`, {
...options,
headers: {
Authorization: `Bearer ${tk}`,
...options.headers,
},
});
if (!response.ok) {
const errorText = await response.text();
throw new Error(`Response Error: ${response.status}\n${errorText}`);
}
// TODO: Check content-type before parsing
return response.json();
}
export function sendAction(action, body = {}, callback = null) {
if (socket?.readyState !== WebSocket.OPEN) {
return Promise.reject(new Error("WebSocket is not open. Cannot send action."));
@@ -358,6 +375,39 @@ export function invalidateCache({ chats=false, agents=false } = {}) {
}
// --- Drive Storage (REST) ---
// Drive endpoints are plain HTTP routes instead of WebSocket actions,
// so they authenticate with the bearer token in the Authorization header.
export function getDrives () {
return webFetch('/files');
}
export function getDriveFiles (driveName) {
return webFetch(`/files/${driveName}`);
}
export function uploadDriveFile (driveName, file) {
const body = new FormData();
body.append('file', file, file.name);
return webFetch(`/files/${driveName}`, {
method: 'POST',
body,
});
}
// Anchor downloads can't set headers, so the token travels as a query parameter
export function driveFileUrl (driveName, filename) {
return `${backendUrl}/files/${driveName}/${filename}?token=${loginToken}`;
}
export function deleteDriveFile (driveName, filename) {
const body = new FormData();
return webFetch(`/files/${driveName}/${filename}`, {
method: 'DELETE',
});
}
// --- Connection ---