From 66d8f2de261ee8231ae088f3dbdd3d6b6ad6ff20 Mon Sep 17 00:00:00 2001 From: DJ Mountney Date: Fri, 29 Dec 2023 13:32:46 -0800 Subject: [PATCH 1/2] Add proper types to runHandler - Args and return values from runHandler should now work within loot core - Updated some of the handler types to be more accurate --- packages/loot-core/src/mocks/budget.ts | 15 +++++------ .../platform/server/connection/index.web.ts | 6 +---- packages/loot-core/src/server/main.ts | 18 ++++++------- packages/loot-core/src/server/mutators.ts | 10 ++++---- .../src/server/schedules/types/handlers.ts | 2 +- .../loot-core/src/types/api-handlers.d.ts | 25 +++++++++++++------ .../loot-core/src/types/server-handlers.d.ts | 18 ++++++------- 7 files changed, 50 insertions(+), 44 deletions(-) diff --git a/packages/loot-core/src/mocks/budget.ts b/packages/loot-core/src/mocks/budget.ts index e4d9506030f..4aa912cfe51 100644 --- a/packages/loot-core/src/mocks/budget.ts +++ b/packages/loot-core/src/mocks/budget.ts @@ -9,6 +9,7 @@ import * as sheet from '../server/sheet'; import { batchMessages, setSyncingMode } from '../server/sync'; import * as monthUtils from '../shared/months'; import { q } from '../shared/query'; +import type { Handlers } from '../types/handlers'; import type { CategoryGroupEntity, PayeeEntity, @@ -566,7 +567,7 @@ async function createBudget(accounts, payees, groups) { await sheet.waitOnSpreadsheet(); } -export async function createTestBudget(handlers) { +export async function createTestBudget(handlers: Handlers) { setSyncingMode('import'); await db.execQuery('PRAGMA journal_mode = OFF'); @@ -577,15 +578,15 @@ export async function createTestBudget(handlers) { await db.runQuery('DELETE FROM categories;'); await db.runQuery('DELETE FROM category_groups'); - const accounts: { name: string; offBudget?: 1; id?: string }[] = [ + const accounts: { name: string; offBudget?: boolean; id?: string }[] = [ { name: 'Bank of America' }, { name: 'Ally Savings' }, { name: 'Capital One Checking' }, { name: 'HSBC' }, - { name: 'Vanguard 401k', offBudget: 1 }, - { name: 'Mortgage', offBudget: 1 }, - { name: 'House Asset', offBudget: 1 }, - { name: 'Roth IRA', offBudget: 1 }, + { name: 'Vanguard 401k', offBudget: true }, + { name: 'Mortgage', offBudget: true }, + { name: 'House Asset', offBudget: true }, + { name: 'Roth IRA', offBudget: true }, ]; await runMutator(() => batchMessages(async () => { @@ -657,7 +658,7 @@ export async function createTestBudget(handlers) { for (const group of categoryGroups) { group.id = await handlers['category-group-create']({ name: group.name, - isIncome: group.is_income ? 1 : 0, + isIncome: group.is_income, }); for (const category of group.categories) { diff --git a/packages/loot-core/src/platform/server/connection/index.web.ts b/packages/loot-core/src/platform/server/connection/index.web.ts index 8b8bcd5b488..c1e3af987fd 100644 --- a/packages/loot-core/src/platform/server/connection/index.web.ts +++ b/packages/loot-core/src/platform/server/connection/index.web.ts @@ -47,14 +47,10 @@ export const init: T.Init = function (serverChn, handlers) { if (handlers[name]) { runHandler(handlers[name], args, { undoTag, name }).then( result => { - if (catchErrors) { - result = { data: result, error: null }; - } - serverChannel.postMessage({ type: 'reply', id, - result, + result: catchErrors ? { data: result, error: null } : result, mutated: isMutating(handlers[name]), undoTag, }); diff --git a/packages/loot-core/src/server/main.ts b/packages/loot-core/src/server/main.ts index 8d8da4116ec..417e417260a 100644 --- a/packages/loot-core/src/server/main.ts +++ b/packages/loot-core/src/server/main.ts @@ -1673,14 +1673,11 @@ handlers['set-server-url'] = async function ({ url, validate = true }) { if (validate) { // Validate the server is running - const { error } = await runHandler( - handlers['subscribe-needs-bootstrap'], - { - url, - }, - ); - if (error) { - return { error }; + const result = await runHandler(handlers['subscribe-needs-bootstrap'], { + url, + }); + if ('error' in result) { + return { error: result.error }; } } } @@ -2296,7 +2293,10 @@ export async function init(config) { export const lib = { getDataDir: fs.getDataDir, sendMessage: (msg, args) => connection.send(msg, args), - send: async (name, args) => { + send: async ( + name: K, + args?: Parameters[0], + ): Promise>> => { const res = await runHandler(app.handlers[name], args); return res; }, diff --git a/packages/loot-core/src/server/mutators.ts b/packages/loot-core/src/server/mutators.ts index 3988e5c58f8..d7b60ea1e1c 100644 --- a/packages/loot-core/src/server/mutators.ts +++ b/packages/loot-core/src/server/mutators.ts @@ -1,6 +1,6 @@ import { captureException, captureBreadcrumb } from '../platform/exceptions'; import { sequential } from '../shared/async'; -import { type HandlerFunctions } from '../types/handlers'; +import { type HandlerFunctions, type Handlers } from '../types/handlers'; const runningMethods = new Set(); @@ -37,11 +37,11 @@ function wait(time) { return new Promise(resolve => setTimeout(resolve, time)); } -export async function runHandler( - handler, - args?, +export async function runHandler( + handler: T, + args?: Parameters[0], { undoTag, name }: { undoTag?; name? } = {}, -) { +): Promise> { // For debug reasons, track the latest handlers that have been // called _latestHandlerNames.push(name); diff --git a/packages/loot-core/src/server/schedules/types/handlers.ts b/packages/loot-core/src/server/schedules/types/handlers.ts index c15fb1479e8..293fcc24007 100644 --- a/packages/loot-core/src/server/schedules/types/handlers.ts +++ b/packages/loot-core/src/server/schedules/types/handlers.ts @@ -5,7 +5,7 @@ export interface SchedulesHandlers { schedule: { id?: string; name?: string; - post_transaction?: boolean; + posts_transaction?: boolean; }; conditions: unknown[]; }) => Promise; diff --git a/packages/loot-core/src/types/api-handlers.d.ts b/packages/loot-core/src/types/api-handlers.d.ts index 71bc1530666..c4e8c2b11b8 100644 --- a/packages/loot-core/src/types/api-handlers.d.ts +++ b/packages/loot-core/src/types/api-handlers.d.ts @@ -59,7 +59,12 @@ export interface ApiHandlers { transactions; }) => Promise; - 'api/transactions-add': (arg: { accountId; transactions }) => Promise<'ok'>; + 'api/transactions-add': (arg: { + accountId; + transactions; + runTransfers?: boolean; + learnCategories?: boolean; + }) => Promise<'ok'>; 'api/transactions-get': (arg: { accountId; @@ -74,9 +79,11 @@ export interface ApiHandlers { 'api/transaction-delete': (arg: { id }) => Promise; - 'api/accounts-get': () => Promise; + 'api/sync': () => Promise; + + 'api/accounts-get': () => Promise; - 'api/account-create': (arg: { account; initialBalance }) => Promise; + 'api/account-create': (arg: { account; initialBalance? }) => Promise; 'api/account-update': (arg: { id; fields }) => Promise; @@ -90,9 +97,11 @@ export interface ApiHandlers { 'api/account-delete': (arg: { id }) => Promise; - 'api/categories-get': (arg: { grouped }) => Promise; + 'api/categories-get': (arg: { + grouped; + }) => Promise | Array>; - 'api/category-group-create': (arg: { group }) => Promise; + 'api/category-group-create': (arg: { group }) => Promise; 'api/category-group-update': (arg: { id; fields }) => Promise; @@ -101,15 +110,15 @@ export interface ApiHandlers { transferCategoryId; }) => Promise; - 'api/category-create': (arg: { category }) => Promise; + 'api/category-create': (arg: { category }) => Promise; 'api/category-update': (arg: { id; fields }) => Promise; 'api/category-delete': (arg: { id; transferCategoryId }) => Promise; - 'api/payees-get': () => Promise; + 'api/payees-get': () => Promise; - 'api/payee-create': (arg: { payee }) => Promise; + 'api/payee-create': (arg: { payee }) => Promise; 'api/payee-update': (arg: { id; fields }) => Promise; diff --git a/packages/loot-core/src/types/server-handlers.d.ts b/packages/loot-core/src/types/server-handlers.d.ts index 5a6487b21ab..f5022b44440 100644 --- a/packages/loot-core/src/types/server-handlers.d.ts +++ b/packages/loot-core/src/types/server-handlers.d.ts @@ -78,20 +78,20 @@ export interface ServerHandlers { 'category-create': (arg: { name; groupId; - isIncome; - hidden: boolean; - }) => Promise; + isIncome?; + hidden?: boolean; + }) => Promise; 'category-update': (category) => Promise; 'category-move': (arg: { id; groupId; targetId }) => Promise; - 'category-delete': (arg: { id; transferId }) => Promise<{ error?: string }>; + 'category-delete': (arg: { id; transferId? }) => Promise<{ error?: string }>; 'category-group-create': (arg: { name; isIncome?: boolean; - }) => Promise; + }) => Promise; 'category-group-update': (group) => Promise; @@ -101,7 +101,7 @@ export interface ServerHandlers { 'must-category-transfer': (arg: { id }) => Promise; - 'payee-create': (arg: { name }) => Promise; + 'payee-create': (arg: { name }) => Promise; 'payees-get': () => Promise; @@ -165,7 +165,7 @@ export interface ServerHandlers { institution; publicToken; accountIds; - offbudgetIds; + offbudgetIds?; }) => Promise; 'gocardless-accounts-connect': (arg: { @@ -177,7 +177,7 @@ export interface ServerHandlers { 'account-create': (arg: { name: string; - balance: number; + balance?: number; offBudget?: boolean; closed?: 0 | 1; }) => Promise; @@ -197,7 +197,7 @@ export interface ServerHandlers { 'poll-web-token-stop': () => Promise<'ok'>; - 'accounts-sync': (arg: { id }) => Promise<{ + 'accounts-sync': (arg: { id? }) => Promise<{ errors: unknown; newTransactions: unknown; matchedTransactions: unknown; From e6380967a4ef07c4508fa7660e0fe9abac9c84df Mon Sep 17 00:00:00 2001 From: DJ Mountney Date: Fri, 29 Dec 2023 15:22:58 -0800 Subject: [PATCH 2/2] Add release note --- upcoming-release-notes/2136.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 upcoming-release-notes/2136.md diff --git a/upcoming-release-notes/2136.md b/upcoming-release-notes/2136.md new file mode 100644 index 00000000000..90a5e66c3b6 --- /dev/null +++ b/upcoming-release-notes/2136.md @@ -0,0 +1,6 @@ +--- +category: Maintenance +authors: [twk3] +--- + +TypeScript: Add proper types to runHandler