Files
web/app/api/web/revalidate/route.ts
2025-02-25 10:37:32 +00:00

145 lines
4.2 KiB
TypeScript

import { revalidateTag } from "next/cache"
import { headers } from "next/headers"
import { z } from "zod"
import { Lang } from "@/constants/languages"
import { env } from "@/env/server"
import { badRequest, internalServerError } from "@/server/errors/next"
import { affix as breadcrumbsAffix } from "@/server/routers/contentstack/breadcrumbs/utils"
import { languageSwitcherAffix } from "@/server/routers/contentstack/languageSwitcher/utils"
import { affix as metadataAffix } from "@/server/routers/contentstack/metadata/utils"
import { affix as pageSettingsAffix } from "@/server/routers/contentstack/pageSettings/utils"
import {
generateRefsResponseTag,
generateRefTag,
generateTag,
} from "@/utils/generateTag"
import type { NextRequest } from "next/server"
const validateJsonBody = z.object({
data: z.object({
content_type: z.object({
uid: z.string(),
}),
entry: z.object({
breadcrumbs: z
.object({
title: z.string(),
})
.optional(),
locale: z.nativeEnum(Lang),
publish_details: z.object({ locale: z.nativeEnum(Lang) }).optional(),
uid: z.string(),
url: z.string().optional(),
page_settings: z
.object({
hide_booking_widget: z.boolean(),
})
.optional(),
}),
}),
})
export async function POST(request: NextRequest) {
try {
const headersList = headers()
const secret = headersList.get("x-revalidate-secret")
if (secret !== env.REVALIDATE_SECRET) {
console.error(`Invalid Secret`)
console.error({ secret })
return badRequest({
now: Date.now(),
revalidated: false,
})
}
const data = await request.json()
const validatedData = validateJsonBody.safeParse(data)
if (!validatedData.success) {
console.error("Bad validation for `validatedData`")
console.error(validatedData.error)
return internalServerError({ revalidated: false, now: Date.now() })
}
const {
data: {
data: { content_type, entry },
},
} = validatedData
// The publish_details.locale is the locale that the entry is published in, regardless if it is "localized" or not
const entryLocale = entry.publish_details?.locale ?? entry.locale
const refsTag = generateRefsResponseTag(entryLocale, entry.uid)
const contentEntryTag = generateRefsResponseTag(
entryLocale,
content_type.uid
)
const refTag = generateRefTag(entryLocale, content_type.uid, entry.uid)
const tag = generateTag(entryLocale, entry.uid)
const languageSwitcherTag = generateTag(
entryLocale,
entry.uid,
languageSwitcherAffix
)
const metadataTag = generateTag(entryLocale, entry.uid, metadataAffix)
console.info(`Revalidating refsTag: ${refsTag}`)
revalidateTag(refsTag)
console.info(`Revalidating refTag: ${refTag}`)
revalidateTag(refTag)
console.info(`Revalidating tag: ${tag}`)
revalidateTag(tag)
console.info(`Revalidating language switcher tag: ${languageSwitcherTag}`)
revalidateTag(languageSwitcherTag)
console.info(`Revalidating metadataTag: ${metadataTag}`)
revalidateTag(metadataTag)
console.info(`Revalidating contentEntryTag: ${contentEntryTag}`)
revalidateTag(contentEntryTag)
if (entry.breadcrumbs) {
const breadcrumbsRefsTag = generateRefsResponseTag(
entryLocale,
entry.uid,
breadcrumbsAffix
)
const breadcrumbsTag = generateTag(
entryLocale,
entry.uid,
breadcrumbsAffix
)
console.info(`Revalidating breadcrumbsRefsTag: ${breadcrumbsRefsTag}`)
revalidateTag(breadcrumbsRefsTag)
console.info(`Revalidating breadcrumbsTag: ${breadcrumbsTag}`)
revalidateTag(breadcrumbsTag)
}
if (entry.page_settings) {
const pageSettingsTag = generateTag(
entryLocale,
entry.uid,
pageSettingsAffix
)
console.info(`Revalidating pageSettingsTag: ${pageSettingsTag}`)
revalidateTag(pageSettingsTag)
}
return Response.json({ revalidated: true, now: Date.now() })
} catch (error) {
console.error("Failed to revalidate tag(s)")
console.error(error)
return internalServerError({ revalidated: false, now: Date.now() })
}
}