Files
web/server/routers/contentstack/accountPage/query.ts
Christel Westerberg c47966f994 fix: caching
2024-05-31 09:38:46 +02:00

178 lines
5.1 KiB
TypeScript

import { Lang } from "@/constants/languages"
import { batchRequest } from "@/lib/graphql/batchRequest"
import {
GetAccountPage,
GetAccountPageRefs,
GetDaDeEnUrlsAccountPage,
GetFiNoSvUrlsAccountPage,
} from "@/lib/graphql/Query/AccountPage.graphql"
import { request } from "@/lib/graphql/request"
import { internalServerError, notFound } from "@/server/errors/trpc"
import { contentstackProcedure, router } from "@/server/trpc"
import {
generateRefsResponseTag,
generateTag,
generateTags,
} from "@/utils/generateTag"
import { removeEmptyObjects } from "../../utils"
import {
type AccountPage,
AccountPageRefsDataRaw,
validateAccountPageRefsSchema,
validateAccountPageSchema,
validateLanguageSwitcherData,
} from "./output"
import { getConnections } from "./utils"
import { ContentEntries } from "@/types/components/myPages/myPage/enums"
import { Embeds } from "@/types/requests/embeds"
import {
LanguageSwitcherData,
LanguageSwitcherQueryDataRaw,
} from "@/types/requests/languageSwitcher"
import { Edges } from "@/types/requests/utils/edges"
import { RTEDocument } from "@/types/rte/node"
export const accountPageQueryRouter = router({
get: contentstackProcedure.query(async ({ ctx }) => {
const { lang, uid } = ctx
const refsResponse = await request<AccountPageRefsDataRaw>(
GetAccountPageRefs,
{
locale: lang,
uid,
},
{
next: {
tags: [generateRefsResponseTag(lang, uid)],
},
}
)
if (!refsResponse.data) {
throw notFound(refsResponse)
}
// Remove empty objects from a fetched content type. Needed since
// Contentstack returns empty objects for all non queried blocks in modular blocks.
// This is an ongoing support case in Contentstack, ticker number #00031579
const cleanedData = removeEmptyObjects(refsResponse.data)
const validatedAccountPageRefs =
validateAccountPageRefsSchema.safeParse(cleanedData)
if (!validatedAccountPageRefs.success) {
throw internalServerError(validatedAccountPageRefs.error)
}
const connections = getConnections(validatedAccountPageRefs.data)
const tags = [
generateTags(lang, connections),
generateTag(lang, validatedAccountPageRefs.data.account_page.system.uid),
].flat()
const response = await request<AccountPageRefsDataRaw>(
GetAccountPage,
{
locale: lang,
uid,
},
{ next: { tags } }
)
if (!response.data) {
throw notFound(response)
}
const validatedAccountPage = validateAccountPageSchema.safeParse(
response.data
)
if (!validatedAccountPage.success) {
throw internalServerError(validatedAccountPage.error)
}
// TODO: Make returned data nicer
const content = validatedAccountPage.data.account_page.content.map(
(block) => {
switch (block.__typename) {
case ContentEntries.AccountPageContentDynamicContent:
return block
case ContentEntries.AccountPageContentShortcuts:
return {
...block,
shortcuts: {
...block.shortcuts,
shortcuts: block.shortcuts.shortcuts.map((shortcut) => ({
text: shortcut.text,
openInNewTab: shortcut.open_in_new_tab,
...shortcut.linkConnection.edges[0].node,
url:
shortcut.linkConnection.edges[0].node.original_url ||
`/${shortcut.linkConnection.edges[0].node.system.locale}${shortcut.linkConnection.edges[0].node.url}`,
})),
},
}
case ContentEntries.AccountPageContentTextContent:
return {
...block,
text_content: {
content: {
json: block.text_content.content.json as RTEDocument,
embedded_itemsConnection: block.text_content.content
.embedded_itemsConnection as Edges<Embeds>,
},
},
}
default:
return null
}
}
)
const accountPage = {
...validatedAccountPage.data.account_page,
content,
} as AccountPage
return accountPage
}),
languageSwitcher: contentstackProcedure.query(async ({ ctx }) => {
const variables = {
uid: ctx.uid,
}
const res = await batchRequest<LanguageSwitcherQueryDataRaw>([
{
document: GetDaDeEnUrlsAccountPage,
variables,
},
{
document: GetFiNoSvUrlsAccountPage,
variables,
},
])
const urls = Object.keys(res.data).reduce<LanguageSwitcherData>(
(acc, key) => {
const item = res.data[key as Lang]?.items[0]
const url = item ? `/${key}${item.url}` : undefined
return { ...acc, [key]: { url, isExternal: false } }
},
{} as LanguageSwitcherData
)
const validatedLanguageSwitcherData =
validateLanguageSwitcherData.safeParse(urls)
if (!validatedLanguageSwitcherData.success) {
throw internalServerError(validatedLanguageSwitcherData.error)
}
return { lang: ctx.lang, urls }
}),
})