mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-11 12:43:09 -05:00
Refactor handler invocation in YNAB importers to use the new send function from main-app. This change improves code consistency and readability by standardizing the method of invoking handlers across different modules.
This commit is contained in:
@@ -9,8 +9,7 @@ import { amountToInteger, groupBy, sortByKey } from '../../shared/util';
|
||||
// This is a special usage of the API because this package is embedded
|
||||
// into Actual itself. We call handlers directly to avoid cyclic dependency
|
||||
// between loot-core and @actual-app/api
|
||||
import { app } from '../main-app';
|
||||
import { runHandler } from '../mutators';
|
||||
import { send } from '../main-app';
|
||||
|
||||
import type * as YNAB4 from './ynab4-types';
|
||||
|
||||
@@ -25,7 +24,7 @@ async function importAccounts(
|
||||
return Promise.all(
|
||||
accounts.map(async account => {
|
||||
if (!account.isTombstone) {
|
||||
const id = await runHandler(app.handlers['api/account-create'], {
|
||||
const id = await send('api/account-create', {
|
||||
account: {
|
||||
name: account.accountName,
|
||||
offbudget: account.onBudget ? false : true,
|
||||
@@ -52,7 +51,7 @@ async function importCategories(
|
||||
masterCategory.subCategories &&
|
||||
masterCategory.subCategories.some(cat => !cat.isTombstone)
|
||||
) {
|
||||
const id = await runHandler(app.handlers['api/category-group-create'], {
|
||||
const id = await send('api/category-group-create', {
|
||||
group: {
|
||||
name: masterCategory.name,
|
||||
is_income: false,
|
||||
@@ -60,7 +59,7 @@ async function importCategories(
|
||||
});
|
||||
entityIdMap.set(masterCategory.entityId, id);
|
||||
if (masterCategory.note) {
|
||||
void runHandler(app.handlers['notes-save'], {
|
||||
void send('notes-save', {
|
||||
id,
|
||||
note: masterCategory.note,
|
||||
});
|
||||
@@ -93,7 +92,7 @@ async function importCategories(
|
||||
categoryName = categoryNameParts.join('/').trim();
|
||||
}
|
||||
|
||||
const id = await runHandler(app.handlers['api/category-create'], {
|
||||
const id = await send('api/category-create', {
|
||||
category: {
|
||||
name: categoryName,
|
||||
group_id: entityIdMap.get(category.masterCategoryId),
|
||||
@@ -101,7 +100,7 @@ async function importCategories(
|
||||
});
|
||||
entityIdMap.set(category.entityId, id);
|
||||
if (category.note) {
|
||||
void runHandler(app.handlers['notes-save'], {
|
||||
void send('notes-save', {
|
||||
id,
|
||||
note: category.note,
|
||||
});
|
||||
@@ -120,7 +119,7 @@ async function importPayees(
|
||||
) {
|
||||
for (const payee of data.payees) {
|
||||
if (!payee.isTombstone) {
|
||||
const id = await runHandler(app.handlers['api/payee-create'], {
|
||||
const id = await send('api/payee-create', {
|
||||
payee: {
|
||||
name: payee.name,
|
||||
transfer_acct: entityIdMap.get(payee.targetAccountId) || null,
|
||||
@@ -138,14 +137,14 @@ async function importTransactions(
|
||||
data: YNAB4.YFull,
|
||||
entityIdMap: Map<string, string>,
|
||||
) {
|
||||
const categories = await runHandler(app.handlers['api/categories-get'], {
|
||||
const categories = await send('api/categories-get', {
|
||||
grouped: false,
|
||||
});
|
||||
const incomeCategoryId: string = categories.find(
|
||||
cat => cat.name === 'Income',
|
||||
).id;
|
||||
const accounts = await runHandler(app.handlers['api/accounts-get']);
|
||||
const payees = await runHandler(app.handlers['api/payees-get']);
|
||||
const accounts = await send('api/accounts-get');
|
||||
const payees = await send('api/payees-get');
|
||||
|
||||
function getCategory(id: string) {
|
||||
if (id == null || id === 'Category/__Split__') {
|
||||
@@ -249,7 +248,7 @@ async function importTransactions(
|
||||
})
|
||||
.filter(x => x);
|
||||
|
||||
await runHandler(app.handlers['api/transactions-add'], {
|
||||
await send('api/transactions-add', {
|
||||
accountId: entityIdMap.get(accountId),
|
||||
transactions: toImport,
|
||||
learnCategories: true,
|
||||
@@ -295,7 +294,7 @@ async function importBudgets(
|
||||
) {
|
||||
const budgets = sortByKey(data.monthlyBudgets, 'month');
|
||||
|
||||
await runHandler(app.handlers['api/batch-budget-start']);
|
||||
await send('api/batch-budget-start');
|
||||
try {
|
||||
for (const budget of budgets) {
|
||||
const filled = fillInBudgets(
|
||||
@@ -312,20 +311,20 @@ async function importBudgets(
|
||||
return;
|
||||
}
|
||||
|
||||
await runHandler(app.handlers['api/budget-set-amount'], {
|
||||
await send('api/budget-set-amount', {
|
||||
month,
|
||||
categoryId: catId,
|
||||
amount,
|
||||
});
|
||||
|
||||
if (catBudget.overspendingHandling === 'AffectsBuffer') {
|
||||
await runHandler(app.handlers['api/budget-set-carryover'], {
|
||||
await send('api/budget-set-carryover', {
|
||||
month,
|
||||
categoryId: catId,
|
||||
flag: false,
|
||||
});
|
||||
} else if (catBudget.overspendingHandling === 'Confined') {
|
||||
await runHandler(app.handlers['api/budget-set-carryover'], {
|
||||
await send('api/budget-set-carryover', {
|
||||
month,
|
||||
categoryId: catId,
|
||||
flag: true,
|
||||
@@ -335,7 +334,7 @@ async function importBudgets(
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
await runHandler(app.handlers['api/batch-budget-end']);
|
||||
await send('api/batch-budget-end');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,7 @@ import type { RecurConfig, RecurPattern, RuleEntity } from '../../types/models';
|
||||
// This is a special usage of the API because this package is embedded
|
||||
// into Actual itself. We call handlers directly to avoid cyclic dependency
|
||||
// between loot-core and @actual-app/api
|
||||
import { app } from '../main-app';
|
||||
import { runHandler } from '../mutators';
|
||||
import { send } from '../main-app';
|
||||
import { ruleModel } from '../transactions/transaction-rules';
|
||||
|
||||
import type {
|
||||
@@ -275,7 +274,7 @@ function importAccounts(data: Budget, entityIdMap: Map<string, string>) {
|
||||
return Promise.all(
|
||||
data.accounts.map(async account => {
|
||||
if (!account.deleted) {
|
||||
const id = await runHandler(app.handlers['api/account-create'], {
|
||||
const id = await send('api/account-create', {
|
||||
account: {
|
||||
name: account.name,
|
||||
offbudget: account.on_budget ? false : true,
|
||||
@@ -295,7 +294,7 @@ async function importCategories(
|
||||
// Hidden categories are put in its own group by YNAB,
|
||||
// so it's already handled.
|
||||
|
||||
const categories = await runHandler(app.handlers['api/categories-get'], {
|
||||
const categories = await send('api/categories-get', {
|
||||
grouped: false,
|
||||
});
|
||||
const incomeCatId = findIdByName(categories, 'Income');
|
||||
@@ -340,7 +339,7 @@ async function importCategories(
|
||||
while (true) {
|
||||
const name = count === 0 ? baseName : `${baseName} (${count})`;
|
||||
try {
|
||||
const id = await runHandler(app.handlers['api/category-group-create'], {
|
||||
const id = await send('api/category-group-create', {
|
||||
group: { ...params, name },
|
||||
});
|
||||
return { id, name };
|
||||
@@ -365,7 +364,7 @@ async function importCategories(
|
||||
while (true) {
|
||||
const name = count === 0 ? baseName : `${baseName} (${count})`;
|
||||
try {
|
||||
const id = await runHandler(app.handlers['api/category-create'], {
|
||||
const id = await send('api/category-create', {
|
||||
category: { ...params, name },
|
||||
});
|
||||
return { id, name };
|
||||
@@ -397,7 +396,7 @@ async function importCategories(
|
||||
groupId = createdGroup.id;
|
||||
entityIdMap.set(group.id, groupId);
|
||||
if (group.note) {
|
||||
void runHandler(app.handlers['notes-save'], {
|
||||
void send('notes-save', {
|
||||
id: groupId,
|
||||
note: group.note,
|
||||
});
|
||||
@@ -438,7 +437,7 @@ async function importCategories(
|
||||
});
|
||||
entityIdMap.set(cat.id, createdCategory.id);
|
||||
if (cat.note) {
|
||||
void runHandler(app.handlers['notes-save'], {
|
||||
void send('notes-save', {
|
||||
id: createdCategory.id,
|
||||
note: cat.note,
|
||||
});
|
||||
@@ -455,7 +454,7 @@ function importPayees(data: Budget, entityIdMap: Map<string, string>) {
|
||||
return Promise.all(
|
||||
data.payees.map(async payee => {
|
||||
if (!payee.deleted) {
|
||||
const id = await runHandler(app.handlers['api/payee-create'], {
|
||||
const id = await send('api/payee-create', {
|
||||
payee: { name: payee.name },
|
||||
});
|
||||
entityIdMap.set(payee.id, id);
|
||||
@@ -506,7 +505,7 @@ async function importFlagsAsTags(
|
||||
|
||||
await Promise.all(
|
||||
[...tagsToCreate.entries()].map(async ([tag, color]) => {
|
||||
await runHandler(app.handlers['tags-create'], {
|
||||
await send('tags-create', {
|
||||
tag,
|
||||
color,
|
||||
description: 'Imported from YNAB',
|
||||
@@ -520,8 +519,8 @@ async function importTransactions(
|
||||
entityIdMap: Map<string, string>,
|
||||
flagNameConflicts: Set<string>,
|
||||
) {
|
||||
const payees = await runHandler(app.handlers['api/payees-get']);
|
||||
const categories = await runHandler(app.handlers['api/categories-get'], {
|
||||
const payees = await send('api/payees-get');
|
||||
const categories = await send('api/categories-get', {
|
||||
grouped: false,
|
||||
});
|
||||
const incomeCatId = findIdByName(categories, 'Income');
|
||||
@@ -786,7 +785,7 @@ async function importTransactions(
|
||||
})
|
||||
.filter(x => x);
|
||||
|
||||
await runHandler(app.handlers['api/transactions-add'], {
|
||||
await send('api/transactions-add', {
|
||||
accountId: entityIdMap.get(accountId),
|
||||
transactions: toImport,
|
||||
learnCategories: true,
|
||||
@@ -810,7 +809,7 @@ async function importScheduledTransactions(
|
||||
return;
|
||||
}
|
||||
|
||||
const payees = await runHandler(app.handlers['api/payees-get']);
|
||||
const payees = await send('api/payees-get');
|
||||
const payeesByTransferAcct = payees
|
||||
.filter(payee => payee?.transfer_acct)
|
||||
.map(payee => [payee.transfer_acct, payee] as [string, Payee]);
|
||||
@@ -833,7 +832,7 @@ async function importScheduledTransactions(
|
||||
|
||||
while (true) {
|
||||
try {
|
||||
return await runHandler(app.handlers['api/schedule-create'], {
|
||||
return await send('api/schedule-create', {
|
||||
...params,
|
||||
name: params.name,
|
||||
});
|
||||
@@ -851,7 +850,7 @@ async function importScheduledTransactions(
|
||||
async function getRuleForSchedule(
|
||||
scheduleId: string,
|
||||
): Promise<RuleEntity | null> {
|
||||
const { data: ruleId } = (await runHandler(app.handlers['api/query'], {
|
||||
const { data: ruleId } = (await send('api/query', {
|
||||
query: q('schedules')
|
||||
.filter({ id: scheduleId })
|
||||
.calculate('rule')
|
||||
@@ -861,7 +860,7 @@ async function importScheduledTransactions(
|
||||
return null;
|
||||
}
|
||||
|
||||
const { data: ruleData } = (await runHandler(app.handlers['api/query'], {
|
||||
const { data: ruleData } = (await send('api/query', {
|
||||
query: q('rules').filter({ id: ruleId }).select('*').serialize(),
|
||||
})) as { data: Array<Record<string, unknown>> };
|
||||
const ruleRow = ruleData?.[0];
|
||||
@@ -922,7 +921,7 @@ async function importScheduledTransactions(
|
||||
value: scheduleNotes,
|
||||
});
|
||||
|
||||
await runHandler(app.handlers['api/rule-update'], {
|
||||
await send('api/rule-update', {
|
||||
rule: buildRuleUpdate(rule, actions),
|
||||
});
|
||||
}
|
||||
@@ -957,7 +956,7 @@ async function importScheduledTransactions(
|
||||
value: categoryId,
|
||||
});
|
||||
|
||||
await runHandler(app.handlers['api/rule-update'], {
|
||||
await send('api/rule-update', {
|
||||
rule: buildRuleUpdate(rule, actions),
|
||||
});
|
||||
}
|
||||
@@ -1036,7 +1035,7 @@ async function importScheduledTransactions(
|
||||
}
|
||||
});
|
||||
|
||||
await runHandler(app.handlers['api/rule-update'], {
|
||||
await send('api/rule-update', {
|
||||
rule: buildRuleUpdate(rule, actions),
|
||||
});
|
||||
}
|
||||
@@ -1063,7 +1062,7 @@ async function importBudgets(data: Budget, entityIdMap: Map<string, string>) {
|
||||
'Credit Card Payments',
|
||||
);
|
||||
|
||||
await runHandler(app.handlers['api/batch-budget-start']);
|
||||
await send('api/batch-budget-start');
|
||||
try {
|
||||
for (const budget of budgets) {
|
||||
const month = monthUtils.monthFromDate(budget.month);
|
||||
@@ -1081,7 +1080,7 @@ async function importBudgets(data: Budget, entityIdMap: Map<string, string>) {
|
||||
return;
|
||||
}
|
||||
|
||||
await runHandler(app.handlers['api/budget-set-amount'], {
|
||||
await send('api/budget-set-amount', {
|
||||
month,
|
||||
categoryId: catId,
|
||||
amount,
|
||||
@@ -1090,7 +1089,7 @@ async function importBudgets(data: Budget, entityIdMap: Map<string, string>) {
|
||||
);
|
||||
}
|
||||
} finally {
|
||||
await runHandler(app.handlers['api/batch-budget-end']);
|
||||
await send('api/batch-budget-end');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as connection from '../platform/server/connection';
|
||||
import type { Handlers } from '../types/handlers';
|
||||
|
||||
import { createApp } from './app';
|
||||
import { runHandler } from './mutators';
|
||||
|
||||
// Main app
|
||||
export const app = createApp<Handlers>();
|
||||
@@ -9,3 +10,16 @@ export const app = createApp<Handlers>();
|
||||
app.events.on('sync', event => {
|
||||
connection.send('sync-event', event);
|
||||
});
|
||||
|
||||
/**
|
||||
* Run a handler by name (server-side). Same API shape as the client connection's send.
|
||||
* Used by server code that needs to invoke handlers directly, e.g. importers.
|
||||
*/
|
||||
export async function send<K extends keyof Handlers>(
|
||||
name: K,
|
||||
args?: Parameters<Handlers[K]>[0],
|
||||
): Promise<Awaited<ReturnType<Handlers[K]>>> {
|
||||
return runHandler(app.handlers[name], args, { name }) as Promise<
|
||||
Awaited<ReturnType<Handlers[K]>>
|
||||
>;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user