- 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.
177 lines
4.9 KiB
TypeScript
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,
|
|
}));
|