UNPKG

split-expense-ynab-venmo-shared

Version:

Shared library code the app Expo+Firebase app 'Split Expense: YNAB + Venmo'

80 lines (67 loc) 2.42 kB
import { objectKeys } from 'ts-extras'; import { Account, API, SaveTransaction } from 'ynab'; import { z } from 'zod'; type YNABConfig = z.infer<typeof YNABEnvVarsSchema>; export class YNABClient { #config: YNABConfig; #ynabApi: API; constructor(config: YNABConfig) { this.#config = config; this.#ynabApi = new API(this.#config.YNAB_API_TOKEN); } async getDefaultBudget() { const budgetsResponse = await this.#ynabApi.budgets.getBudgets(); const firstBudget = budgetsResponse.data.budgets[0]; if (!firstBudget) throw new Error('No budget found.'); return firstBudget; } async getAccounts(): Promise<Account[]> { const response = await this.#ynabApi.accounts.getAccounts(this.#config.DEFAULT_BUDGET_ID); return response.data.accounts; } async getCategoryGroups() { const budget = await this.getDefaultBudget(); const categoriesResponse = await this.#ynabApi.categories.getCategories(budget.id); return categoriesResponse.data.category_groups; } async getCategoriesFlat() { const categoryGroups = await this.getCategoryGroups(); const categoriesFlat = categoryGroups .filter((group) => !group.hidden) .map((group) => group.categories) .flat(); return categoriesFlat; } async addTransactions(transactions: TransactionDetails[]) { try { await this.#ynabApi.transactions.createTransaction(this.#config.DEFAULT_BUDGET_ID, { transactions: transactions.map((transaction) => this.createTransaction(transaction)), }); } catch (e) { console.error(e); } } createTransaction(transactionDetails: TransactionDetails): SaveTransaction { return { account_id: transactionDetails.accountId, amount: transactionDetails.cents * 10, date: new Date().toISOString().split('T')[0], payee_name: transactionDetails.payeeName, memo: transactionDetails.memo, category_id: transactionDetails.categoryId, }; } } export const YNABEnvVarsSchema = z.object({ YNAB_API_TOKEN: z.string(), DEFAULT_BUDGET_ID: z.string(), }); export const YNAB_ENV_VARS = objectKeys(YNABEnvVarsSchema.keyof().Values); export const TransactionDetailsSchema = z.object({ accountId: z.string(), cents: z.number(), payeeName: z.string(), memo: z.string().optional(), categoryId: z.string(), }); export type TransactionDetails = z.infer<typeof TransactionDetailsSchema>;