import type { z } from 'zod' import { parsePath, withQuery } from 'ufo' import type { LinkSchema } from '@/schemas/link' export default eventHandler(async (event) => { const { pathname: slug } = parsePath(event.path.replace(/^\/|\/$/g, '')) // remove leading and trailing slashes const { slugRegex, reserveSlug } = useAppConfig(event) const { homeURL, linkCacheTtl, redirectWithQuery, caseSensitive } = useRuntimeConfig(event) const { cloudflare } = event.context if (event.path === '/' && homeURL) return sendRedirect(event, homeURL) if (slug && !reserveSlug.includes(slug) && slugRegex.test(slug) && cloudflare) { const { KV } = cloudflare.env let link: z.infer | null = null const getLink = async (key: string) => await KV.get(`link:${key}`, { type: 'json', cacheTtl: linkCacheTtl }) link = await getLink(slug) // fallback to lowercase slug if caseSensitive is false and the slug is not found const lowerCaseSlug = slug.toLowerCase() if (!caseSensitive && !link && lowerCaseSlug !== slug) { console.log('lowerCaseSlug fallback:', `slug:${slug} lowerCaseSlug:${lowerCaseSlug}`) link = await getLink(lowerCaseSlug) } if (link) { event.context.link = link try { await useAccessLog(event) } catch (error) { console.error('Failed write access log:', error) } const target = redirectWithQuery ? withQuery(link.url, getQuery(event)) : link.url return sendRedirect(event, target, +useRuntimeConfig(event).redirectStatusCode) } } })