From ab4639f48f42d16335cf11c1d92be5fd0c680548 Mon Sep 17 00:00:00 2001 From: Robert Dyer <rdyer@unl.edu> Date: Thu, 11 Jul 2024 03:27:32 -0500 Subject: [PATCH] API: add getBudgets() methods to list all budgets in the local cache or remote server. (#2928) --- packages/api/methods.test.ts | 13 +++++++ packages/api/methods.ts | 4 ++ packages/loot-core/src/server/api-models.ts | 38 +++++++++++++++++++ packages/loot-core/src/server/api.ts | 11 ++++++ .../loot-core/src/types/api-handlers.d.ts | 3 ++ upcoming-release-notes/2928.md | 6 +++ 6 files changed, 75 insertions(+) create mode 100644 upcoming-release-notes/2928.md diff --git a/packages/api/methods.test.ts b/packages/api/methods.test.ts index 9a9e2fb9e..8e0a9b586 100644 --- a/packages/api/methods.test.ts +++ b/packages/api/methods.test.ts @@ -58,6 +58,19 @@ describe('API CRUD operations', () => { await api.loadBudget(budgetName); }); + // api: getBudgets + test('getBudgets', async () => { + const budgets = await api.getBudgets(); + expect(budgets).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + id: 'test-budget', + name: 'Default Test Db', + }), + ]), + ); + }); + // apis: getCategoryGroups, createCategoryGroup, updateCategoryGroup, deleteCategoryGroup test('CategoryGroups: successfully update category groups', async () => { const month = '2023-10'; diff --git a/packages/api/methods.ts b/packages/api/methods.ts index cc25bfe3e..124d5d666 100644 --- a/packages/api/methods.ts +++ b/packages/api/methods.ts @@ -31,6 +31,10 @@ export async function downloadBudget(syncId, { password }: { password? } = {}) { return send('api/download-budget', { syncId, password }); } +export async function getBudgets() { + return send('api/get-budgets'); +} + export async function sync() { return send('api/sync'); } diff --git a/packages/loot-core/src/server/api-models.ts b/packages/loot-core/src/server/api-models.ts index 69be7a40a..ebd68e8d4 100644 --- a/packages/loot-core/src/server/api-models.ts +++ b/packages/loot-core/src/server/api-models.ts @@ -1,3 +1,4 @@ +import { Budget } from '../types/budget'; import type { AccountEntity, CategoryEntity, @@ -5,6 +6,7 @@ import type { PayeeEntity, } from '../types/models'; +import { RemoteFile } from './cloud-storage'; import * as models from './models'; export type APIAccountEntity = Pick<AccountEntity, 'id' | 'name'> & { @@ -114,3 +116,39 @@ export const payeeModel = { return payee as PayeeEntity; }, }; + +export type APIFileEntity = Omit<RemoteFile, 'deleted' | 'fileId'> & { + id?: string; + cloudFileId: string; + state?: 'remote'; +}; + +export const remoteFileModel = { + toExternal(file: RemoteFile): APIFileEntity | null { + if (file.deleted) { + return null; + } + return { + cloudFileId: file.fileId, + state: 'remote', + groupId: file.groupId, + name: file.name, + encryptKeyId: file.encryptKeyId, + hasKey: file.hasKey, + }; + }, + + fromExternal(file: APIFileEntity) { + return { deleted: false, fileId: file.cloudFileId, ...file } as RemoteFile; + }, +}; + +export const budgetModel = { + toExternal(file: Budget): APIFileEntity { + return file as APIFileEntity; + }, + + fromExternal(file: APIFileEntity) { + return file as Budget; + }, +}; diff --git a/packages/loot-core/src/server/api.ts b/packages/loot-core/src/server/api.ts index fe670152a..f2bbe5f42 100644 --- a/packages/loot-core/src/server/api.ts +++ b/packages/loot-core/src/server/api.ts @@ -22,9 +22,11 @@ import { ServerHandlers } from '../types/server-handlers'; import { addTransactions } from './accounts/sync'; import { accountModel, + budgetModel, categoryModel, categoryGroupModel, payeeModel, + remoteFileModel, } from './api-models'; import { runQuery as aqlQuery } from './aql'; import * as cloudStorage from './cloud-storage'; @@ -226,6 +228,15 @@ handlers['api/download-budget'] = async function ({ syncId, password }) { await handlers['load-budget']({ id: result.id }); }; +handlers['api/get-budgets'] = async function () { + const budgets = await handlers['get-budgets'](); + const files = (await handlers['get-remote-files']()) || []; + return [ + ...budgets.map(file => budgetModel.toExternal(file)), + ...files.map(file => remoteFileModel.toExternal(file)).filter(file => file), + ]; +}; + handlers['api/sync'] = async function () { const { id } = prefs.getPrefs(); const result = await handlers['sync-budget'](); diff --git a/packages/loot-core/src/types/api-handlers.d.ts b/packages/loot-core/src/types/api-handlers.d.ts index edd89582d..d8f23ae5b 100644 --- a/packages/loot-core/src/types/api-handlers.d.ts +++ b/packages/loot-core/src/types/api-handlers.d.ts @@ -3,6 +3,7 @@ import type { APIAccountEntity, APICategoryEntity, APICategoryGroupEntity, + APIFileEntity, APIPayeeEntity, } from '../server/api-models'; @@ -23,6 +24,8 @@ export interface ApiHandlers { password?: string; }) => Promise<void>; + 'api/get-budgets': () => Promise<APIFileEntity[]>; + 'api/start-import': (arg: { budgetName: string }) => Promise<void>; 'api/finish-import': () => Promise<void>; diff --git a/upcoming-release-notes/2928.md b/upcoming-release-notes/2928.md new file mode 100644 index 000000000..3c3490058 --- /dev/null +++ b/upcoming-release-notes/2928.md @@ -0,0 +1,6 @@ +--- +category: Enhancements +authors: [psybers] +--- + +API: add getBudgets() method to list all local/remote budgets. -- GitLab