Files
bookhoard/web/src/api-explorer-docs.ts
T
john-okeefe b4cf1ddafa style: apply code formatting to generated templates and TypeScript files
- Regenerate Go template files with updated FileName paths for error reporting
- Apply Prettier formatting to api-explorer-docs.ts for consistency
- Format long function signatures across multiple lines for readability
- Format long conditional chains for better code clarity

Changes are purely formatting and do not affect functionality:
- api-explorer-docs.ts: Format initAPIExplorerDoc, tryDocEndpoint, and other functions
- Generated _templ.go files: Update FileName paths from relative to absolute (e.g., "admin.templ" → "templates/admin.templ")

This ensures consistent code style across the codebase and improves
error reporting by providing full file paths in template error messages.
2026-03-12 15:44:46 -04:00

177 lines
4.9 KiB
TypeScript

import { Alpine } from "./alpine";
import { getToken } from "./storage";
let endpointPath = "";
let exampleResponse: unknown = null;
function initAPIExplorerDoc(
path: string,
request: string,
response: string,
): void {
endpointPath = path;
exampleResponse = JSON.parse(response);
}
function showDocMode(mode: "mock" | "real"): void {
const mockBtn = document.getElementById("mock-btn");
const realBtn = document.getElementById("real-btn");
const responseBody = document.getElementById("response-body");
const responseStatus = document.getElementById("response-status");
const responseTime = document.getElementById("response-time");
const apiResponse = document.querySelector(".api-response");
const requestBody = document.getElementById(
"request-body",
) as HTMLTextAreaElement;
const tryItOut = document.getElementById("try-it-out");
if (
!mockBtn ||
!realBtn ||
!responseBody ||
!responseStatus ||
!responseTime ||
!apiResponse ||
!requestBody ||
!tryItOut
)
return;
if (mode === "mock") {
mockBtn.classList.add("bg-accent", "text-white");
mockBtn.classList.remove("bg-background-primary", "text-text-primary");
realBtn.classList.remove("bg-accent", "text-white");
realBtn.classList.add("bg-background-primary", "text-text-primary");
apiResponse.classList.remove("hidden");
requestBody.readOnly = true;
tryItOut.classList.add("hidden");
responseBody.textContent = JSON.stringify(exampleResponse, null, 2);
responseStatus.textContent = "200 OK";
responseTime.textContent = "Mock";
} else {
realBtn.classList.add("bg-accent", "text-white");
realBtn.classList.remove("bg-background-primary", "text-text-primary");
mockBtn.classList.remove("bg-accent", "text-white");
mockBtn.classList.add("bg-background-primary", "text-text-primary");
apiResponse.classList.add("hidden");
requestBody.readOnly = false;
tryItOut.classList.remove("hidden");
}
}
async function tryDocEndpoint(): Promise<void> {
const methodSelect = document.getElementById(
"http-method",
) as HTMLSelectElement;
const requestBody = document.getElementById(
"request-body",
) as HTMLTextAreaElement;
const responseBody = document.getElementById("response-body");
const responseStatus = document.getElementById("response-status");
const responseTime = document.getElementById("response-time");
const apiResponse = document.querySelector(".api-response");
if (
!methodSelect ||
!requestBody ||
!responseBody ||
!responseStatus ||
!responseTime ||
!apiResponse
)
return;
const method = methodSelect.value;
const body = requestBody.value;
const startTime = Date.now();
try {
const token = getToken();
if (!token) {
throw new Error("No authentication token found");
}
const response = await fetch(endpointPath, {
method: method,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: ["GET", "DELETE"].includes(method) ? undefined : body,
});
const duration = Date.now() - startTime;
const data = await response.json();
responseStatus.textContent = `${response.status} (${response.statusText})`;
responseTime.textContent = `${duration}ms`;
responseBody.textContent = JSON.stringify(data, null, 2);
apiResponse.classList.remove("hidden");
} catch (error) {
responseStatus.textContent = "Error";
responseBody.textContent = (error as Error).message;
apiResponse.classList.remove("hidden");
}
}
function copyDocRequest(): void {
const requestBody = document.getElementById(
"request-body",
) as HTMLTextAreaElement;
if (requestBody) {
navigator.clipboard.writeText(requestBody.value);
}
}
function copyDocResponse(): void {
const responseBody = document.getElementById("response-body");
if (responseBody) {
navigator.clipboard.writeText(responseBody.textContent || "");
}
}
function generateDocCURL(): void {
const methodSelect = document.getElementById(
"http-method",
) as HTMLSelectElement;
const requestBody = document.getElementById(
"request-body",
) as HTMLTextAreaElement;
if (!methodSelect || !requestBody) return;
const method = methodSelect.value;
const body = requestBody.value;
const token = getToken();
let curl = `curl -X ${method} \\n -H "Content-Type: application/json" \\n -H "Authorization: Bearer ${token}"`;
if (!["GET", "DELETE"].includes(method) && body.trim()) {
curl += ` \\n -d '${body}'`;
}
curl += ` \\n ${endpointPath}`;
navigator.clipboard.writeText(curl);
}
export {
copyDocRequest,
copyDocResponse,
generateDocCURL,
initAPIExplorerDoc,
showDocMode,
tryDocEndpoint,
};
Alpine.data("apiExplorerDoc", () => ({
copyDocRequest,
copyDocResponse,
generateDocCURL,
initAPIExplorerDoc,
showDocMode,
tryDocEndpoint,
}));