//? intent: In-app API explorer — try this project's routes without leaving the browser. /* eslint-disable luckystack/no-raw-try-catch, luckystack/no-raw-fetch-in-src -- This file is the LuckyStack API Explorer UI: a Swagger-like browser that lets users (a) test framework `/api/*` and `/sync/*` endpoints over both socket AND raw HTTP transports, and (b) inspect runtime JSON payloads. Both raw `fetch` to typed routes and inline `try { JSON.parse } catch { fallback }` are intentional here — the helpers (`apiRequest`, `tryCatch`) would defeat the "show the consumer the wire-level details" purpose. Do NOT propagate this disable to consumer code; it lives only inside this docs-viewer file. */ import { useEffect, useMemo, useState } from 'react'; import { backendUrl, rateLimiting } from 'config'; import { i18nNotify as notify, useTranslator } from '@luckystack/core/client'; import { apiRequest } from 'src/_sockets/apiRequest'; import { joinRoom, leaveRoom } from 'src/_sockets/socketInitializer'; import { syncRequest, useSyncEvents } from 'src/_sockets/syncRequest'; import apiDocs from './apiDocs.generated.json'; interface ApiDoc { page: string; name: string; version: string; method: string; description?: string; input: string; output: string; auth: { login?: boolean; additional?: { key: string; value?: unknown; type?: string; nullish?: boolean; mustBeFalsy?: boolean; }[]; }; rateLimit: number | false | undefined; path: string; } interface SyncDoc { page: string; name: string; version: string; clientInput: string; serverOutput: string; clientOutput: string; path: string; } interface DocsResult { apis: Record; syncs: Record; } interface ApiRunResponse { status?: 'success' | 'error'; message?: string; [key: string]: unknown; } interface ParsedObjectField { key: string; optional: boolean; type: string; } type AdditionalPermission = NonNullable[number]; const methodBadgeClass = (method: string): string => { switch (method.toUpperCase()) { case 'GET': { return 'bg-correct text-title-primary'; } case 'POST': { return 'bg-primary text-title-primary'; } case 'PUT': { return 'bg-warning text-title'; } case 'DELETE': { return 'bg-wrong text-title-primary'; } case 'PATCH': { return 'bg-secondary text-title-secondary'; } default: { return 'bg-container2 text-common'; } } }; const statusBadgeClass = (status: 'idle' | 'loading' | 'success' | 'error'): string => { if (status === 'success') return 'bg-correct/10 border-correct/30 text-correct'; if (status === 'error') return 'bg-wrong/10 border-wrong/30 text-wrong'; if (status === 'loading') return 'bg-primary/10 border-primary/30 text-primary'; return 'bg-container2 border-container2-border text-common/50'; }; const statusDotClass = (status: 'idle' | 'loading' | 'success' | 'error'): string => { if (status === 'success') return 'bg-correct'; if (status === 'error') return 'bg-wrong'; if (status === 'loading') return 'bg-primary animate-pulse'; return 'bg-common/30'; }; const parseObjectType = (typeText: string): ParsedObjectField[] => { const clean = typeText.trim(); if (!clean.startsWith('{') || !clean.endsWith('}')) return []; const inner = clean.slice(1, -1); const rows: string[] = []; let token = ''; let depthParen = 0; let depthBrace = 0; let depthBracket = 0; for (const char of inner) { if (char === '(') depthParen += 1; if (char === ')') depthParen -= 1; if (char === '{') depthBrace += 1; if (char === '}') depthBrace -= 1; if (char === '[') depthBracket += 1; if (char === ']') depthBracket -= 1; if ((char === ';' || char === ',') && depthParen === 0 && depthBrace === 0 && depthBracket === 0) { const trimmed = token.trim(); if (trimmed.length > 0) rows.push(trimmed); token = ''; continue; } token += char; } const final = token.trim(); if (final.length > 0) rows.push(final); const result: ParsedObjectField[] = []; for (const row of rows) { const match = /^(\w+)(\?)?\s*:\s*(.+)$/.exec(row); if (!match) continue; result.push({ key: match[1], optional: Boolean(match[2]), type: match[3].trim(), }); } return result; }; const randomPrimitive = (type: string): unknown => { const trimmed = type.trim(); if (trimmed.includes('|')) { const unionParts = trimmed.split('|').map((part) => part.trim()).filter(Boolean); const preferred = unionParts.find((part) => part !== 'undefined' && part !== 'null'); const unionPart = unionParts[0] ?? 'string'; return randomPrimitive(preferred ?? unionPart); } if (trimmed === 'string') return `text-${String(Math.floor(Math.random() * 1000))}`; if (trimmed === 'number') return Math.floor(Math.random() * 100); if (trimmed === 'boolean') return Math.random() > 0.5; if (trimmed === 'Date') return new Date().toISOString(); if (trimmed.endsWith('[]')) { const innerType = trimmed.slice(0, -2); return [randomPrimitive(innerType), randomPrimitive(innerType)]; } if (trimmed.startsWith("'") && trimmed.endsWith("'")) { return trimmed.slice(1, -1); } if (trimmed.startsWith('"') && trimmed.endsWith('"')) { return trimmed.slice(1, -1); } return null; }; const generateRandomInput = (typeText: string): Record => { const fields = parseObjectType(typeText); const result: Record = {}; for (const field of fields) { if (field.optional && Math.random() > 0.6) { continue; } result[field.key] = randomPrimitive(field.type); } return result; }; const buildApiRoutePath = (api: ApiDoc): string => { if (api.page === 'root') { return `api/system/${api.name}/${api.version}`; } return `api/${api.page}/${api.name}/${api.version}`; }; const buildApiRequestName = (api: ApiDoc): string => { if (api.page === 'root') { return `system/${api.name}`; } return `${api.page}/${api.name}`; }; const buildSyncRoutePath = (sync: SyncDoc): string => { if (sync.page === 'root') { return `sync/system/${sync.name}/${sync.version}`; } return `sync/${sync.page}/${sync.name}/${sync.version}`; }; const buildSyncRequestName = (sync: SyncDoc): string => { if (sync.page === 'root') { return `system/${sync.name}`; } return `${sync.page}/${sync.name}`; }; const formatTypeText = (text: string): string => { const clean = text.trim(); if (!clean) return ''; let result = ''; let indentLevel = 0; let inSingleQuote = false; let inDoubleQuote = false; const indent = () => { result += ' '.repeat(Math.max(indentLevel, 0)); }; for (let index = 0; index < clean.length; index += 1) { const char = clean[index]; const previous = clean[index - 1]; if (char === "'" && !inDoubleQuote && previous !== '\\') { inSingleQuote = !inSingleQuote; result += char; continue; } if (char === '"' && !inSingleQuote && previous !== '\\') { inDoubleQuote = !inDoubleQuote; result += char; continue; } if (inSingleQuote || inDoubleQuote) { result += char; continue; } if (char === '{' || char === '[' || char === '(') { result += char; indentLevel += 1; result += '\n'; indent(); continue; } if (char === '}' || char === ']' || char === ')') { indentLevel -= 1; if (!result.endsWith('\n')) { result += '\n'; } indent(); result += char; continue; } if (char === ';' || char === ',') { result += char; result += '\n'; indent(); continue; } if (char === ':') { result += ': '; continue; } result += char; } return result .split('\n') .map((line) => line.trimEnd()) .join('\n') .trim(); }; const buildApiFetchExample = (api: ApiDoc, input: string): string => { const route = buildApiRoutePath(api); const method = api.method.toUpperCase(); const data = input.trim() || '{}'; return [ `const data = ${data};`, '', `await fetch('${backendUrl}/${route}', {`, ` method: '${method}',`, ` headers: { 'Content-Type': 'application/json' },`, ` body: JSON.stringify(data),`, `});`, ].join('\n'); }; const buildApiSocketExample = (api: ApiDoc, input: string): string => { const routeName = buildApiRequestName(api); const data = input.trim() || '{}'; return [ `const data = ${data};`, '', `socket.emit('apiRequest', {`, ` name: 'api/${routeName}/${api.version}',`, ` data,`, ` responseIndex: 1,`, `});`, ].join('\n'); }; const buildSyncFetchExample = (sync: SyncDoc, input: string): string => { const route = buildSyncRoutePath(sync); const data = input.trim() || '{}'; return [ `const data = ${data};`, '', `await fetch('${backendUrl}/${route}', {`, ` method: 'POST',`, ` headers: { 'Content-Type': 'application/json' },`, ` body: JSON.stringify({`, ` data,`, ` receiver: 'room-code',`, ` ignoreSelf: false,`, ` }),`, `});`, ].join('\n'); }; const buildSyncSocketExample = (sync: SyncDoc, input: string, receiver: string, ignoreSelf: boolean): string => { const routeName = buildSyncRequestName(sync); const data = input.trim() || '{}'; return [ `const data = ${data};`, '', `socket.emit('sync', {`, ` name: 'sync/${routeName}/${sync.version}',`, ` cb: '${routeName}/${sync.version}',`, ` data,`, ` receiver: ${JSON.stringify(receiver)},`, ` ignoreSelf: ${String(ignoreSelf)},`, ` responseIndex: 1,`, `});`, ].join('\n'); }; const getRateLimitText = ({ selectedApiRateLimit, defaultApiLimit, translate, }: { selectedApiRateLimit: number | false | undefined; defaultApiLimit: number | false; translate: (params: { key: string }) => string; }): string => { if (selectedApiRateLimit === false) return translate({ key: 'docs.unlimited' }); if (typeof selectedApiRateLimit === 'number') return `${String(selectedApiRateLimit)} req/min`; if (defaultApiLimit === false) return translate({ key: 'docs.unlimited' }); return `${String(defaultApiLimit)} req/min (default)`; }; const getAdditionalPermissionLabel = (item: AdditionalPermission): string => { const formatUnknownValue = (value: unknown): string => { if (typeof value === 'string') return value; if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') { return String(value); } if (value === null) return 'null'; if (value === undefined) return 'undefined'; try { return JSON.stringify(value); } catch { return '[unserializable]'; } }; if (item.value !== undefined) { const value = formatUnknownValue(item.value); return `${item.key} = ${value}`; } if (item.type !== undefined) { return `${item.key}: ${item.type}`; } if (item.nullish !== undefined) { return item.nullish ? `${item.key} is nullish` : `${item.key} not nullish`; } if (item.mustBeFalsy !== undefined) { return item.mustBeFalsy ? `${item.key} is falsy` : `${item.key} is truthy`; } return item.key; }; export default function DocsPage() { const translate = useTranslator(); const { upsertSyncEventCallback } = useSyncEvents(); //? JSON import inferred type is deeply readonly with literal-narrowed //? fields; structurally compatible with DocsResult but TS won't accept a //? single `as` cast. The double-cast is the JSON-import escape hatch. // eslint-disable-next-line no-restricted-syntax -- JSON import widening const [docs] = useState(apiDocs as unknown as DocsResult); // luckystack-allow no-as-any: JSON-import widening — the readonly literal type is structurally a DocsResult but TS rejects a single cast const [selectedApi, setSelectedApi] = useState(null); const [selectedSync, setSelectedSync] = useState(null); const [inputData, setInputData] = useState('{}'); const [receiver, setReceiver] = useState(""); const [joinedRoom, setJoinedRoom] = useState(""); const [roomToLeave, setRoomToLeave] = useState(""); const [joinedRooms, setJoinedRooms] = useState([]); const [ignoreSelf, setIgnoreSelf] = useState(false); const [apiResult, setApiResult] = useState(null); const [syncResult, setSyncResult] = useState(null); const [status, setStatus] = useState<'idle' | 'loading' | 'success' | 'error'>('idle'); const selectedPath = useMemo(() => { if (selectedApi) return selectedApi.path; if (selectedSync) return selectedSync.path; return null; }, [selectedApi, selectedSync]); const selectedApiAdditional = selectedApi?.auth.additional ?? []; const selectedApiNeedsLogin = selectedApi?.auth.login === true; const defaultApiLimit = rateLimiting.defaultApiLimit; useEffect(() => { if (!selectedSync) return; const name = buildSyncRequestName(selectedSync); //? Runtime-driven dispatch — the generated `apiTypes` map narrows //? upsertSyncEventCallback's params to a literal-typed shape per route. //? Here `name` is read from the docs JSON at runtime, so we erase via //? a typed local + identifier-as-never instead of an object-literal-as //? cast (banned by consistent-type-assertions). const callbackParams = { name, version: selectedSync.version, callback: ({ clientOutput, serverOutput }: { clientOutput: unknown; serverOutput: unknown }) => { setSyncResult({ status: 'success', clientOutput, serverOutput, }); setStatus('success'); }, }; return upsertSyncEventCallback(callbackParams as never); }, [selectedSync, upsertSyncEventCallback]) const normalizeInputData = () => { setInputData((previous) => { const clean = previous.trim(); if (clean === '') return '{}'; try { return JSON.stringify(JSON.parse(clean), null, 2); } catch { return previous; } }); }; const parseInput = (): Record | null => { try { return JSON.parse(inputData) as Record; } catch { notify.error({ key: 'docs.invalidJsonInput' }); return null; } }; const parseHttpResponse = async (response: Response): Promise => { const responseText = await response.text(); if (!responseText) { return { status: response.ok ? 'success' : 'error', message: response.ok ? 'docs.emptyResponseBody' : 'docs.emptyErrorResponseBody', httpStatus: response.status, }; } try { const parsed: unknown = JSON.parse(responseText); return { ...(parsed !== null && typeof parsed === 'object' ? parsed as Record : {}), httpStatus: response.status, }; } catch { return { status: 'error', message: 'docs.invalidJsonResponse', rawResponse: responseText, httpStatus: response.status, }; } }; const runApiWithSocket = () => { if (!selectedApi) return; const parsedInput = parseInput(); if (!parsedInput) { setStatus('error'); setApiResult({ status: 'error', message: 'docs.invalidJsonInput' }); return; } setStatus('loading'); setApiResult(null); void (async () => { try { const name = buildApiRequestName(selectedApi); //? Runtime-driven dispatch — see the upsertSyncEventCallback note //? above for why we erase via typed local + identifier-as-never //? instead of object-literal-as. The narrowed `OutputForFullName` //? collapses to `never`, so a single `as ApiRunResponse` widens //? without needing a double-cast. const apiParams = { name, version: selectedApi.version, data: parsedInput, disableErrorMessage: true, }; const rawResponse = await apiRequest(apiParams as never); const response = rawResponse as ApiRunResponse; setApiResult(response); setStatus(response.status === 'success' ? 'success' : 'error'); } catch { setApiResult({ status: 'error', message: 'docs.httpApiRequestFailed' }); setStatus('error'); } })(); }; const runApiWithHttp = async () => { if (!selectedApi) return; const parsedInput = parseInput(); if (!parsedInput) { setStatus('error'); setApiResult({ status: 'error', message: 'docs.invalidJsonInput' }); return; } setStatus('loading'); setApiResult(null); try { const routePath = buildApiRoutePath(selectedApi); const method = selectedApi.method.toUpperCase(); let url = `${backendUrl}/${routePath}`; const requestInit: RequestInit = { method, credentials: 'include', }; if (method === 'GET') { const query = new URLSearchParams(); for (const [key, value] of Object.entries(parsedInput)) { query.set(key, typeof value === 'string' ? value : JSON.stringify(value)); } const queryString = query.toString(); if (queryString) { url = `${url}?${queryString}`; } } else { requestInit.headers = { 'Content-Type': 'application/json' }; requestInit.body = JSON.stringify(parsedInput); } const response = await fetch(url, requestInit); const parsedResponse = await parseHttpResponse(response); setApiResult(parsedResponse); setStatus(response.ok ? 'success' : 'error'); } catch (error) { setApiResult({ status: 'error', message: 'docs.httpApiRequestFailed' }); setStatus('error'); console.error('docs http api request failed:', error); } }; const runSyncWithSocket = () => { if (!selectedSync) return; const parsedInput = parseInput(); if (!parsedInput) { setStatus('error'); setSyncResult({ status: 'error', message: 'docs.invalidJsonInput' }); return; } setStatus('loading'); setSyncResult(null); const name = buildSyncRequestName(selectedSync); void (async () => { //? Runtime-driven dispatch — see the apiRequest/upsertSyncEventCallback //? notes above. Same typed-local + identifier-as-never pattern. const syncParams = { name, version: selectedSync.version, data: parsedInput, receiver, ignoreSelf, }; const response = await syncRequest(syncParams as never); if (response.status === 'error') { setSyncResult({ status: 'error', message: response.message || 'docs.httpSyncRequestFailed', errorCode: response.errorCode, errorParams: response.errorParams, httpStatus: response.httpStatus, }); setStatus('error'); return; } setSyncResult(response); setStatus('success'); })(); }; const runSyncWithHttp = async () => { if (!selectedSync) return; const parsedInput = parseInput(); if (!parsedInput) { setStatus('error'); setSyncResult({ status: 'error', message: 'docs.invalidJsonInput' }); return; } setStatus('loading'); setSyncResult(null); const name = buildSyncRequestName(selectedSync); try { const response = await fetch(`${backendUrl}/sync/${name}/${selectedSync.version}`, { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ data: parsedInput, receiver, ignoreSelf, }), }); const parsedResponse = await parseHttpResponse(response); setSyncResult(parsedResponse); setStatus(response.ok ? 'success' : 'error'); } catch (error) { setSyncResult({ status: 'error', message: 'docs.httpSyncRequestFailed', }); setStatus('error'); console.error('docs http sync request failed:', error); } }; const applyRandomPreset = () => { if (selectedApi) { setInputData(JSON.stringify(generateRandomInput(selectedApi.input), null, 2)); return; } if (selectedSync) { setInputData(JSON.stringify(generateRandomInput(selectedSync.clientInput), null, 2)); } }; const joinSelectedRoom = async () => { const room = joinedRoom.trim(); if (room === '') { notify.error({ key: 'docs.roomCodeRequired' }); return; } const joined = await joinRoom(room); console.log(joined) if (joined) { setJoinedRooms((previous) => previous.includes(room) ? previous : [...previous, room]); setRoomToLeave(room); notify.success({ key: 'docs.joinedRoom' }); } else { notify.error({ key: 'docs.failedToJoinRoom' }); } }; const leaveSelectedRoom = async () => { const room = roomToLeave.trim(); if (!room) { notify.error({ key: 'docs.roomCodeRequired' }); return; } const left = await leaveRoom(room); if (left) { setJoinedRooms((previous) => previous.filter((r) => r !== room)); notify.success({ key: 'docs.leftRoom' }); } else { notify.error({ key: 'docs.failedToLeaveRoom' }); } }; if (!docs) return
{translate({ key: 'docs.failedToLoadDocumentation' })}
; const rateLimitText = selectedApi ? getRateLimitText({ selectedApiRateLimit: selectedApi.rateLimit, defaultApiLimit, translate, }) : ''; return (
{/* ── Sidebar ── */}
{/* Sticky sidebar header */}

{translate({ key: 'docs.documentation' })}

{translate({ key: 'docs.joinedRooms' })}
{joinedRooms.length === 0 && (
{translate({ key: 'docs.noRoomsJoined' })}
)} {joinedRooms.map((room) => (
{room}
))}
{/* APIs section */}
{translate({ key: 'docs.apisSmall' })}
{Object.entries(docs.apis).map(([page, apis]) => (
{page}
{apis.map((api) => ( ))}
))}
{/* Syncs section */}
{translate({ key: 'docs.syncsSmall' })}
{Object.entries(docs.syncs).map(([page, syncs]) => (
{page}
{syncs.map((sync) => ( ))}
))}
{/* ── Main content ── */}
{!selectedPath && (
{translate({ key: 'docs.doc' })}
{translate({ key: 'docs.selectApiOrSync' })}
)} {selectedApi && (
{/* Header card */}
{selectedApi.method}

{selectedApi.name}

{translate({ key: 'docs.fetchRequestExample' })}
{buildApiFetchExample(selectedApi, inputData)}
{translate({ key: 'docs.socketRequestExample' })}
{buildApiSocketExample(selectedApi, inputData)}
{selectedApi.description && (
{selectedApi.description}
)} {/* Status badge — inline in header */}
{translate({ key: 'docs.status' })} {status}
{/* Meta row */}
{/* Rate limit */}
{translate({ key: 'docs.rateLimit' })}
{rateLimitText}
{/* Auth */}
{translate({ key: 'docs.auth' })}
{selectedApiNeedsLogin ? translate({ key: 'docs.loginRequired' }) : translate({ key: 'docs.loginOptional' })}
{/* Additional permissions */}
{translate({ key: 'docs.additionalPermissions' })}
{selectedApiAdditional.length === 0 ?
{translate({ key: 'docs.none' })}
: (
{selectedApiAdditional.map((item) => { const label = getAdditionalPermissionLabel(item); return (
{label}
); })}
)}
{/* Type schema cards */}
{translate({ key: 'docs.input' })}
{formatTypeText(selectedApi.input)}
{translate({ key: 'docs.output' })}
{formatTypeText(selectedApi.output)}
{/* Run panel */}
{translate({ key: 'docs.requestPayload' })}