Spaces:
Runtime error
Runtime error
| import { NextRequest, NextResponse } from 'next/server' | |
| import { config } from '@/lib/config' | |
| import { requireRole } from '@/lib/auth' | |
| import { readLimiter } from '@/lib/rate-limit' | |
| import { buildLinkGraph, extractWikiLinks } from '@/lib/memory-utils' | |
| import { readFile } from 'fs/promises' | |
| import { join, basename, extname } from 'path' | |
| import { logger } from '@/lib/logger' | |
| const MEMORY_PATH = config.memoryDir | |
| export async function GET(request: NextRequest) { | |
| const auth = requireRole(request, 'viewer') | |
| if ('error' in auth) return NextResponse.json({ error: auth.error }, { status: auth.status }) | |
| const limited = readLimiter(request) | |
| if (limited) return limited | |
| if (!MEMORY_PATH) { | |
| return NextResponse.json({ error: 'Memory directory not configured' }, { status: 500 }) | |
| } | |
| const { searchParams } = new URL(request.url) | |
| const filePath = searchParams.get('file') | |
| try { | |
| if (filePath) { | |
| // Return links for a specific file | |
| const fullPath = join(MEMORY_PATH, filePath) | |
| // Basic path traversal check | |
| if (!fullPath.startsWith(MEMORY_PATH)) { | |
| return NextResponse.json({ error: 'Invalid path' }, { status: 400 }) | |
| } | |
| const content = await readFile(fullPath, 'utf-8') | |
| const links = extractWikiLinks(content) | |
| // Also find backlinks from the full graph | |
| const graph = await buildLinkGraph(MEMORY_PATH) | |
| const node = graph.nodes[filePath] | |
| const incoming = node?.incoming ?? [] | |
| const outgoing = node?.outgoing ?? [] | |
| return NextResponse.json({ | |
| file: filePath, | |
| wikiLinks: links, | |
| outgoing, | |
| incoming, | |
| }) | |
| } | |
| // Return full link graph | |
| const graph = await buildLinkGraph(MEMORY_PATH) | |
| // Serialize for the frontend (strip wikiLinks detail for the full graph) | |
| const nodes = Object.values(graph.nodes).map((n) => ({ | |
| path: n.path, | |
| name: n.name, | |
| outgoing: n.outgoing, | |
| incoming: n.incoming, | |
| linkCount: n.outgoing.length + n.incoming.length, | |
| hasSchema: n.schema !== null, | |
| })) | |
| return NextResponse.json({ | |
| nodes, | |
| totalFiles: graph.totalFiles, | |
| totalLinks: graph.totalLinks, | |
| orphans: graph.orphans, | |
| }) | |
| } catch (err) { | |
| logger.error({ err }, 'Memory links API error') | |
| return NextResponse.json({ error: 'Internal server error' }, { status: 500 }) | |
| } | |
| } | |