site-panzai/node_modules/nitropack/dist/runtime/internal/route-rules.mjs
2026-11-13 13:57:04 +01:00

85 lines
2.5 KiB
JavaScript

import defu from "defu";
import {
createError,
eventHandler,
proxyRequest,
sendRedirect,
setHeaders
} from "h3";
import { createRouter as createRadixRouter, toRouteMatcher } from "radix3";
import { getQuery, joinURL, withQuery, withoutBase } from "ufo";
import { useRuntimeConfig } from "./config.mjs";
import {
isPathInScope,
isTargetInScope,
resolveRedirectTarget
} from "./route-rules-utils.mjs";
const config = useRuntimeConfig();
const _routeRulesMatcher = toRouteMatcher(
createRadixRouter({ routes: config.nitro.routeRules })
);
export function createRouteRulesHandler(ctx) {
return eventHandler((event) => {
const routeRules = getRouteRules(event);
if (routeRules.headers) {
setHeaders(event, routeRules.headers);
}
if (routeRules.redirect) {
const target = resolveRedirectTarget(
event.path,
routeRules.redirect.to,
routeRules.redirect._redirectStripBase
);
if (target === void 0) {
throw createError({ statusCode: 400 });
}
return sendRedirect(event, target, routeRules.redirect.statusCode);
}
if (routeRules.proxy) {
const target = resolveRuleTarget(
event,
routeRules.proxy.to,
routeRules.proxy._proxyStripBase
);
return proxyRequest(event, target, {
fetch: ctx.localFetch,
...routeRules.proxy
});
}
});
}
function resolveRuleTarget(event, to, stripBase) {
if (!to.endsWith("/**")) {
if (event.path.includes("?")) {
return withQuery(to, getQuery(event.path));
}
return to;
}
const targetBase = to.slice(0, -3);
let targetPath = event.path;
if (stripBase) {
if (!isPathInScope(event.path.split("?")[0], stripBase)) {
throw createError({ statusCode: 400 });
}
targetPath = withoutBase(targetPath, stripBase);
} else if (targetPath.startsWith("//")) {
targetPath = targetPath.replace(/^\/+/, "/");
}
const target = joinURL(targetBase, targetPath);
if (!isTargetInScope(target, targetBase)) {
throw createError({ statusCode: 400 });
}
return target;
}
export function getRouteRules(event) {
event.context._nitro = event.context._nitro || {};
if (!event.context._nitro.routeRules) {
event.context._nitro.routeRules = getRouteRulesForPath(
withoutBase(event.path.split("?")[0], useRuntimeConfig().app.baseURL)
);
}
return event.context._nitro.routeRules;
}
export function getRouteRulesForPath(path) {
return defu({}, ..._routeRulesMatcher.matchAll(path).reverse());
}