Feat(SW-3708): refactor contentstack fetching (removing all refs) and cache invalidation * Remove all REFS * Revalidate correct language * PR fixes * PR fixes * Throw when errors from contentstack api Approved-by: Joakim Jäderberg
87 lines
2.3 KiB
TypeScript
87 lines
2.3 KiB
TypeScript
import { z } from "zod"
|
|
|
|
import { createLogger } from "@scandic-hotels/common/logger/createLogger"
|
|
|
|
import { env } from "@/env/server"
|
|
|
|
const logger = createLogger("contentstack-references")
|
|
|
|
/**
|
|
* Schema for validating Contentstack Management API references response
|
|
*/
|
|
const entryReferenceSchema = z.object({
|
|
uid: z.string().optional(),
|
|
entry_uid: z.string(),
|
|
content_type_uid: z.string(),
|
|
locale: z.string(),
|
|
title: z.string(),
|
|
_version: z.number().optional(),
|
|
content_type_title: z.string().optional(),
|
|
})
|
|
|
|
const referencesResponseSchema = z.object({
|
|
references: z.array(entryReferenceSchema).optional().default([]),
|
|
})
|
|
|
|
export type EntryReference = z.infer<typeof entryReferenceSchema>
|
|
|
|
/**
|
|
* Fetches all entries that reference the given entry from Contentstack Management API.
|
|
*
|
|
* This is used during cache invalidation to find parent pages that embed/reference
|
|
* the changed entry, so we can invalidate their caches as well.
|
|
*
|
|
* @see https://www.contentstack.com/docs/developers/apis/content-management-api#entry-references
|
|
*/
|
|
export async function fetchEntryReferences(
|
|
contentTypeUid: string,
|
|
entryUid: string
|
|
): Promise<EntryReference[]> {
|
|
const managementToken = env.CMS_MANAGEMENT_TOKEN
|
|
|
|
if (!managementToken) {
|
|
throw new Error("CMS_MANAGEMENT_TOKEN not configured")
|
|
}
|
|
|
|
// Contentstack EU region base URL
|
|
const baseUrl = "https://eu-api.contentstack.com"
|
|
const url = `${baseUrl}/v3/content_types/${contentTypeUid}/entries/${entryUid}/references`
|
|
|
|
const response = await fetch(url, {
|
|
method: "GET",
|
|
headers: {
|
|
api_key: env.CMS_API_KEY,
|
|
authorization: managementToken,
|
|
branch: env.CMS_BRANCH,
|
|
"Content-Type": "application/json",
|
|
},
|
|
// Don't cache this request - we need fresh data
|
|
cache: "no-store",
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const errorText = await response.text()
|
|
throw new Error(
|
|
`Failed to fetch entry references: ${response.status} ${errorText}`,
|
|
{
|
|
cause: response,
|
|
}
|
|
)
|
|
}
|
|
|
|
const data = await response.json()
|
|
const parsed = referencesResponseSchema.safeParse(data)
|
|
|
|
if (!parsed.success) {
|
|
throw new Error("Invalid response from Contentstack references API", {
|
|
cause: parsed.error,
|
|
})
|
|
}
|
|
|
|
logger.debug(
|
|
`Found ${parsed.data.references.length} references for ${contentTypeUid}/${entryUid}`
|
|
)
|
|
|
|
return parsed.data.references
|
|
}
|