Just logging an error makes it difficult to relate the error log to code in the codebase. Error logging a message right before the error itself makes it easier to search the codebase for that error log.
139 lines
3.8 KiB
TypeScript
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.error(
|
|
`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.error(
|
|
`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.error(
|
|
`Failed to validate My Pages Navigation Return Data - (lang: ${lang}`
|
|
)
|
|
console.error(validatedNav.error)
|
|
return null
|
|
}
|
|
|
|
return validatedNav.data
|
|
}),
|
|
})
|