Files
web/server/routers/contentstack/myPages/navigation/query.ts
2024-06-20 09:29:12 +02:00

139 lines
3.8 KiB
TypeScript

import {
GetNavigationMyPages,
GetNavigationMyPagesRefs,
} from "@/lib/graphql/Query/NavigationMyPages.graphql"
import { request } from "@/lib/graphql/request"
import { notFound } from "@/server/errors/trpc"
import { contentstackBaseProcedure, router } from "@/server/trpc"
import {
generateRefsResponseTag,
generateTag,
generateTags,
} from "@/utils/generateTag"
import { removeMultipleSlashes } from "@/utils/url"
import {
type GetNavigationMyPagesData,
type GetNavigationMyPagesRefsData,
getNavigationSchema,
type MenuItems,
navigationPayloadSchema,
navigationRefsPayloadSchema,
} from "./output"
import { getConnections } from "./utils"
import { PageLinkEnum } from "@/types/requests/pageLinks"
export function mapMenuItems(menuItems: MenuItems) {
return menuItems.map((menuItem) => {
return {
...menuItem,
links: menuItem.links
.filter((link) => {
// If content is unpublished or in other way inaccessible in Contentstack
// there will be no edges, filter out those links.
return !!link.page.edges[0]
})
.map((link) => {
const page = link.page.edges[0].node
let originalUrl = undefined
if (
page.__typename === PageLinkEnum.ContentPage ||
page.__typename === PageLinkEnum.LoyaltyPage
) {
if (page.web.original_url) {
originalUrl = page.web.original_url
}
}
return {
lang: page.system.locale,
linkText: link.link_text ? link.link_text : page.title,
uid: page.system.uid,
url: removeMultipleSlashes(`/${page.system.locale}/${page.url}`),
originalUrl,
}
}),
}
})
}
export const navigationQueryRouter = router({
get: contentstackBaseProcedure.query(async function ({ ctx }) {
const { lang } = ctx
const refsResponse = await request<GetNavigationMyPagesRefsData>(
GetNavigationMyPagesRefs,
{ locale: lang },
{
tags: [generateRefsResponseTag(lang, "navigation_my_pages")],
}
)
if (!refsResponse.data) {
throw notFound(refsResponse)
}
const validatedMyPagesNavigationRefs =
navigationRefsPayloadSchema.safeParse(refsResponse.data)
if (!validatedMyPagesNavigationRefs.success) {
console.info(
`Failed to validate My Pages Navigation Refs - (lang: ${lang}`
)
console.error(validatedMyPagesNavigationRefs.error)
return null
}
const connections = getConnections(validatedMyPagesNavigationRefs.data)
const tags = [
generateTags(lang, connections),
generateTag(
lang,
validatedMyPagesNavigationRefs.data.all_navigation_my_pages.items[0]
.system.uid
),
].flat()
const response = await request<GetNavigationMyPagesData>(
GetNavigationMyPages,
{ locale: lang },
{ tags }
)
if (!response.data) {
throw notFound(response)
}
const validatedMyPagesNavigation = navigationPayloadSchema.safeParse(
response.data
)
if (!validatedMyPagesNavigation.success) {
console.info(
`Failed to validate My Pages Navigation Data - (lang: ${lang}`
)
console.error(validatedMyPagesNavigation.error)
return null
}
const menuItem =
validatedMyPagesNavigation.data.all_navigation_my_pages.items[0]
const nav = {
menuItems: mapMenuItems(menuItem.menu_items),
title: menuItem.title,
}
const validatedNav = getNavigationSchema.safeParse(nav)
if (!validatedNav.success) {
console.info(
`Failed to validate My Pages Navigation Return Data - (lang: ${lang}`
)
console.error(validatedNav.error)
return null
}
return validatedNav.data
}),
})