+server.ts

 1import { json } from '@sveltejs/kit';
 2import { getRepoDir } from '$lib/server/vcs';
 3import { highlightLines } from '$lib/server/highlighter';
 4import { readFile } from 'fs/promises';
 5import { join } from 'path';
 6import type { RequestHandler } from './$types.ts';
 7
 8function getLanguage(filePath: string): string {
 9	const ext = filePath.split('.').pop()?.toLowerCase() || '';
10	// Simplified — the full map is in git.ts but we just need the extension here
11	const map: Record<string, string> = {
12		ts: 'typescript', tsx: 'tsx', js: 'javascript', jsx: 'jsx',
13		py: 'python', rb: 'ruby', go: 'go', rs: 'rust', java: 'java',
14		swift: 'swift', kt: 'kotlin', cs: 'csharp', php: 'php',
15		css: 'css', scss: 'scss', html: 'html', svelte: 'svelte', vue: 'vue',
16		json: 'json', yaml: 'yaml', yml: 'yaml', md: 'markdown',
17		sh: 'bash', sql: 'sql', c: 'c', cpp: 'cpp', h: 'c', hpp: 'cpp',
18		m: 'objective-c', dart: 'dart', lua: 'lua', r: 'r', scala: 'scala',
19		ex: 'elixir', hs: 'haskell', toml: 'toml', xml: 'xml'
20	};
21	return map[ext] || 'text';
22}
23
24export const GET: RequestHandler = async ({ url }) => {
25	try {
26		const filePath = url.searchParams.get('file');
27		const startLine = parseInt(url.searchParams.get('start') || '1', 10);
28		const endLine = parseInt(url.searchParams.get('end') || '20', 10);
29
30		if (!filePath) {
31			return json({ error: 'file parameter required' }, { status: 400 });
32		}
33
34		const fullPath = join(getRepoDir(), filePath);
35		const content = await readFile(fullPath, 'utf-8');
36		const allLines = content.split('\n');
37		const language = getLanguage(filePath);
38
39		// Highlight the full file
40		const highlighted = await highlightLines(content, language);
41
42		// Extract requested range (1-indexed)
43		const start = Math.max(1, startLine);
44		const end = Math.min(allLines.length, endLine);
45		const lines = [];
46
47		for (let i = start; i <= end; i++) {
48			lines.push({
49				type: 'context' as const,
50				content: allLines[i - 1],
51				html: highlighted.get(i),
52				oldNumber: i,
53				newNumber: i
54			});
55		}
56
57		return json({ lines, totalLines: allLines.length });
58	} catch (err) {
59		return json({ error: String(err) }, { status: 500 });
60	}
61};