UNPKG

@baruchiro/actual-mcp

Version:

Actual Budget MCP server exposing API functionality

63 lines 2.92 kB
import { getTransactions } from '../../actual-api.js'; import { fetchAllPayees } from './fetch-payees.js'; import { fetchAllCategories } from './fetch-categories.js'; import { GroupAggregator } from '../aggregation/group-by.js'; const groupAggregator = new GroupAggregator(); async function _buildTransactionLookups(options) { const [payees, categories] = await Promise.all([ options.includePayees ? fetchAllPayees() : Promise.resolve([]), options.includeCategories ? fetchAllCategories() : Promise.resolve([]), ]); const payeesById = options.includePayees ? groupAggregator.byId(payees) : {}; const categoriesById = options.includeCategories ? groupAggregator.byId(categories) : {}; return { payeesById, categoriesById }; } async function _enrichTransactions(transactions) { if (transactions.length === 0) { return transactions; } // # Reason: Only fetch lookup tables when transactions are missing names to avoid redundant API calls. const needsPayees = transactions.some((transaction) => Boolean(transaction.payee)); const needsCategories = transactions.some((transaction) => Boolean(transaction.category)); if (!needsPayees && !needsCategories) { return transactions; } const { payeesById, categoriesById } = await _buildTransactionLookups({ includePayees: needsPayees, includeCategories: needsCategories, }); return transactions.map((transaction) => { const payeeName = needsPayees && transaction.payee ? payeesById[transaction.payee]?.name : undefined; const categoryName = needsCategories && transaction.category ? categoriesById[transaction.category]?.name : undefined; const enriched = { ...transaction }; if (payeeName !== undefined) { enriched.payee_name = payeeName; } if (categoryName !== undefined) { enriched.category_name = categoryName; } return enriched; }); } export async function fetchTransactionsForAccount(accountId, start, end) { const transactions = await getTransactions(accountId, start, end); return _enrichTransactions(transactions); } export async function fetchAllOnBudgetTransactions(accounts, start, end) { let transactions = []; const onBudgetAccounts = accounts.filter((a) => !a.offbudget && !a.closed); for (const account of onBudgetAccounts) { const tx = await getTransactions(account.id, start, end); transactions = [...transactions, ...tx]; } return _enrichTransactions(transactions); } export async function fetchAllTransactions(accounts, start, end) { let transactions = []; for (const account of accounts) { const tx = await getTransactions(account.id, start, end); transactions = [...transactions, ...tx]; } return _enrichTransactions(transactions); } //# sourceMappingURL=fetch-transactions.js.map