- Changed import path for routes in next-env.d.ts - Updated dependencies in package.json, including @kevisual/api and @kevisual/query - Added delete functionality in QueryView component - Modified run function in studio to accept a custom type - Enhanced searchRoutes function in studio store with Fuse.js for better filtering - Updated DataItemForm to use QueryRouterServer from the browser - Added dynamic URL handling in query module - Improved proxy request handling based on app key - Adjusted TypeScript configuration for stricter checks - Created a new page component for dynamic routing - Introduced a new Toaster component for notifications
72 lines
2.4 KiB
TypeScript
72 lines
2.4 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server';
|
||
|
||
const API_URL = process.env.API_URL || 'http://localhost:51515';
|
||
console.log(`Proxy API_URL: ${API_URL}`);
|
||
/**
|
||
* 通用代理函数
|
||
* @param request 原始请求
|
||
* @param targetHost 目标服务器地址(如 http://localhost:51515)
|
||
* @returns NextResponse 代理响应
|
||
*/
|
||
async function proxyRequest(request: NextRequest, targetHost: string): Promise<NextResponse> {
|
||
const { pathname } = request.nextUrl;
|
||
const targetUrl = new URL(pathname + request.nextUrl.search, targetHost);
|
||
|
||
try {
|
||
console.log(`Proxying request to: ${targetUrl.toString()}`);
|
||
const response = await fetch(targetUrl.toString(), {
|
||
method: request.method,
|
||
headers: {
|
||
// 复制原始请求的所有头部
|
||
...Object.fromEntries(request.headers.entries()),
|
||
// 确保转发 cookie
|
||
cookie: request.headers.get('cookie') || '',
|
||
},
|
||
body: request.method !== 'GET' && request.method !== 'HEAD' ? await request.text() : undefined,
|
||
// 包含 cookie 的请求
|
||
credentials: 'include',
|
||
});
|
||
|
||
// 创建响应,保留原始响应的所有头部(包括 Set-Cookie)
|
||
const responseHeaders = new Headers(response.headers);
|
||
|
||
return new NextResponse(response.body, {
|
||
status: response.status,
|
||
statusText: response.statusText,
|
||
headers: responseHeaders,
|
||
});
|
||
} catch (error) {
|
||
console.error('Proxy error:', error);
|
||
return NextResponse.json(
|
||
{ error: 'Proxy request failed' },
|
||
{ status: 502 }
|
||
);
|
||
}
|
||
}
|
||
|
||
export async function proxy(request: NextRequest) {
|
||
const { pathname } = request.nextUrl;
|
||
const method = request.method;
|
||
const [username, appKey] = pathname.split('/').filter(Boolean);
|
||
const searchParams = request.nextUrl.searchParams;
|
||
const path = searchParams.get('path') || '';
|
||
// 代理 /api 请求
|
||
if (pathname.startsWith('/api')) {
|
||
return proxyRequest(request, API_URL);
|
||
}
|
||
// 代理 /root/home 或 /root/home/ 请求 (第二个路径段后可以为空或以 / 结尾)
|
||
if (pathname.startsWith('/root') && appKey !== 'v1') {
|
||
return proxyRequest(request, API_URL);
|
||
}
|
||
if (pathname.startsWith('/root') && path && appKey === 'v1') {
|
||
return proxyRequest(request, API_URL);
|
||
}
|
||
|
||
return NextResponse.next();
|
||
}
|
||
|
||
export const config = {
|
||
matcher: ['/api/:path*', '/root/:segment/:path*'],
|
||
};
|
||
|
||
export default proxy; |