/** * API endpoint for listing files and directories in a repository */ import { json, error } from '@sveltejs/kit'; import type { RequestHandler } from './$types'; import { FileManager } from '$lib/services/git/file-manager.js'; import { MaintainerService } from '$lib/services/nostr/maintainer-service.js'; import { DEFAULT_NOSTR_RELAYS } from '$lib/config.js'; import { nip19 } from 'nostr-tools'; import { requireNpubHex } from '$lib/utils/npub-utils.js'; import { handleApiError, handleValidationError, handleNotFoundError, handleAuthorizationError } from '$lib/utils/error-handler.js'; const repoRoot = process.env.GIT_REPO_ROOT || '/repos'; const fileManager = new FileManager(repoRoot); const maintainerService = new MaintainerService(DEFAULT_NOSTR_RELAYS); export const GET: RequestHandler = async ({ params, url, request }) => { const { npub, repo } = params; const ref = url.searchParams.get('ref') || 'HEAD'; const path = url.searchParams.get('path') || ''; const userPubkey = url.searchParams.get('userPubkey') || request.headers.get('x-user-pubkey'); if (!npub || !repo) { return handleValidationError('Missing npub or repo parameter', { operation: 'listFiles' }); } try { if (!fileManager.repoExists(npub, repo)) { return handleNotFoundError('Repository not found', { operation: 'listFiles', npub, repo }); } // Check repository privacy let repoOwnerPubkey: string; try { repoOwnerPubkey = requireNpubHex(npub); } catch { return handleValidationError('Invalid npub format', { operation: 'listFiles', npub }); } const canView = await maintainerService.canView(userPubkey || null, repoOwnerPubkey, repo); if (!canView) { return handleAuthorizationError('This repository is private. Only owners and maintainers can view it.', { operation: 'listFiles', npub, repo }); } const files = await fileManager.listFiles(npub, repo, ref, path); return json(files); } catch (err) { return handleApiError(err, { operation: 'listFiles', npub, repo, path, ref }, 'Failed to list files'); } };