UNPKG

fumadocs-openapi

Version:

Generate MDX docs for your OpenAPI spec

77 lines (76 loc) 2.94 kB
const keys = ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'HEAD']; export function createProxy(options = {}) { const { allowedOrigins, allowedUrls, filterRequest = (req) => { return (!allowedUrls || allowedUrls.some((item) => req.url.startsWith(item))); }, overrides, } = options; const handlers = {}; async function handler(req) { const searchParams = new URL(req.url).searchParams; const url = searchParams.get('url'); if (!url) return Response.json('[Proxy] A `url` query parameter is required for proxy url', { status: 400, }); const parsedUrl = URL.parse(url); if (!parsedUrl) return Response.json('[Proxy] Invalid `url` parameter value.', { status: 400, }); if (allowedOrigins && !allowedOrigins.includes(parsedUrl.origin)) { return Response.json(`[Proxy] The origin "${parsedUrl.origin}" is not allowed.`, { status: 400, }); } const contentLength = req.headers.get('content-length'); const hasBody = contentLength && parseInt(contentLength) > 0; let proxied = new Request(parsedUrl, { method: req.method, cache: 'no-cache', headers: req.headers, body: hasBody && ['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method.toUpperCase()) ? await req.arrayBuffer() : undefined, }); if (overrides?.request) { proxied = overrides.request(proxied); } if (!filterRequest(proxied)) { return Response.json('[Proxy] The proxied request is not allowed', { status: 403, }); } proxied.headers.forEach((_value, originalKey) => { const key = originalKey.toLowerCase(); if (key === 'origin') { proxied.headers.delete(originalKey); } }); let res = await fetch(proxied).catch((e) => new Error(e.toString())); if (res instanceof Error) { return Response.json(`[Proxy] Failed to proxy request: ${res.message}`, { status: 500, }); } if (overrides?.response) { res = overrides.response(res); } const headers = new Headers(res.headers); headers.forEach((_value, originalKey) => { const key = originalKey.toLowerCase(); if (key.startsWith('access-control-') || key === 'content-encoding') { headers.delete(originalKey); } }); headers.set('X-Forwarded-Host', res.url); return new Response(res.body, { status: res.status, statusText: res.statusText, headers, }); } for (const key of keys) { handlers[key] = handler; } return handlers; }