Files
web/packages/trpc/lib/routers/contentstack/collectionPage/utils.ts
Erik Tiekstra 8d34089637 feat(BOOK-609): Using embedded url for assets instead of href since that is not updated when the asset is updated)
* feat(BOOK-609): Updated refs handling for assets inside content pages

Approved-by: Linus Flood
2026-01-13 10:40:36 +00:00

145 lines
4.1 KiB
TypeScript

import { createCounter } from "@scandic-hotels/common/telemetry"
import { notFoundError } from "../../../errors"
import { GetCollectionPageRefs } from "../../../graphql/Query/CollectionPage/CollectionPage.graphql"
import { request } from "../../../graphql/request"
import {
CollectionPageEnum,
type CollectionPageRefs,
type GetCollectionPageRefsSchema,
} from "../../../types/collectionPage"
import {
generateRefsResponseTag,
generateTag,
generateTagsFromAssetSystem,
generateTagsFromSystem,
} from "../../../utils/generateTag"
import { collectionPageRefsSchema } from "./output"
import type { Lang } from "@scandic-hotels/common/constants/language"
import type { AssetSystem, System } from "../schemas/system"
export async function fetchCollectionPageRefs(lang: Lang, uid: string) {
const getCollectionPageRefsCounter = createCounter(
"trpc.contentstack.collectionPage.get.refs"
)
const metricsGetCollectionPageRefs = getCollectionPageRefsCounter.init({
lang,
uid,
})
metricsGetCollectionPageRefs.start()
const cacheKey = generateRefsResponseTag(lang, uid)
const variables = {
locale: lang,
uid,
}
const refsResponse = await request<GetCollectionPageRefsSchema>(
GetCollectionPageRefs,
variables,
{
key: cacheKey,
ttl: "max",
}
)
if (!refsResponse.data) {
metricsGetCollectionPageRefs.noDataError()
throw notFoundError({
message: "GetCollectionPageRefs returned no data",
errorDetails: variables,
})
}
return refsResponse.data
}
export function validateCollectionPageRefs(
data: GetCollectionPageRefsSchema,
lang: Lang,
uid: string
) {
const getCollectionPageRefsCounter = createCounter(
"trpc.contentstack.collectionPage.get.refs"
)
const metricsGetCollectionPageRefs = getCollectionPageRefsCounter.init({
lang,
uid,
})
const validatedData = collectionPageRefsSchema.safeParse(data)
if (!validatedData.success) {
metricsGetCollectionPageRefs.validationError(validatedData.error)
return null
}
metricsGetCollectionPageRefs.success()
return validatedData.data
}
export function generatePageTags(
validatedData: CollectionPageRefs,
lang: Lang
): string[] {
const { connections, assetConnections } = getConnections(validatedData)
return [
generateTagsFromSystem(lang, connections),
generateTagsFromAssetSystem(assetConnections),
generateTag(lang, validatedData.collection_page.system.uid),
].flat()
}
export function getConnections({ collection_page }: CollectionPageRefs) {
const connections: System["system"][] = [collection_page.system]
const assetConnections: AssetSystem[] = []
if (collection_page.hero_video?.sourceConnection.edges[0]) {
assetConnections.push(
collection_page.hero_video.sourceConnection.edges[0].node
)
}
if (collection_page.blocks) {
collection_page.blocks.forEach((block) => {
const typeName = block.__typename
switch (typeName) {
case CollectionPageEnum.ContentStack.blocks.Shortcuts:
if (block.shortcuts.shortcuts.length) {
connections.push(...block.shortcuts.shortcuts.filter((c) => !!c))
}
break
case CollectionPageEnum.ContentStack.blocks.CardsGrid:
if (block.cards_grid.length) {
connections.push(...block.cards_grid)
}
break
case CollectionPageEnum.ContentStack.blocks.UspGrid:
if (block.usp_grid.length) {
connections.push(...block.usp_grid.filter((c) => !!c))
}
break
case CollectionPageEnum.ContentStack.blocks.VideoCard:
if (block.video_card?.system) {
connections.push(block.video_card.system)
}
if (block.video_card?.video.sourceConnection.edges[0]) {
assetConnections.push(
block.video_card.video.sourceConnection.edges[0].node
)
}
break
case CollectionPageEnum.ContentStack.blocks.DynamicContent:
break
default:
const _exhaustiveCheck: never = typeName
break
}
})
}
return { connections, assetConnections }
}