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)
173 lines
4.8 KiB
TypeScript
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,
|
|
}));
|