Files
web/apps/scandic-web/lib/contentstack/fetchEntryReferences.ts
Linus Flood 5fc93472f4 Merged in feat/rework-contentstack (pull request #3493)
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
2026-01-27 12:38:36 +00:00

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
}