From 29aa2cc936810d4630ec0e091c1927b05177eea9 Mon Sep 17 00:00:00 2001 From: Andrew Kingston Date: Thu, 5 Dec 2024 15:10:16 +0000 Subject: [PATCH] Update backup endpoints and fix some errors --- .../settings/backups/index.svelte | 37 ++++-------- packages/builder/src/stores/portal/backups.js | 24 ++------ .../builder/src/stores/portal/backups.test.js | 60 +++++-------------- packages/frontend-core/src/api/analytics.ts | 1 + packages/frontend-core/src/api/backups.ts | 28 +++------ packages/frontend-core/src/api/index.ts | 4 +- 6 files changed, 42 insertions(+), 112 deletions(-) diff --git a/packages/builder/src/pages/builder/app/[application]/settings/backups/index.svelte b/packages/builder/src/pages/builder/app/[application]/settings/backups/index.svelte index e8a67b2ae1..ecdd3ee419 100644 --- a/packages/builder/src/pages/builder/app/[application]/settings/backups/index.svelte +++ b/packages/builder/src/pages/builder/app/[application]/settings/backups/index.svelte @@ -99,21 +99,18 @@ } async function fetchBackups(filters, page, dateRange = []) { - const body = { - appId: $appStore.appId, + const opts = { ...filters, page, } - const [startDate, endDate] = dateRange if (startDate) { - body.startDate = startDate + opts.startDate = startDate } if (endDate) { - body.endDate = endDate + opts.endDate = endDate } - - const response = await backups.searchBackups(body) + const response = await backups.searchBackups($appStore.appId, opts) pageInfo.fetched(response.hasNextPage, response.nextPage) // flatten so we have an easier structure to use for the table schema @@ -123,9 +120,7 @@ async function createManualBackup() { try { loading = true - let response = await backups.createManualBackup({ - appId: $appStore.appId, - }) + let response = await backups.createManualBackup($appStore.appId) await fetchBackups(filterOpt, page) notifications.success(response.message) } catch (err) { @@ -149,24 +144,14 @@ async function handleButtonClick({ detail }) { if (detail.type === "backupDelete") { - await backups.deleteBackup({ - appId: $appStore.appId, - backupId: detail.backupId, - }) + await backups.deleteBackup($appStore.appId, detail.backupId) await fetchBackups(filterOpt, page) } else if (detail.type === "backupRestore") { - await backups.restoreBackup({ - appId: $appStore.appId, - backupId: detail.backupId, - name: detail.restoreBackupName, - }) - await fetchBackups(filterOpt, page) - } else if (detail.type === "backupUpdate") { - await backups.updateBackup({ - appId: $appStore.appId, - backupId: detail.backupId, - name: detail.name, - }) + await backups.restoreBackup( + $appStore.appId, + detail.backupId, + detail.restoreBackupName + ) await fetchBackups(filterOpt, page) } } diff --git a/packages/builder/src/stores/portal/backups.js b/packages/builder/src/stores/portal/backups.js index d367ec73e8..e8378afc0f 100644 --- a/packages/builder/src/stores/portal/backups.js +++ b/packages/builder/src/stores/portal/backups.js @@ -11,40 +11,28 @@ export function createBackupsStore() { }) } - async function searchBackups({ - appId, - trigger, - type, - page, - startDate, - endDate, - }) { - return API.searchBackups(appId, { trigger, type, page, startDate, endDate }) + async function searchBackups(appId, opts) { + return API.searchBackups(appId, opts) } - async function restoreBackup({ appId, backupId, name }) { - return API.restoreBackup({ appId, backupId, name }) + async function restoreBackup(appId, backupId, name) { + return API.restoreBackup(appId, backupId, name) } - async function deleteBackup({ appId, backupId }) { - return API.deleteBackup({ appId, backupId }) + async function deleteBackup(appId, backupId) { + return API.deleteBackup(appId, backupId) } async function createManualBackup(appId) { return API.createManualBackup(appId) } - async function updateBackup({ appId, backupId, name }) { - return API.updateBackup({ appId, backupId, name }) - } - return { createManualBackup, searchBackups, selectBackup, deleteBackup, restoreBackup, - updateBackup, subscribe: store.subscribe, } } diff --git a/packages/builder/src/stores/portal/backups.test.js b/packages/builder/src/stores/portal/backups.test.js index 18feb01938..16c487e6e7 100644 --- a/packages/builder/src/stores/portal/backups.test.js +++ b/packages/builder/src/stores/portal/backups.test.js @@ -20,7 +20,6 @@ vi.mock("api", () => { restoreBackup: vi.fn(() => "restoreBackupReturn"), deleteBackup: vi.fn(() => "deleteBackupReturn"), createManualBackup: vi.fn(() => "createManualBackupReturn"), - updateBackup: vi.fn(() => "updateBackupReturn"), }, } }) @@ -61,8 +60,7 @@ describe("backups store", () => { ctx.page = "page" ctx.startDate = "startDate" ctx.endDate = "endDate" - ctx.value = await ctx.returnedStore.searchBackups({ - appId: ctx.appId, + ctx.value = await ctx.returnedStore.searchBackups(ctx.appId, { trigger: ctx.trigger, type: ctx.type, page: ctx.page, @@ -73,8 +71,7 @@ describe("backups store", () => { it("calls and returns the API searchBackups method", ctx => { expect(API.searchBackups).toHaveBeenCalledTimes(1) - expect(API.searchBackups).toHaveBeenCalledWith({ - appId: ctx.appId, + expect(API.searchBackups).toHaveBeenCalledWith(ctx.appId, { trigger: ctx.trigger, type: ctx.type, page: ctx.page, @@ -103,18 +100,12 @@ describe("backups store", () => { beforeEach(async ctx => { ctx.appId = "appId" ctx.backupId = "backupId" - ctx.value = await ctx.returnedStore.deleteBackup({ - appId: ctx.appId, - backupId: ctx.backupId, - }) + ctx.value = await ctx.returnedStore.deleteBackup(ctx.appId, ctx.backupId) }) it("calls and returns the API deleteBackup method", ctx => { expect(API.deleteBackup).toHaveBeenCalledTimes(1) - expect(API.deleteBackup).toHaveBeenCalledWith({ - appId: ctx.appId, - backupId: ctx.backupId, - }) + expect(API.deleteBackup).toHaveBeenCalledWith(ctx.appId, ctx.backupId) expect(ctx.value).toBe("deleteBackupReturn") }) }) @@ -124,47 +115,24 @@ describe("backups store", () => { ctx.appId = "appId" ctx.backupId = "backupId" ctx.$name = "name" // `name` is used by some sort of internal ctx thing and is readonly - ctx.value = await ctx.returnedStore.restoreBackup({ - appId: ctx.appId, - backupId: ctx.backupId, - name: ctx.$name, - }) + ctx.value = await ctx.returnedStore.restoreBackup( + ctx.appId, + ctx.backupId, + ctx.$name + ) }) it("calls and returns the API restoreBackup method", ctx => { expect(API.restoreBackup).toHaveBeenCalledTimes(1) - expect(API.restoreBackup).toHaveBeenCalledWith({ - appId: ctx.appId, - backupId: ctx.backupId, - name: ctx.$name, - }) + expect(API.restoreBackup).toHaveBeenCalledWith( + ctx.appId, + ctx.backupId, + ctx.$name + ) expect(ctx.value).toBe("restoreBackupReturn") }) }) - describe("updateBackup", () => { - beforeEach(async ctx => { - ctx.appId = "appId" - ctx.backupId = "backupId" - ctx.$name = "name" // `name` is used by some sort of internal ctx thing and is readonly - ctx.value = await ctx.returnedStore.updateBackup({ - appId: ctx.appId, - backupId: ctx.backupId, - name: ctx.$name, - }) - }) - - it("calls and returns the API updateBackup method", ctx => { - expect(API.updateBackup).toHaveBeenCalledTimes(1) - expect(API.updateBackup).toHaveBeenCalledWith({ - appId: ctx.appId, - backupId: ctx.backupId, - name: ctx.$name, - }) - expect(ctx.value).toBe("updateBackupReturn") - }) - }) - describe("subscribe", () => { it("calls and returns the API updateBackup method", ctx => { expect(ctx.returnedStore.subscribe).toBe(ctx.writableReturn.subscribe) diff --git a/packages/frontend-core/src/api/analytics.ts b/packages/frontend-core/src/api/analytics.ts index 0920a65654..82a41ca98f 100644 --- a/packages/frontend-core/src/api/analytics.ts +++ b/packages/frontend-core/src/api/analytics.ts @@ -30,6 +30,7 @@ export const buildAnalyticsEndpoints = ( ...request, timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, }, + parseResponse: () => null, }) }, }) diff --git a/packages/frontend-core/src/api/backups.ts b/packages/frontend-core/src/api/backups.ts index 7ec9e72322..090ff97fc6 100644 --- a/packages/frontend-core/src/api/backups.ts +++ b/packages/frontend-core/src/api/backups.ts @@ -1,26 +1,20 @@ import { - CreateAppBackupRequest, CreateAppBackupResponse, ImportAppBackupResponse, SearchAppBackupsRequest, - UpdateAppBackupRequest, } from "@budibase/types" import { BaseAPIClient } from "./types" export interface BackupEndpoints { - createManualBackup: ( - appId: string, - name?: string - ) => Promise + createManualBackup: (appId: string) => Promise restoreBackup: ( appId: string, backupId: string, - name: string + name?: string ) => Promise // Missing request or response types searchBackups: (appId: string, opts: SearchAppBackupsRequest) => Promise - updateBackup: (appId: string, backupId: string, name: string) => Promise deleteBackup: ( appId: string, backupId: string @@ -28,14 +22,9 @@ export interface BackupEndpoints { } export const buildBackupEndpoints = (API: BaseAPIClient): BackupEndpoints => ({ - createManualBackup: async (appId, name) => { - return await API.post({ + createManualBackup: async appId => { + return await API.post({ url: `/api/apps/${appId}/backups`, - body: name - ? { - name, - } - : undefined, }) }, searchBackups: async (appId, opts) => { @@ -49,15 +38,12 @@ export const buildBackupEndpoints = (API: BaseAPIClient): BackupEndpoints => ({ url: `/api/apps/${appId}/backups/${backupId}`, }) }, - updateBackup: async (appId, backupId, name) => { - return await API.patch({ - url: `/api/apps/${appId}/backups/${backupId}`, - body: { name }, - }) - }, restoreBackup: async (appId, backupId, name) => { return await API.post({ url: `/api/apps/${appId}/backups/${backupId}/import`, + // Name is a legacy thing, but unsure if it is needed for restoring. + // Leaving this in just in case, but not type casting the body here + // as we won't normally have it, but it's required in the type. body: { name }, }) }, diff --git a/packages/frontend-core/src/api/index.ts b/packages/frontend-core/src/api/index.ts index 23d8576e5b..be36f3c485 100644 --- a/packages/frontend-core/src/api/index.ts +++ b/packages/frontend-core/src/api/index.ts @@ -160,8 +160,10 @@ export const createAPIClient = (config: APIClientConfig = {}): APIClient => { try { if (parseResponse) { return await parseResponse(response) - } else { + } else if (response.status !== 204) { return (await response.json()) as ResponseT + } else { + return undefined } } catch (error) { delete cache[url]