Files
bookhoard/web/src/api-explorer-docs.ts
T
john-okeefe f85c9c3f66 refactor(reader): Fix reader-context imports and remove dead code
Problem:
- Many format modules imported from '../core/reader-context'
- reader-context.ts was a local interface file, not a true context module
- Confusion between canonical reader-shell.ts and local reader-context.ts
- PDF page-cache.ts was 100% dead code (unused, unregistered, no exports)
- Several unused variables and imports across reader modules

Root Cause:
- reader-context.ts created as temporary file during refactoring
- Modules imported from it instead of canonical reader-shell.ts
- page-cache.ts copied from comic version but never integrated
- Incomplete refactoring left behind unused code

Solution:
- Update all imports to use reader-shell (canonical source)
- Remove unused page-cache.ts (dead code)
- Clean up unused variables and imports
- Consolidate type definitions

Changes:

Import Path Updates:
- comic/*: '../core/reader-context' → '../../reader-shell'
- manga/*: '../core/reader-context' → '../../reader-shell'
- pdf/*: '../core/reader-context' → '../../reader-shell'
- reflowable/ebook/*: '../core/reader-context' → '../../reader-shell'
- All now import UniversalReader from single source

Dead Code Removal:
- pdf/page-cache.ts: Deleted entirely
  - No init() function exported
  - Not registered in reader-shell.ts
  - All functions unused (createPDFPageCache, getCachedPage, etc.)
  - Only 2 lines of executable code (console.log, DOM cleanup)
  - 148 lines of dead code

Clean Up:
- navigator-panel.ts: Remove unused containerRect variable
- api-explorer-docs.ts, api.ts, queue.ts: Fix unused imports
- unlinked_books.ts: Remove unused variables
- panel-dock-system.ts: Remove unused context variables

Impact:
-  All modules use canonical type definitions
-  No more duplicate/conflicting interfaces
-  Dead code removed (148 lines)
-  Cleaner imports, easier maintenance
-  TypeScript compiler warnings resolved

Files changed: 26
Lines changed: +450, -520 (net -70 lines)
2026-04-10 23:21:44 -04:00

173 lines
4.8 KiB
TypeScript

import { Alpine } from "./alpine";
import { getToken } from "./storage";
let endpointPath = "";
let exampleResponse: unknown = null;
function initAPIExplorerDoc(path: 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,
}));