From ee534492a0902f381e69291712b8ace638104214 Mon Sep 17 00:00:00 2001 From: Michael Novotny Date: Mon, 31 Jul 2023 22:33:13 -0500 Subject: [PATCH] Moves revalidation logic to `lib` (#1132) --- app/api/revalidate/route.ts | 35 +++-------------------------------- lib/shopify/index.ts | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 32 deletions(-) diff --git a/app/api/revalidate/route.ts b/app/api/revalidate/route.ts index 94ddfff9b..47af2a4a4 100644 --- a/app/api/revalidate/route.ts +++ b/app/api/revalidate/route.ts @@ -1,37 +1,8 @@ -import { TAGS } from 'lib/constants'; -import { revalidateTag } from 'next/cache'; -import { headers } from 'next/headers'; +import { revalidate } from 'lib/shopify'; import { NextRequest, NextResponse } from 'next/server'; export const runtime = 'edge'; -// We always need to respond with a 200 status code to Shopify, -// otherwise it will continue to retry the request. -export async function POST(req: NextRequest): Promise { - const collectionWebhooks = ['collections/create', 'collections/delete', 'collections/update']; - const productWebhooks = ['products/create', 'products/delete', 'products/update']; - const topic = headers().get('x-shopify-topic') || 'unknown'; - const secret = req.nextUrl.searchParams.get('secret'); - const isCollectionUpdate = collectionWebhooks.includes(topic); - const isProductUpdate = productWebhooks.includes(topic); - - if (!secret || secret !== process.env.SHOPIFY_REVALIDATION_SECRET) { - console.error('Invalid revalidation secret.'); - return NextResponse.json({ status: 200 }); - } - - if (!isCollectionUpdate && !isProductUpdate) { - // We don't need to revalidate anything for any other topics. - return NextResponse.json({ status: 200 }); - } - - if (isCollectionUpdate) { - revalidateTag(TAGS.collections); - } - - if (isProductUpdate) { - revalidateTag(TAGS.products); - } - - return NextResponse.json({ status: 200, revalidated: true, now: Date.now() }); +export async function POST(req: NextRequest): Promise { + return revalidate(req); } diff --git a/lib/shopify/index.ts b/lib/shopify/index.ts index 64b5d24e8..a8804d045 100644 --- a/lib/shopify/index.ts +++ b/lib/shopify/index.ts @@ -1,5 +1,8 @@ import { HIDDEN_PRODUCT_TAG, SHOPIFY_GRAPHQL_API_ENDPOINT, TAGS } from 'lib/constants'; import { isShopifyError } from 'lib/type-guards'; +import { revalidateTag } from 'next/cache'; +import { headers } from 'next/headers'; +import { NextRequest, NextResponse } from 'next/server'; import { addToCartMutation, createCartMutation, @@ -408,3 +411,35 @@ export async function getProducts({ return reshapeProducts(removeEdgesAndNodes(res.body.data.products)); } + +// This is called from `app/api/revalidate.ts` so providers can control revalidation logic. +export async function revalidate(req: NextRequest): Promise { + // We always need to respond with a 200 status code to Shopify, + // otherwise it will continue to retry the request. + const collectionWebhooks = ['collections/create', 'collections/delete', 'collections/update']; + const productWebhooks = ['products/create', 'products/delete', 'products/update']; + const topic = headers().get('x-shopify-topic') || 'unknown'; + const secret = req.nextUrl.searchParams.get('secret'); + const isCollectionUpdate = collectionWebhooks.includes(topic); + const isProductUpdate = productWebhooks.includes(topic); + + if (!secret || secret !== process.env.SHOPIFY_REVALIDATION_SECRET) { + console.error('Invalid revalidation secret.'); + return NextResponse.json({ status: 200 }); + } + + if (!isCollectionUpdate && !isProductUpdate) { + // We don't need to revalidate anything for any other topics. + return NextResponse.json({ status: 200 }); + } + + if (isCollectionUpdate) { + revalidateTag(TAGS.collections); + } + + if (isProductUpdate) { + revalidateTag(TAGS.products); + } + + return NextResponse.json({ status: 200, revalidated: true, now: Date.now() }); +}