fix(proxy): separate upstream target resolution from proxy dispatch and add site-level proxy URLs
This commit is contained in:
@@ -73,6 +73,7 @@ describe('executeEndpointFlow', () => {
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(dispatchRequest).toHaveBeenCalledTimes(1);
|
||||
expect(dispatchRequest.mock.calls[0]?.[1]).toBe('https://example.com/v1/responses');
|
||||
expect(fetchMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
@@ -219,22 +220,6 @@ describe('executeEndpointFlow', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('uses proxyUrl for the default fetch path when no dispatch hook is provided', async () => {
|
||||
fetchMock.mockResolvedValueOnce(toUndiciResponse(new Response(JSON.stringify({ ok: true }), {
|
||||
status: 200,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
})));
|
||||
|
||||
await executeEndpointFlow({
|
||||
siteUrl: 'https://example.com',
|
||||
proxyUrl: 'https://proxy.internal/base',
|
||||
endpointCandidates: ['responses'],
|
||||
buildRequest: () => requestFor('/v1/responses'),
|
||||
});
|
||||
|
||||
expect(fetchMock.mock.calls[0]?.[0]).toBe('https://proxy.internal/base/v1/responses');
|
||||
});
|
||||
|
||||
it('returns normalized final error when all endpoints fail', async () => {
|
||||
fetchMock.mockResolvedValueOnce(toUndiciResponse(new Response(JSON.stringify({
|
||||
error: { message: 'upstream_error', type: 'upstream_error' },
|
||||
|
||||
@@ -59,7 +59,6 @@ export function withUpstreamPath(path: string, message: string): string {
|
||||
|
||||
type ExecuteEndpointFlowInput = {
|
||||
siteUrl: string;
|
||||
proxyUrl?: string | null;
|
||||
endpointCandidates: UpstreamEndpoint[];
|
||||
buildRequest: (endpoint: UpstreamEndpoint, endpointIndex: number) => BuiltEndpointRequest;
|
||||
dispatchRequest?: (
|
||||
@@ -73,12 +72,6 @@ type ExecuteEndpointFlowInput = {
|
||||
onAttemptSuccess?: (ctx: EndpointAttemptSuccessContext) => void | Promise<void>;
|
||||
};
|
||||
|
||||
function buildAbsoluteUrl(base: string, path: string): string {
|
||||
const normalizedBase = base.replace(/\/+$/, '');
|
||||
const normalizedPath = path.replace(/^\/+/, '');
|
||||
return normalizedPath ? `${normalizedBase}/${normalizedPath}` : normalizedBase;
|
||||
}
|
||||
|
||||
export async function executeEndpointFlow(input: ExecuteEndpointFlowInput): Promise<EndpointFlowResult> {
|
||||
const endpointCount = input.endpointCandidates.length;
|
||||
if (endpointCount <= 0) {
|
||||
@@ -96,10 +89,7 @@ export async function executeEndpointFlow(input: ExecuteEndpointFlowInput): Prom
|
||||
for (let endpointIndex = 0; endpointIndex < endpointCount; endpointIndex += 1) {
|
||||
const endpoint = input.endpointCandidates[endpointIndex] as UpstreamEndpoint;
|
||||
const request = input.buildRequest(endpoint, endpointIndex);
|
||||
const defaultTarget = buildUpstreamUrl(input.siteUrl, request.path);
|
||||
const targetUrl = input.proxyUrl
|
||||
? buildAbsoluteUrl(input.proxyUrl, request.path)
|
||||
: defaultTarget;
|
||||
const targetUrl = buildUpstreamUrl(input.siteUrl, request.path);
|
||||
|
||||
let response = input.dispatchRequest
|
||||
? await input.dispatchRequest(request, targetUrl)
|
||||
|
||||
Reference in New Issue
Block a user