mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
136 lines
3.9 KiB
TypeScript
136 lines
3.9 KiB
TypeScript
function readIdArray(json: unknown, resourceName: string): Array<{ id: string }> {
|
|
if (!json || typeof json !== "object" || !("data" in json)) {
|
|
throw new Error(`Invalid ${resourceName} response: missing data array`);
|
|
}
|
|
|
|
const data = (json as { data?: unknown }).data;
|
|
if (!Array.isArray(data)) {
|
|
throw new Error(`Invalid ${resourceName} response: data is not an array`);
|
|
}
|
|
|
|
for (const item of data) {
|
|
if (!item || typeof item !== "object" || typeof (item as { id?: unknown }).id !== "string") {
|
|
throw new Error(
|
|
`Invalid ${resourceName} response: each item must include a string id`,
|
|
);
|
|
}
|
|
}
|
|
|
|
return data as Array<{ id: string }>;
|
|
}
|
|
|
|
function readBackupDetail(json: unknown) {
|
|
if (!json || typeof json !== "object" || !("data" in json)) {
|
|
throw new Error("Invalid backup detail response: missing data object");
|
|
}
|
|
|
|
const data = (json as { data?: unknown }).data;
|
|
if (!data || typeof data !== "object") {
|
|
throw new Error("Invalid backup detail response: data is not an object");
|
|
}
|
|
|
|
const id = (data as { id?: unknown }).id;
|
|
const storages = (data as { storages?: unknown }).storages;
|
|
|
|
if (typeof id !== "string") {
|
|
throw new Error("Invalid backup detail response: data.id must be a string");
|
|
}
|
|
|
|
if (!Array.isArray(storages)) {
|
|
throw new Error(
|
|
"Invalid backup detail response: data.storages is not an array",
|
|
);
|
|
}
|
|
|
|
for (const item of storages) {
|
|
if (
|
|
!item ||
|
|
typeof item !== "object" ||
|
|
typeof (item as { id?: unknown }).id !== "string" ||
|
|
typeof (item as { status?: unknown }).status !== "string"
|
|
) {
|
|
throw new Error(
|
|
"Invalid backup detail response: each storage must include string id and status",
|
|
);
|
|
}
|
|
}
|
|
|
|
return {
|
|
id,
|
|
storages: storages as Array<{ id: string; status: string }>,
|
|
};
|
|
}
|
|
|
|
export async function discoverAgentId(api: {
|
|
get: (path: string) => Promise<{ response: Response; json: unknown; text: string }>;
|
|
}) {
|
|
const result = await api.get("/api/v1/agents");
|
|
if (!result.response.ok) {
|
|
throw new Error(`Failed to list agents: ${result.response.status} ${result.text}`);
|
|
}
|
|
|
|
const agents = readIdArray(result.json, "agents");
|
|
if (agents.length === 0) {
|
|
throw new Error("No agent could be discovered from /api/v1/agents.");
|
|
}
|
|
|
|
return agents[0].id;
|
|
}
|
|
|
|
export async function discoverDatabaseId(api: {
|
|
get: (path: string) => Promise<{ response: Response; json: unknown; text: string }>;
|
|
}) {
|
|
const result = await api.get("/api/v1/databases");
|
|
if (!result.response.ok) {
|
|
throw new Error(
|
|
`Failed to list databases: ${result.response.status} ${result.text}`,
|
|
);
|
|
}
|
|
|
|
const databases = readIdArray(result.json, "databases");
|
|
if (databases.length === 0) {
|
|
throw new Error("No database could be discovered from /api/v1/databases.");
|
|
}
|
|
|
|
return databases[0].id;
|
|
}
|
|
|
|
export async function discoverBackupContext(
|
|
api: {
|
|
get: (path: string) => Promise<{ response: Response; json: unknown; text: string }>;
|
|
},
|
|
databaseId: string | null,
|
|
) {
|
|
if (!databaseId) {
|
|
throw new Error("Backup discovery requires a database id.");
|
|
}
|
|
|
|
const backups = await api.get(`/api/v1/databases/${databaseId}/backup`);
|
|
if (!backups.response.ok) {
|
|
throw new Error(
|
|
`Failed to list backups: ${backups.response.status} ${backups.text}`,
|
|
);
|
|
}
|
|
|
|
const backupList = readIdArray(backups.json, "backups");
|
|
for (const backup of backupList) {
|
|
const detail = await api.get(`/api/v1/databases/${databaseId}/backup/${backup.id}`);
|
|
if (!detail.response.ok) {
|
|
continue;
|
|
}
|
|
|
|
const payload = readBackupDetail(detail.json);
|
|
const storage = payload.storages.find((item) => item.status === "success");
|
|
if (storage) {
|
|
return {
|
|
backupId: payload.id,
|
|
backupStorageId: storage.id,
|
|
};
|
|
}
|
|
}
|
|
|
|
throw new Error(
|
|
`No successful backup storage could be discovered for database ${databaseId}.`,
|
|
);
|
|
}
|