53 lines
1.2 KiB
TypeScript
53 lines
1.2 KiB
TypeScript
import { revalidateTag } from 'next/cache';
|
|
|
|
const MAX_TAGS = 50;
|
|
const MAX_TAG_LENGTH = 256;
|
|
|
|
function parseTags(payload: unknown): string[] | null {
|
|
if (typeof payload !== 'object' || payload === null) {
|
|
return null;
|
|
}
|
|
|
|
const tags = (payload as { tags?: unknown }).tags;
|
|
|
|
if (!Array.isArray(tags) || tags.length === 0 || tags.length > MAX_TAGS) {
|
|
return null;
|
|
}
|
|
if (
|
|
!tags.every((tag) => typeof tag === 'string' && tag.length > 0 && tag.length <= MAX_TAG_LENGTH)
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
return tags;
|
|
}
|
|
|
|
export async function POST(request: Request) {
|
|
const secret = process.env['REVALIDATE_SECRET'];
|
|
|
|
if (!secret || request.headers.get('x-revalidate-secret') !== secret) {
|
|
return Response.json({ message: 'Unauthorized' }, { status: 401 });
|
|
}
|
|
|
|
let payload: unknown;
|
|
try {
|
|
payload = await request.json();
|
|
} catch {
|
|
return Response.json({ message: 'Invalid JSON body' }, { status: 400 });
|
|
}
|
|
|
|
const tags = parseTags(payload);
|
|
if (!tags) {
|
|
return Response.json(
|
|
{ message: 'Body must contain a non-empty "tags" array of strings' },
|
|
{ status: 400 }
|
|
);
|
|
}
|
|
|
|
for (const tag of tags) {
|
|
revalidateTag(tag, 'max');
|
|
}
|
|
|
|
return Response.json({ revalidated: tags });
|
|
}
|