mirror of
https://github.com/Xevion/xevion.dev.git
synced 2025-12-06 03:17:08 -06:00
Add 'revalidate' route, add DIRECTUS_REVALIDATE_KEY
This commit is contained in:
@@ -9,3 +9,4 @@
|
|||||||
# Example:
|
# Example:
|
||||||
# SERVERVAR=foo
|
# SERVERVAR=foo
|
||||||
# NEXT_PUBLIC_CLIENTVAR=bar
|
# 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.
|
* This way you can ensure the app isn't built with invalid env vars.
|
||||||
*/
|
*/
|
||||||
export const serverSchema = z.object({
|
export const serverSchema = z.object({
|
||||||
|
DIRECTUS_REVALIDATE_KEY: z.string(),
|
||||||
NODE_ENV: z.enum(["development", "test", "production"]),
|
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