split-expense-ynab-venmo-shared
Version:
Shared library code the app Expo+Firebase app 'Split Expense: YNAB + Venmo'
185 lines (182 loc) • 5.93 kB
JavaScript
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/ynab.ts
import { objectKeys } from "ts-extras";
import { API } from "ynab";
import { z } from "zod";
var _config, _ynabApi;
var YNABClient = class {
constructor(config) {
__privateAdd(this, _config, void 0);
__privateAdd(this, _ynabApi, void 0);
__privateSet(this, _config, config);
__privateSet(this, _ynabApi, new API(__privateGet(this, _config).YNAB_API_TOKEN));
}
getDefaultBudget() {
return __async(this, null, function* () {
const budgetsResponse = yield __privateGet(this, _ynabApi).budgets.getBudgets();
const firstBudget = budgetsResponse.data.budgets[0];
if (!firstBudget)
throw new Error("No budget found.");
return firstBudget;
});
}
getAccounts() {
return __async(this, null, function* () {
const response = yield __privateGet(this, _ynabApi).accounts.getAccounts(__privateGet(this, _config).DEFAULT_BUDGET_ID);
return response.data.accounts;
});
}
getCategoryGroups() {
return __async(this, null, function* () {
const budget = yield this.getDefaultBudget();
const categoriesResponse = yield __privateGet(this, _ynabApi).categories.getCategories(budget.id);
return categoriesResponse.data.category_groups;
});
}
getCategoriesFlat() {
return __async(this, null, function* () {
const categoryGroups = yield this.getCategoryGroups();
const categoriesFlat = categoryGroups.filter((group) => !group.hidden).map((group) => group.categories).flat();
return categoriesFlat;
});
}
addTransactions(transactions) {
return __async(this, null, function* () {
try {
yield __privateGet(this, _ynabApi).transactions.createTransaction(__privateGet(this, _config).DEFAULT_BUDGET_ID, {
transactions: transactions.map((transaction) => this.createTransaction(transaction))
});
} catch (e) {
console.error(e);
}
});
}
createTransaction(transactionDetails) {
return {
account_id: transactionDetails.accountId,
amount: transactionDetails.cents * 10,
date: (/* @__PURE__ */ new Date()).toISOString().split("T")[0],
payee_name: transactionDetails.payeeName,
memo: transactionDetails.memo,
category_id: transactionDetails.categoryId
};
}
};
_config = new WeakMap();
_ynabApi = new WeakMap();
var YNABEnvVarsSchema = z.object({
YNAB_API_TOKEN: z.string(),
DEFAULT_BUDGET_ID: z.string()
});
var YNAB_ENV_VARS = objectKeys(YNABEnvVarsSchema.keyof().Values);
var TransactionDetailsSchema = z.object({
accountId: z.string(),
cents: z.number(),
payeeName: z.string(),
memo: z.string().optional(),
categoryId: z.string()
});
// src/venmo.ts
import { z as z2 } from "zod";
import { objectKeys as objectKeys2 } from "ts-extras";
var _accessToken, _defaultChargeeUserId;
var VenmoClient = class {
constructor(config) {
__privateAdd(this, _accessToken, void 0);
__privateAdd(this, _defaultChargeeUserId, void 0);
__privateSet(this, _accessToken, config.accessToken);
__privateSet(this, _defaultChargeeUserId, config.defaultChargeeId);
}
requestPayment(details) {
return __async(this, null, function* () {
try {
const chargeResponse = yield fetch("https://api.venmo.com/v1/payments", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${__privateGet(this, _accessToken)}`
},
body: JSON.stringify({
note: details.note,
metadata: {
quasi_cash_disclaimer_viewed: false
},
amount: details.cents * -0.01,
user_id: __privateGet(this, _defaultChargeeUserId),
audience: "private"
})
});
if (!chargeResponse.ok) {
throw new Error(`Venmo charge failed with status ${chargeResponse.status}`);
}
} catch (e) {
console.error("Venmo charge error: ", e);
throw e;
}
});
}
};
_accessToken = new WeakMap();
_defaultChargeeUserId = new WeakMap();
var ChargeeIdSchema = z2.string();
var VenmoEnvVarsSchema = z2.object({
DEFAULT_VENMO_CHARGEE_ID: ChargeeIdSchema,
VENMO_API_ACCESS_TOKEN: z2.string()
});
var VENMO_ENV_VAR_NAMES = objectKeys2(VenmoEnvVarsSchema.keyof().Values);
var VenmoConfigSchema = z2.object({
accessToken: z2.string(),
defaultChargeeId: ChargeeIdSchema
});
var PaymentDetailsSchema = z2.object({
cents: z2.number(),
note: z2.string()
});
export {
PaymentDetailsSchema,
TransactionDetailsSchema,
VENMO_ENV_VAR_NAMES,
VenmoClient,
VenmoConfigSchema,
VenmoEnvVarsSchema,
YNABClient,
YNABEnvVarsSchema,
YNAB_ENV_VARS
};