Files
pastel-ui/app/api/pastel/[...path]/route.ts
valknarness ea44b592dd fix: await params in API route handlers for Next.js 16 compatibility
In Next.js 16, route handler params are now async Promises.
Updated all HTTP method handlers (GET, POST, PUT, DELETE, PATCH)
to properly await the params before accessing path segments.

This fixes the build error:
"Type 'Promise<{ path: string[] }>' is not assignable to type '{ path: string[] }'"

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 16:10:30 +01:00

123 lines
3.2 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
/**
* API Proxy Route for Pastel API
*
* This proxy allows runtime configuration of the Pastel API URL
* without rebuilding the Docker image. The API URL is read from
* the server-side environment variable at runtime.
*
* Client requests go to: /api/pastel/*
* Proxied to: PASTEL_API_URL/*
*/
const PASTEL_API_URL = process.env.PASTEL_API_URL || 'http://localhost:3001';
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }
) {
const { path } = await params;
return proxyRequest(request, path, 'GET');
}
export async function POST(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }
) {
const { path } = await params;
return proxyRequest(request, path, 'POST');
}
export async function PUT(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }
) {
const { path } = await params;
return proxyRequest(request, path, 'PUT');
}
export async function DELETE(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }
) {
const { path } = await params;
return proxyRequest(request, path, 'DELETE');
}
export async function PATCH(
request: NextRequest,
{ params }: { params: Promise<{ path: string[] }> }
) {
const { path } = await params;
return proxyRequest(request, path, 'PATCH');
}
async function proxyRequest(
request: NextRequest,
pathSegments: string[],
method: string
) {
try {
const path = pathSegments.join('/');
const targetUrl = `${PASTEL_API_URL}/api/v1/${path}`;
// Get request body if present
const body = method !== 'GET' && method !== 'DELETE'
? await request.text()
: undefined;
// Forward the request to the Pastel API
const response = await fetch(targetUrl, {
method,
headers: {
'Content-Type': 'application/json',
// Forward relevant headers
...(request.headers.get('accept') && {
'Accept': request.headers.get('accept')!
}),
},
body,
});
// Get response data
const data = await response.text();
// Return response with same status and headers
return new NextResponse(data, {
status: response.status,
headers: {
'Content-Type': response.headers.get('content-type') || 'application/json',
// Add CORS headers if needed
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
} catch (error) {
console.error('Proxy error:', error);
return NextResponse.json(
{
success: false,
error: {
code: 'PROXY_ERROR',
message: error instanceof Error ? error.message : 'Failed to proxy request',
},
},
{ status: 500 }
);
}
}
// Handle OPTIONS requests for CORS
export async function OPTIONS() {
return new NextResponse(null, {
status: 204,
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
},
});
}