Spaces:
Sleeping
Sleeping
| const _BODY_PREVIEW_MAX = 280; | |
| function _looksLikeHtmlDocument(body) { | |
| const s = String(body || "").trimStart(); | |
| if (!s) return false; | |
| if (s.startsWith("<!DOCTYPE") || s.startsWith("<!doctype")) return true; | |
| if (s.length >= 5 && /^<\s*html[\s>]/i.test(s.slice(0, 32))) return true; | |
| return s.startsWith("<html"); | |
| } | |
| function _clipMessage(msg) { | |
| const t = String(msg || "").trim(); | |
| if (!t) return ""; | |
| return t.length > _BODY_PREVIEW_MAX ? `${t.slice(0, _BODY_PREVIEW_MAX)}…` : t; | |
| } | |
| function _messageForFailedRequest(status, rawText, parsedPayload) { | |
| const raw = String(rawText || "").trim(); | |
| if (_looksLikeHtmlDocument(raw)) { | |
| return `Server error (${status}) — the response was a web page, not JSON. Try again in a moment.`; | |
| } | |
| if (parsedPayload && typeof parsedPayload.detail === "string" && parsedPayload.detail.trim()) { | |
| return _clipMessage(parsedPayload.detail); | |
| } | |
| if (parsedPayload && parsedPayload.detail != null) { | |
| try { | |
| return _clipMessage(JSON.stringify(parsedPayload.detail)); | |
| } catch { | |
| return `Request failed (${status})`; | |
| } | |
| } | |
| return _clipMessage(raw) || `Request failed (${status})`; | |
| } | |
| export async function api(path, options = {}) { | |
| const response = await fetch(path, options); | |
| const text = await response.text(); | |
| let payload; | |
| try { | |
| payload = text ? JSON.parse(text) : {}; | |
| } catch { | |
| if (!response.ok) { | |
| const message = _messageForFailedRequest(response.status, text, null); | |
| const error = new Error(message); | |
| error.status = response.status; | |
| error.payload = null; | |
| throw error; | |
| } | |
| return {}; | |
| } | |
| if (!response.ok) { | |
| const message = _messageForFailedRequest(response.status, text, payload); | |
| const error = new Error(message); | |
| error.status = response.status; | |
| error.payload = payload; | |
| throw error; | |
| } | |
| return payload; | |
| } | |
| export function authHeaders(token) { | |
| return token ? { "x-private-token": token } : {}; | |
| } | |
| export function uiReactionFor(rating) { | |
| if (rating === "love") return "love"; | |
| if (rating === "like") return "like"; | |
| if (rating === "curious") return "maybe"; | |
| if (rating === "not_interested") return "not_interested"; | |
| if (rating === "hard_no" || rating === "no") return "no_go"; | |
| return ""; | |
| } | |
| export function currentDirectionsFor(plays, kinkId) { | |
| return plays?.[kinkId]?.directions || []; | |
| } | |
| export { directionColumnsForPlay, directionsAfterColumnDrop } from "./direction-logic.js"; | |