Files
2026-10-14 20:29:22 +02:00

56 lines
1.7 KiB
JavaScript

"use strict";
function req(path, options) {
const headers = { "Content-Type": "application/json" };
options = Object.assign({ method: "GET", headers }, options || {});
if (options.body && typeof options.body === "object") {
options.body = JSON.stringify(options.body);
}
return fetch(path, options).then(function (r) {
return r.json().then(function (data) {
if (!r.ok) throw new Error(data.error || "request failed");
return data;
});
});
}
function postForm(path, form) {
const data = {};
for (const [k, v] of new FormData(form)) {
if (v) data[k] = v;
}
return req(path, { method: "POST", body: JSON.stringify(data) });
}
function patchJson(path, body) {
return req(path, { method: "PATCH", body: body });
}
function delReq(path) {
return req(path, { method: "DELETE" });
}
function escapeHtml(s) {
return String(s)
.replace(/&/g, "&")
.replace(/</g, "&lt;")
.replace(/>/g, "&gt;")
.replace(/"/g, "&quot;");
}
function uuid() {
if (typeof crypto !== "undefined" && crypto.randomUUID) return crypto.randomUUID();
const a = new Uint8Array(16);
(crypto.getRandomValues || function () { for (let i = 0; i < a.length; i++) a[i] = Math.floor(Math.random() * 256); })(a);
a[6] = (a[6] & 0x0f) | 0x40;
a[8] = (a[8] & 0x3f) | 0x80;
const hex = Array.from(a, b => b.toString(16).padStart(2, "0")).join("");
return hex.slice(0, 8) + "-" + hex.slice(8, 12) + "-" + hex.slice(12, 16) + "-" + hex.slice(16, 20) + "-" + hex.slice(20);
}
function appendMsg(el, message, isError) {
el.textContent = message || "";
el.classList.toggle("hidden", !message);
el.style.color = isError ? "#dc2626" : "#047857";
}