diff --git a/app/api/web/revalidate/route.ts b/app/api/web/revalidate/route.ts index 227c11946..723f72649 100644 --- a/app/api/web/revalidate/route.ts +++ b/app/api/web/revalidate/route.ts @@ -1,30 +1,44 @@ import { revalidateTag } from "next/cache" +import { headers } from "next/headers" import { NextRequest } from "next/server" +import { z } from "zod" +import { Lang } from "@/constants/languages" import { env } from "@/env/server" +import { internalServerError } from "@/server/errors/next" + +import { + generateRefsResponseTag, + generateRefTag, + generateTag, +} from "@/utils/generateTag" + +const validateJsonBody = z.object({ + api_key: z.string(), + module: z.string(), + + data: z.object({ + content_type: z.object({ + uid: z.string(), + }), + entry: z.object({ + locale: z.nativeEnum(Lang), + uid: z.string(), + url: z.string().optional(), + }), + }), +}) export async function POST(request: NextRequest) { try { - const secret = request.nextUrl.searchParams.get("secret") ?? "" - const tagsParam = request.nextUrl.searchParams.get("tags") ?? "" + const headersList = headers() + const secret = headersList.get("x-revalidate-secret") if (secret !== env.REVALIDATE_SECRET) { + console.error(`Invalid Secret`) + console.error({ secret }) return Response.json( { - message: "Invalid secret", - now: Date.now(), - revalidated: false, - }, - { - status: 401, - } - ) - } - - if (!tagsParam) { - return Response.json( - { - message: "Missing tags param", now: Date.now(), revalidated: false, }, @@ -34,31 +48,37 @@ export async function POST(request: NextRequest) { ) } - const tags = tagsParam.split(",") - if (!tags.length) { - return Response.json( - { - message: "No tags", - now: Date.now(), - revalidated: false, - }, - { - status: 400, - } - ) + 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() }) } - tags.forEach((tag) => { - revalidateTag(tag) - }) + const { + data: { + data: { content_type, entry }, + }, + } = validatedData + const identifier = entry.url ?? content_type.uid + const refsTag = generateRefsResponseTag(entry.locale, identifier) + const refTag = generateRefTag(entry.locale, content_type.uid, entry.uid) + const tag = generateTag(entry.locale, entry.uid) + + console.info(`Revalidating refsTag: ${refsTag}`) + revalidateTag(refsTag) + + console.info(`Revalidating refTag: ${refTag}`) + revalidateTag(refTag) + + console.info(`Revalidating tag: ${tag}`) + revalidateTag(tag) return Response.json({ revalidated: true, now: Date.now() }) } catch (error) { console.info("Failed to revalidate tag(s)") console.error(error) - return Response.json( - { revalidated: false, now: Date.now() }, - { status: 500 } - ) + return internalServerError({ revalidated: false, now: Date.now() }) } } diff --git a/components/MyPages/Sidebar/helpers.ts b/components/MyPages/Sidebar/helpers.ts deleted file mode 100644 index 82c90ceee..000000000 --- a/components/MyPages/Sidebar/helpers.ts +++ /dev/null @@ -1,19 +0,0 @@ -import type { - MenuItem, - NavigationItem, -} from "@/types/requests/myPages/navigation" - -export function mapMenuItems(navigationItems: NavigationItem[]) { - return navigationItems.map(({ item }): MenuItem => { - const { node } = item.pageConnection.edges[0] - - return { - linkText: item.link_text || node.title, - lang: node.system.locale, - subItems: item.sub_items ? mapMenuItems(item.sub_items) : null, - uid: node.system.uid, - url: `/${node.system.locale}/${node.url}`.replaceAll(/\/\/+/g, "/"), - originalUrl: node.web?.original_url, - } - }) -} diff --git a/components/MyPages/Sidebar/index.tsx b/components/MyPages/Sidebar/index.tsx index 10f9f2e1a..6e8e80d11 100644 --- a/components/MyPages/Sidebar/index.tsx +++ b/components/MyPages/Sidebar/index.tsx @@ -1,38 +1,25 @@ import { Fragment } from "react" import { LogOut } from "react-feather" -import { GetNavigationMyPages } from "@/lib/graphql/Query/NavigationMyPages.graphql" -import { request } from "@/lib/graphql/request" +import { serverClient } from "@/lib/trpc/server" import Link from "@/components/TempDesignSystem/Link" import Title from "@/components/Title" -import { mapMenuItems } from "./helpers" - import styles from "./sidebar.module.css" -import type { - GetNavigationMyPagesData, - SidebarProps, -} from "@/types/requests/myPages/navigation" +import type { SidebarProps } from "@/types/requests/myPages/navigation" export default async function Sidebar({ lang }: SidebarProps) { - const response = await request( - GetNavigationMyPages, - { - locale: lang, - } - ) - // navigation_my_pages is of type Single, hence the hard [0] - const navigation = response.data.all_navigation_my_pages.items[0] - const menuItems = mapMenuItems(navigation.items) + const navigation = + await serverClient().contentstack.myPages.navigation.get(lang) return (