// src/routes/api/[...path]/+server.ts import { BACKEND_API_URL } from '$lib/server/config'; import { json, error } from '@sveltejs/kit'; // import type { RequestHandler } from './$types'; // Helper function to handle both JSON and file responses async function handleResponse(response: Response) { if (!response.ok) { throw error(response.status, await response.text()); } const contentType = response.headers.get('Content-Type') || ''; if (contentType.includes('application/json')) { // Handle JSON response const data = await response.json(); return json(data); } else { // Handle file or other non-JSON response const responseBody = await response.arrayBuffer(); return new Response(responseBody, { status: response.status, headers: { 'Content-Type': contentType, 'Content-Disposition': response.headers.get('Content-Disposition') || '', 'Content-Length': response.headers.get('Content-Length') || '' } }); } } // Shared function to prepare the request with authentication function prepareRequest(locals: App.Locals, request: Request) { const token = locals.authToken || 'server-default-token'; const headers = new Headers({ Authorization: `Bearer ${token}` }); // Forward important headers from the original request const contentType = request.headers.get('Content-Type'); if (contentType) headers.set('Content-Type', contentType); const accept = request.headers.get('Accept'); if (accept) headers.set('Accept', accept); return headers; } // GET handler export const GET: RequestHandler = async ({ params, locals, fetch, request, url }) => { try { const path = params.path; const queryString = url.search; const backendUrl = `${BACKEND_API_URL}/${path}${queryString}`; const headers = prepareRequest(locals, request); const response = await fetch(backendUrl, { method: 'GET', headers }); return handleResponse(response); } catch (e) { console.error('API proxy error (GET):', e); throw error(500, 'Failed to fetch from API'); } }; // POST handler export const POST: RequestHandler = async ({ params, locals, fetch, request, url }) => { try { const path = params.path; const queryString = url.search; const backendUrl = `${BACKEND_API_URL}/${path}${queryString}`; const headers = prepareRequest(locals, request); // Get the request body const body = await request.arrayBuffer(); const response = await fetch(backendUrl, { method: 'POST', headers, body }); return handleResponse(response); } catch (e) { console.error('API proxy error (POST):', e); throw error(500, 'Failed to post to API'); } }; // PATCH handler export const PATCH: RequestHandler = async ({ params, locals, fetch, request, url }) => { try { const path = params.path; const queryString = url.search; const backendUrl = `${BACKEND_API_URL}/${path}${queryString}`; const headers = prepareRequest(locals, request); // Get the request body const body = await request.arrayBuffer(); const response = await fetch(backendUrl, { method: 'PATCH', headers, body }); return handleResponse(response); } catch (e) { console.error('API proxy error (PATCH):', e); throw error(500, 'Failed to update API resource'); } }; // DELETE handler export const DELETE: RequestHandler = async ({ params, locals, fetch, request, url }) => { try { const path = params.path; const queryString = url.search; const backendUrl = `${BACKEND_API_URL}/${path}${queryString}`; const headers = prepareRequest(locals, request); // DELETE may or may not have a body let options: RequestInit = { method: 'DELETE', headers }; // Add body if the request has one if ( request.headers.get('Content-Length') && parseInt(request.headers.get('Content-Length') || '0') > 0 ) { options.body = await request.arrayBuffer(); } const response = await fetch(backendUrl, options); return response; } catch (e) { console.error('API proxy error (DELETE):', e); throw error(500, 'Failed to delete API resource'); } };