mirror of
https://github.com/Xevion/xevion.dev.git
synced 2025-12-05 21:16:55 -06:00
Add 'revalidate' route, add DIRECTUS_REVALIDATE_KEY
This commit is contained in:
@@ -9,3 +9,4 @@
|
||||
# Example:
|
||||
# SERVERVAR=foo
|
||||
# NEXT_PUBLIC_CLIENTVAR=bar
|
||||
DIRECTUS_REVALIDATE_KEY=
|
||||
|
||||
1
src/env/schema.mjs
vendored
1
src/env/schema.mjs
vendored
@@ -6,6 +6,7 @@ import { z } from "zod";
|
||||
* This way you can ensure the app isn't built with invalid env vars.
|
||||
*/
|
||||
export const serverSchema = z.object({
|
||||
DIRECTUS_REVALIDATE_KEY: z.string(),
|
||||
NODE_ENV: z.enum(["development", "test", "production"]),
|
||||
});
|
||||
|
||||
|
||||
102
src/pages/api/revalidate.ts
Normal file
102
src/pages/api/revalidate.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { readItem, readItems } from "@directus/sdk";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
import { z } from "zod";
|
||||
import directus from "../../utils/directus";
|
||||
|
||||
async function getURLs(
|
||||
type: string,
|
||||
key: string,
|
||||
payload: Map<string, unknown>,
|
||||
): Promise<string[] | null> {
|
||||
if (type == "project_link" || type == "project_technology") {
|
||||
console.error({
|
||||
message: `Failed to provide URls for '${type}' type`,
|
||||
type,
|
||||
key,
|
||||
payload,
|
||||
});
|
||||
return [];
|
||||
}
|
||||
|
||||
if (type === "project") return ["/projects", `/projects/${key}`];
|
||||
if (type === "metadata") return ["/"];
|
||||
if (type === "technology") {
|
||||
const urls = ["/technology"];
|
||||
|
||||
// Get all projects with the technology
|
||||
const all_projects = await directus.request(readItems("project"));
|
||||
if (all_projects != null) {
|
||||
for (const project of all_projects) {
|
||||
if (project.technologies?.some((t) => t.id === key))
|
||||
urls.push(`/projects/${project.id}`);
|
||||
}
|
||||
}
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
||||
if (type === "projects") {
|
||||
const urls = ["/projects", `/projects/${key}`];
|
||||
// TODO: If 'featured', index page should be revalidated
|
||||
|
||||
const project = await directus.request(readItem("project", key));
|
||||
if (project != null) return urls;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const requestSchema = z.object({
|
||||
type: z.string(),
|
||||
keys: z.array(z.string()).min(1),
|
||||
source: z.map(z.string(), z.any()),
|
||||
payload: z.map(z.string(), z.any()),
|
||||
});
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse,
|
||||
) {
|
||||
if (req.method !== "POST")
|
||||
return res.status(405).json({ message: "Method not allowed" });
|
||||
|
||||
if (
|
||||
req.headers["Authorization"] !==
|
||||
"Bearer " + process.env.DIRECTUS_REVALIDATE_KEY
|
||||
)
|
||||
return res.status(401).json({ message: "Invalid token" });
|
||||
|
||||
try {
|
||||
// Verify JSON body
|
||||
const { success, data } = requestSchema.safeParse(req.body);
|
||||
if (!success) return res.status(400).json({ message: "Invalid JSON body" });
|
||||
|
||||
// Get URLs
|
||||
const urls = await getURLs(data.type, data.keys[0]!, data.payload);
|
||||
if (urls === null)
|
||||
return res
|
||||
.status(404)
|
||||
.json({ revalidated: false, message: "Collection not found" });
|
||||
|
||||
// Revalidate all URLs
|
||||
try {
|
||||
await Promise.all(urls.map((url) => res.revalidate(url)));
|
||||
} catch (error) {
|
||||
console.error({ message: "Error while revalidating", error });
|
||||
return res.status(500).json({
|
||||
revalidated: false,
|
||||
message: "Error while revalidating",
|
||||
urls,
|
||||
});
|
||||
}
|
||||
|
||||
// Return success
|
||||
return res.json({ revalidated: true, urls });
|
||||
} catch (error) {
|
||||
console.error({
|
||||
message: "Error while preparing to revalidate",
|
||||
error,
|
||||
});
|
||||
return res.status(500).send("Error revalidating");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user