import "../../dialect-helpers-DRI5pyY3.mjs";
import "../../base64-CmWvODNW.mjs";
import "../../types-CuW0zWDA.mjs";
import { t as RedirectRepository } from "../../redirect-IyfNirgS.mjs";
import { a as setCachedRedirects, i as matchCachedPatterns, n as getCachedRedirects } from "../../cache-CEBAZjir.mjs";
import { a as getDb } from "../../loader-CB6YHeul.mjs";
import { n as isTerminalStatus } from "../../status-CqJQX1QN.mjs";
import { defineMiddleware } from "astro:middleware";

//#region src/astro/middleware/redirect.ts
/**
* Redirect middleware
*
* Intercepts incoming requests and checks for matching redirect rules.
* Runs after runtime init (needs db) but before setup/auth (should handle
* ALL routes, including public ones, and should be fast).
*
* Skip paths:
* - /_emdash/* (admin UI, API routes, auth endpoints)
* - /_image (Astro image optimization)
* - Static assets (files with extensions)
*
* 404 logging happens post-response: if next() returns 404 and the path
* wasn't already matched by a redirect, log it.
*/
/** Paths that should never be intercepted by redirects */
const SKIP_PREFIXES = ["/_emdash", "/_image"];
/** Static asset extensions -- don't redirect file requests */
const ASSET_EXTENSION = /\.\w{1,10}$/;
function isRedirectCode(code) {
	return code === 301 || code === 302 || code === 303 || code === 307 || code === 308;
}
const onRequest = defineMiddleware(async (context, next) => {
	const { pathname } = context.url;
	if (SKIP_PREFIXES.some((prefix) => pathname.startsWith(prefix))) return next();
	if (ASSET_EXTENSION.test(pathname)) return next();
	let db = context.locals.emdash?.db;
	if (!db) try {
		db = await getDb();
	} catch {
		return next();
	}
	try {
		const repo = new RedirectRepository(db);
		let cached = getCachedRedirects();
		if (!cached) cached = setCachedRedirects(await repo.findAllEnabled());
		let exact = cached.exact.get(pathname);
		if (!exact && pathname.length > 1) {
			const alt = pathname.endsWith("/") ? pathname.slice(0, -1) : `${pathname}/`;
			exact = cached.exact.get(alt);
		}
		if (exact) {
			if (isTerminalStatus(exact.type)) {
				repo.recordHit(exact.id).catch(() => {});
				return new Response(null, { status: exact.type });
			}
			const dest = exact.destination;
			if (dest.startsWith("//") || dest.startsWith("/\\")) return next();
			repo.recordHit(exact.id).catch(() => {});
			const code = isRedirectCode(exact.type) ? exact.type : 301;
			return context.redirect(dest, code);
		}
		const patternMatch = matchCachedPatterns(cached.patterns, pathname);
		if (patternMatch) {
			const { redirect, destination } = patternMatch;
			if (isTerminalStatus(redirect.type)) {
				repo.recordHit(redirect.id).catch(() => {});
				return new Response(null, { status: redirect.type });
			}
			if (destination.startsWith("//") || destination.startsWith("/\\")) return next();
			repo.recordHit(redirect.id).catch(() => {});
			const code = isRedirectCode(redirect.type) ? redirect.type : 301;
			return context.redirect(destination, code);
		}
		const response = await next();
		if (response.status === 404) {
			const referrer = context.request.headers.get("referer") ?? null;
			const userAgent = context.request.headers.get("user-agent") ?? null;
			repo.log404({
				path: pathname,
				referrer,
				userAgent
			}).catch(() => {});
		}
		return response;
	} catch {
		return next();
	}
});

//#endregion
export { onRequest };
//# sourceMappingURL=redirect.mjs.map