splitwise-sdk
Version:
Splitwise API SDK for Node.js
202 lines (201 loc) • 7.78 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SplitwiseClient = void 0;
const oauth_1 = require("oauth");
const constants_1 = require("./constants");
const logger_1 = require("./logger");
class SplitwiseClient {
consumerKey;
consumerSecret;
accessToken;
oauth2;
logger;
constructor(options) {
this.consumerKey = options.consumerKey;
this.consumerSecret = options.consumerSecret;
this.accessToken = options.accessToken;
this.logger = (0, logger_1.getLogger)(options.logger, logger_1.LOG_LEVELS.INFO);
// OAuth2-Instanz initialisieren, falls consumerKey und consumerSecret vorhanden sind.
if (this.consumerKey && this.consumerSecret) {
this.oauth2 = new oauth_1.OAuth2(this.consumerKey, this.consumerSecret, "https://secure.splitwise.com/", // Basis-URL
"oauth/", // Autorisierungs-Pfad (anpassen falls nötig)
"oauth/token", // Access-Token-Pfad (anpassen falls nötig)
undefined // Statt null: undefined
);
}
}
log(level, message) {
if (process.env.NODE_ENV === "development" || level !== logger_1.LOG_LEVELS.DEBUG)
this.logger(`[${level.toUpperCase()}] ${message}`);
}
/**
* Hilfsmethode, um Query-Strings aus einem Objekt zu erzeugen.
*/
buildQueryString(params) {
const qs = new URLSearchParams();
for (const key in params) {
if (params[key] !== undefined && params[key] !== null) {
qs.append(key, String(params[key]));
}
}
return qs.toString();
}
/**
* Holt den Access Token mithilfe der OAuth-Library.
* Falls bereits ein Token vorhanden ist, wird dieser genutzt.
*/
async fetchAccessToken() {
if (this.accessToken) {
return this.accessToken;
}
if (!this.oauth2) {
throw new Error("Consumer Key und Consumer Secret sind erforderlich, um einen Access Token abzurufen.");
}
this.log(logger_1.LOG_LEVELS.DEBUG, "Access Token wird abgerufen...");
// Eigener Promise-Wrapper, um den callback-basierten Aufruf zu behandeln
const token = await new Promise((resolve, reject) => {
this.oauth2.getOAuthAccessToken("", { grant_type: "client_credentials" }, (err, token) => {
if (err) {
reject(err);
}
else {
if (token) {
resolve(token);
}
else {
reject(new Error("Token is undefined"));
}
}
});
});
if (!token) {
throw new Error("Kein Access Token in der Antwort enthalten.");
}
this.accessToken = token;
this.log(logger_1.LOG_LEVELS.DEBUG, "Access Token erfolgreich abgerufen.");
return token;
}
/**
* Generische Methode, um API-Anfragen zu stellen.
*/
async request(endpoint, method = constants_1.HTTP_VERBS.GET, body) {
const token = await this.fetchAccessToken();
const url = `${constants_1.API_URL}${endpoint}`;
const headers = {
Authorization: `Bearer ${token}`,
"Content-Type": "application/json",
};
this.log(logger_1.LOG_LEVELS.INFO, `Anfrage an ${url} (Methode: ${method}) wird ausgeführt.`);
const response = await fetch(url, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
});
if (!response.ok) {
const errorBody = await response.text();
throw new Error(`API-Anfrage fehlgeschlagen: ${response.status} ${response.statusText} – ${errorBody}`);
}
return response.json();
}
// === API-Funktionen basierend auf der OpenAPI-Definition ===
// Users
async getCurrentUser() {
return this.request("get_current_user", constants_1.HTTP_VERBS.GET);
}
async getUser(id) {
return this.request(`get_user/${id}`, constants_1.HTTP_VERBS.GET);
}
async updateUser(id, body) {
return this.request(`update_user/${id}`, constants_1.HTTP_VERBS.POST, body);
}
// Groups
async getGroups() {
return this.request("get_groups", constants_1.HTTP_VERBS.GET);
}
async getGroup(id) {
return this.request(`get_group/${id}`, constants_1.HTTP_VERBS.GET);
}
async createGroup(body) {
return this.request("create_group", constants_1.HTTP_VERBS.POST, body);
}
async deleteGroup(id) {
return this.request(`delete_group/${id}`, constants_1.HTTP_VERBS.POST);
}
async undeleteGroup(id) {
return this.request(`undelete_group/${id}`, constants_1.HTTP_VERBS.POST);
}
async addUserToGroup(body) {
return this.request("add_user_to_group", constants_1.HTTP_VERBS.POST, body);
}
async removeUserFromGroup(body) {
return this.request("remove_user_from_group", constants_1.HTTP_VERBS.POST, body);
}
// Friends
async getFriends() {
return this.request("get_friends", constants_1.HTTP_VERBS.GET);
}
async getFriend(id) {
return this.request(`get_friend/${id}`, constants_1.HTTP_VERBS.GET);
}
async createFriend(body) {
return this.request("create_friend", constants_1.HTTP_VERBS.POST, body);
}
async createFriends(body) {
return this.request("create_friends", constants_1.HTTP_VERBS.POST, body);
}
async deleteFriend(id) {
return this.request(`delete_friend/${id}`, constants_1.HTTP_VERBS.POST);
}
// Currencies
async getCurrencies() {
return this.request("get_currencies", constants_1.HTTP_VERBS.GET);
}
// Expenses
async getExpense(id) {
return this.request(`get_expense/${id}`, constants_1.HTTP_VERBS.GET);
}
async getExpenses(queryParams) {
let endpoint = "get_expenses";
if (queryParams && Object.keys(queryParams).length > 0) {
endpoint += "?" + this.buildQueryString(queryParams);
}
return this.request(endpoint, constants_1.HTTP_VERBS.GET);
}
async createExpense(body) {
// body kann entweder vom Typ "equal_group_split" oder "by_shares" sein
return this.request("create_expense", constants_1.HTTP_VERBS.POST, body);
}
async updateExpense(id, body) {
return this.request(`update_expense/${id}`, constants_1.HTTP_VERBS.POST, body);
}
async deleteExpense(id) {
return this.request(`delete_expense/${id}`, constants_1.HTTP_VERBS.POST);
}
async undeleteExpense(id) {
return this.request(`undelete_expense/${id}`, constants_1.HTTP_VERBS.POST);
}
// Comments
async getComments(expense_id) {
const endpoint = "get_comments?" + this.buildQueryString({ expense_id });
return this.request(endpoint, constants_1.HTTP_VERBS.GET);
}
async createComment(body) {
return this.request("create_comment", constants_1.HTTP_VERBS.POST, body);
}
async deleteComment(id) {
return this.request(`delete_comment/${id}`, constants_1.HTTP_VERBS.POST);
}
// Notifications
async getNotifications(queryParams) {
let endpoint = "get_notifications";
if (queryParams && Object.keys(queryParams).length > 0) {
endpoint += "?" + this.buildQueryString(queryParams);
}
return this.request(endpoint, constants_1.HTTP_VERBS.GET);
}
// Categories
async getCategories() {
return this.request("get_categories", constants_1.HTTP_VERBS.GET);
}
}
exports.SplitwiseClient = SplitwiseClient;