actual-moneymoney
Version:
An importer for syncing MoneyMoney accounts and transactions to Actual.
148 lines (147 loc) • 6.19 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import actual from '@actual-app/api';
import fs from 'fs/promises';
import { formatDate } from './date.js';
import { DEFAULT_DATA_DIR } from './shared.js';
class ActualApi {
constructor(serverConfig, logger) {
this.serverConfig = serverConfig;
this.logger = logger;
this.isInitialized = false;
this.api = null;
}
init() {
return __awaiter(this, void 0, void 0, function* () {
const actualDataDir = DEFAULT_DATA_DIR;
const dataDirExists = yield fs
.access(actualDataDir)
.then(() => true)
.catch(() => false);
if (!dataDirExists) {
yield fs.mkdir(actualDataDir, { recursive: true });
this.logger.debug(`Created Actual data directory at ${actualDataDir}`);
}
this.logger.debug(`Initializing Actual instance for server ${this.serverConfig.serverUrl} with data directory ${actualDataDir}`);
yield this.suppressConsoleLog(() => __awaiter(this, void 0, void 0, function* () {
yield actual.init({
dataDir: actualDataDir,
serverURL: this.serverConfig.serverUrl,
password: this.serverConfig.serverPassword,
});
}));
this.isInitialized = true;
});
}
ensureInitialization() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.isInitialized) {
yield this.init();
}
});
}
sync() {
return __awaiter(this, void 0, void 0, function* () {
yield this.ensureInitialization();
yield this.suppressConsoleLog(() => __awaiter(this, void 0, void 0, function* () {
yield actual.internal.send('sync');
}));
});
}
getAccounts() {
return __awaiter(this, void 0, void 0, function* () {
yield this.ensureInitialization();
const accounts = yield this.suppressConsoleLog(() => __awaiter(this, void 0, void 0, function* () {
return yield actual.getAccounts();
}));
return accounts;
});
}
loadBudget(budgetId) {
return __awaiter(this, void 0, void 0, function* () {
this.logger.debug(`Looking for budget configuration with syncId '${budgetId}'...`);
const budgetConfig = this.serverConfig.budgets.find((b) => b.syncId === budgetId);
if (!budgetConfig) {
throw new Error(`No budget with syncId '${budgetId}' found.`);
}
this.logger.debug(`Loading budget with syncId ${budgetId}...`);
yield this.suppressConsoleLog(() => __awaiter(this, void 0, void 0, function* () {
yield actual.downloadBudget(budgetConfig.syncId, budgetConfig.e2eEncryption.enabled
? {
password: budgetConfig.e2eEncryption.password,
}
: undefined);
}));
});
}
importTransactions(accountId, transactions) {
return this.suppressConsoleLog(() => actual.importTransactions(accountId, transactions, {
defaultCleared: false,
}));
}
getTransactions(accountId) {
const startDate = formatDate(new Date(2000, 1, 1));
const endDate = formatDate(new Date());
return this.suppressConsoleLog(() => actual.getTransactions(accountId, startDate, endDate));
}
shutdown() {
return __awaiter(this, void 0, void 0, function* () {
yield this.ensureInitialization();
yield this.suppressConsoleLog(() => actual.shutdown());
});
}
getUserToken() {
return __awaiter(this, void 0, void 0, function* () {
var _a;
const response = yield fetch(`${this.serverConfig.serverUrl}/account/login`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
password: this.serverConfig.serverPassword,
}),
});
const responseData = (yield response.json());
const userToken = (_a = responseData.data) === null || _a === void 0 ? void 0 : _a.token;
if (!userToken) {
throw new Error('Could not get user token: Invalid server password.');
}
return userToken;
});
}
getUserFiles() {
return __awaiter(this, void 0, void 0, function* () {
const userToken = yield this.getUserToken();
const response = yield fetch(`${this.serverConfig.serverUrl}/sync/list-user-files`, {
headers: {
'X-Actual-Token': userToken,
},
});
const responseData = (yield response.json());
return responseData.data.filter((f) => f.deleted === 0);
});
}
suppressConsoleLog(callback) {
return __awaiter(this, void 0, void 0, function* () {
const originalConsoleLog = console.log;
console.log = (message) => {
this.logger.actual(message);
};
try {
return yield callback();
}
finally {
console.log = originalConsoleLog;
}
});
}
}
export default ActualApi;