Skip to content

Commit

Permalink
update home story instead of creating a new one (#56)
Browse files Browse the repository at this point in the history
* update home story instead of creating a new one

* remove console log
  • Loading branch information
dogfrogfog authored Nov 11, 2024
1 parent 3f9688f commit 46df51e
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 48 deletions.
7 changes: 5 additions & 2 deletions apps/storyblok/CLI/sb.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const main = async () => {
// Log in to storyblok CLI

spinner.start("Logging in to storyblok CLI ⏳");
const stdio = "ignore";
const stdio = process.env.DEBUG ? "inherit" : "ignore";
try {
execSync("pnpm storyblok logout", {
stdio,
Expand All @@ -82,6 +82,7 @@ const main = async () => {
// Create Vercel production and preview projects

spinner.start("Creating Vercel production and preview projects ⏳");
const whRevalidateSecret = crypto.randomUUID();
const {
deploymentUrl: productionDeploymentUrl,
projectName: productionProjectName,
Expand All @@ -92,6 +93,7 @@ const main = async () => {
isPreview: false,
spaceId,
previewToken,
whRevalidateSecret,
},
});

Expand All @@ -105,6 +107,7 @@ const main = async () => {
isPreview: true,
spaceId,
previewToken,
whRevalidateSecret,
},
});
spinner.succeed(
Expand All @@ -119,7 +122,7 @@ const main = async () => {
});
await createStoryblokWebhook(
spaceId,
`${productionDeploymentUrl}/api/revalidate`,
`${productionDeploymentUrl}/api/revalidate?secret=${whRevalidateSecret}`,
);
spinner.succeed("Storyblok space successfully updated ✅");

Expand Down
125 changes: 94 additions & 31 deletions apps/storyblok/CLI/services/storyblok.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -187,35 +187,6 @@ async function getSectionsFolder(spaceId) {
return data.component_groups.find((folder) => folder.name === "sections");
}

async function createStory(spaceId, storyData) {
const envs = loadEnvVariables();
const token = envs.SB_PERSONAL_ACCESS_TOKEN;

const response = await fetch(
`https://mapi.storyblok.com/v1/spaces/${spaceId}/stories`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: token,
},
body: JSON.stringify({
story: storyData,
publish: 1,
}),
},
);

if (!response.ok) {
console.log(response.status, response.statusText, await response.json());
throw new Error(`❌ HTTP error! Status: ${response.status}`);
}

const data = await response.json();

return data;
}

const globalComponentNames = ["header", "footer"];
export async function uploadBackupStories(spaceId) {
// Get directory path relative to current file
Expand Down Expand Up @@ -304,8 +275,12 @@ export async function uploadBackupStories(spaceId) {
parent_id: newParentId,
};

// home page is created by default
if (story.slug !== "home") {
if (story.slug === "home") {
console.log("updated story data");

const homeStory = await getStoryBySlug(spaceId, "home");
await updateStory(spaceId, homeStory.id, storyData);
} else {
await createStory(spaceId, storyData);
}
} catch (error) {
Expand All @@ -314,3 +289,91 @@ export async function uploadBackupStories(spaceId) {
}
}
}

export async function getStoryBySlug(spaceId, slug) {
const envs = loadEnvVariables();
const token = envs.SB_PERSONAL_ACCESS_TOKEN;

const searchParams = new URLSearchParams({
version: "draft",
by_slugs: slug, // home, headers/default-header
});

const response = await fetch(
`https://mapi.storyblok.com/v1/spaces/${spaceId}/stories?${searchParams}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: token,
},
},
);

if (!response.ok) {
console.log(response.status, response.statusText, await response.json());
throw new Error(`❌ HTTP error! Status: ${response.status}`);
}

const data = await response.json();
return data.stories[0] || null;
}

async function createStory(spaceId, storyData) {
const envs = loadEnvVariables();
const token = envs.SB_PERSONAL_ACCESS_TOKEN;

const response = await fetch(
`https://mapi.storyblok.com/v1/spaces/${spaceId}/stories`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: token,
},
body: JSON.stringify({
story: storyData,
publish: 1,
}),
},
);

if (!response.ok) {
console.log(response.status, response.statusText, await response.json());
throw new Error(`❌ HTTP error! Status: ${response.status}`);
}

const data = await response.json();

return data;
}

export async function updateStory(spaceId, storyId, storyData) {
const envs = loadEnvVariables();
const token = envs.SB_PERSONAL_ACCESS_TOKEN;

const response = await fetch(
`https://mapi.storyblok.com/v1/spaces/${spaceId}/stories/${storyId}`,
{
method: "PUT",
headers: {
"Content-Type": "application/json",
Authorization: token,
},
body: JSON.stringify({
story: storyData,
publish: 1,
force_update: 1,
}),
},
);

if (!response.ok) {
console.log(response.status, response.statusText, await response.json());
throw new Error(`❌ HTTP error! Status: ${response.status}`);
}

const data = await response.json();

return data;
}
6 changes: 5 additions & 1 deletion apps/storyblok/CLI/services/vercel.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export async function getVercelUserInfo() {
}

export async function createVercelProject({ projectName, sbParams }) {
const { isPreview, spaceId, previewToken } = sbParams;
const { isPreview, spaceId, previewToken, whRevalidateSecret } = sbParams;
const envs = loadEnvVariables();
const repoName = envs.REPO_NAME;
const vercelToken = envs.VERCEL_PERSONAL_AUTH_TOKEN;
Expand Down Expand Up @@ -105,6 +105,10 @@ export async function createVercelProject({ projectName, sbParams }) {
key: "SB_PREVIEW_TOKEN",
value: previewToken,
},
{
key: "SB_WEBHOOK_REVALIDATE_SECRET",
value: whRevalidateSecret,
},
{
key: "SB_SPACE_ID",
value: spaceId + "",
Expand Down
20 changes: 6 additions & 14 deletions apps/storyblok/src/app/api/revalidate/route.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,21 @@
import { createHmac } from "crypto";
import { revalidateTag } from "next/cache";

import { SB_CACHE_VERSION_TAG } from "@/constants/cacheTags";

const webhookSecret = process.env.SB_WEBHOOK_REVALIDATE_SECRET || "";

function generateSignature(body: string) {
return createHmac("sha1", webhookSecret).update(body).digest("hex");
}

export async function POST(request: Request) {
const body = await request.json();
const signature = request.headers.get("webhook-signature");
const { searchParams } = new URL(request.url);
const secret = searchParams.get("secret");

if (!body || !signature) {
if (!body || !secret) {
return Response.json(
{ error: "No body or signature provided" },
{ error: "No body or secret provided" },
{ status: 400 },
);
}

const generatedSignature = generateSignature(JSON.stringify(body));

if (signature !== generatedSignature) {
return Response.json({ error: "Invalid signature" }, { status: 400 });
if (secret !== process.env.SB_WEBHOOK_REVALIDATE_SECRET) {
return Response.json({ error: "No secret provided" }, { status: 400 });
}

revalidateTag(SB_CACHE_VERSION_TAG);
Expand Down

0 comments on commit 46df51e

Please sign in to comment.