|
// retoor <retoor@molodetz.nl>
|
|
|
|
export class DevRant {
|
|
constructor(baseUrl, username, password) {
|
|
this.baseUrl = baseUrl.replace(/\/$/, "");
|
|
this.username = username;
|
|
this.password = password;
|
|
this.auth = {};
|
|
}
|
|
|
|
_url(path, params) {
|
|
const url = new URL(`${this.baseUrl}/api/${path.replace(/^\//, "")}`);
|
|
for (const [key, value] of Object.entries(params || {})) {
|
|
url.searchParams.set(key, value);
|
|
}
|
|
return url;
|
|
}
|
|
|
|
async _request(method, path, params = {}, body = null) {
|
|
const merged = { ...params, ...this.auth };
|
|
const headers = { Accept: "application/json" };
|
|
let url;
|
|
const init = { method, headers };
|
|
if (method === "GET" || method === "DELETE") {
|
|
url = this._url(path, merged);
|
|
} else {
|
|
url = this._url(path);
|
|
headers["Content-Type"] = "application/x-www-form-urlencoded";
|
|
init.body = new URLSearchParams({ ...merged, ...(body || {}) }).toString();
|
|
}
|
|
const response = await fetch(url, init);
|
|
return response.json();
|
|
}
|
|
|
|
async login() {
|
|
const result = await this._request("POST", "users/auth-token", {}, {
|
|
username: this.username,
|
|
password: this.password,
|
|
});
|
|
if (!result.success) throw new Error(result.error || "login failed");
|
|
const token = result.auth_token;
|
|
this.auth = { user_id: token.user_id, token_id: token.id, token_key: token.key };
|
|
return this.auth;
|
|
}
|
|
|
|
register(email) {
|
|
return this._request("POST", "users", {}, {
|
|
username: this.username,
|
|
email,
|
|
password: this.password,
|
|
});
|
|
}
|
|
|
|
async rants(sort = "recent", limit = 20, skip = 0) {
|
|
const result = await this._request("GET", "devrant/rants", { sort, limit, skip });
|
|
return result.rants || [];
|
|
}
|
|
|
|
rant(rantId) {
|
|
return this._request("GET", `devrant/rants/${rantId}`);
|
|
}
|
|
|
|
async search(term) {
|
|
return (await this._request("GET", "devrant/search", { term })).results || [];
|
|
}
|
|
|
|
async userId(username) {
|
|
return (await this._request("GET", "get-user-id", { username })).user_id;
|
|
}
|
|
|
|
async profile(userId) {
|
|
return (await this._request("GET", `users/${userId}`)).profile;
|
|
}
|
|
|
|
async notifs() {
|
|
return (await this._request("GET", "users/me/notif-feed")).data || {};
|
|
}
|
|
|
|
clearNotifs() {
|
|
return this._request("DELETE", "users/me/notif-feed");
|
|
}
|
|
|
|
editProfile(fields) {
|
|
return this._request("POST", "users/me/edit-profile", {}, fields);
|
|
}
|
|
|
|
postRant(text, tags = "") {
|
|
return this._request("POST", "devrant/rants", {}, { rant: text, tags });
|
|
}
|
|
|
|
editRant(rantId, text, tags = "") {
|
|
return this._request("POST", `devrant/rants/${rantId}`, {}, { rant: text, tags });
|
|
}
|
|
|
|
deleteRant(rantId) {
|
|
return this._request("DELETE", `devrant/rants/${rantId}`);
|
|
}
|
|
|
|
voteRant(rantId, vote) {
|
|
return this._request("POST", `devrant/rants/${rantId}/vote`, {}, { vote });
|
|
}
|
|
|
|
favorite(rantId) {
|
|
return this._request("POST", `devrant/rants/${rantId}/favorite`);
|
|
}
|
|
|
|
unfavorite(rantId) {
|
|
return this._request("POST", `devrant/rants/${rantId}/unfavorite`);
|
|
}
|
|
|
|
comment(rantId, text) {
|
|
return this._request("POST", `devrant/rants/${rantId}/comments`, {}, { comment: text });
|
|
}
|
|
|
|
voteComment(commentId, vote) {
|
|
return this._request("POST", `comments/${commentId}/vote`, {}, { vote });
|
|
}
|
|
}
|
|
|
|
export function fromEnv() {
|
|
return new DevRant(
|
|
process.env.DEVRANT_BASE || "http://localhost:10500",
|
|
process.env.DEVRANT_USERNAME,
|
|
process.env.DEVRANT_PASSWORD,
|
|
);
|
|
}
|