import { z } from "zod" import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url" import { nullableStringValidator } from "@scandic-hotels/common/utils/zod/stringValidator" import { ContentEnum } from "../../../types/content" import { safeUnion } from "../base/utils" import { systemSchema } from "./system" export const pageLinkSchema = z.object({ system: systemSchema, title: z.string().optional().default(""), url: z.string().optional().default(""), }) export const accountPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.AccountPage), }) .merge(pageLinkSchema) export const extendedPageLinkSchema = pageLinkSchema.merge( z.object({ web: z .object({ original_url: z.string().optional().default(""), }) .default({ original_url: "" }), }) ) export const campaignOverviewPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.CampaignOverviewPage), }) .merge(extendedPageLinkSchema) export const collectionPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.CollectionPage), }) .merge(extendedPageLinkSchema) export const contentPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.ContentPage), }) .merge(extendedPageLinkSchema) export const destinationCityPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.DestinationCityPage), }) .merge(pageLinkSchema) export const campaignPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.CampaignPage), }) .merge(pageLinkSchema) export const destinationCountryPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.DestinationCountryPage), }) .merge(pageLinkSchema) export const destinationOverviewPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.DestinationOverviewPage), }) .merge(pageLinkSchema) export const hotelPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.HotelPage), }) .merge(pageLinkSchema) export const loyaltyPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.LoyaltyPage), }) .merge(extendedPageLinkSchema) export const startPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.StartPage), }) .merge(pageLinkSchema) export const promoCampaignPageSchema = z .object({ __typename: z.literal(ContentEnum.blocks.PromoCampaignPage), }) .merge(pageLinkSchema) export const rawLinkUnionSchema = z.discriminatedUnion("__typename", [ accountPageSchema, campaignOverviewPageSchema, campaignPageSchema, collectionPageSchema, contentPageSchema, destinationCityPageSchema, destinationCountryPageSchema, destinationOverviewPageSchema, hotelPageSchema, loyaltyPageSchema, startPageSchema, promoCampaignPageSchema, ]) export const linkUnionSchema = safeUnion(rawLinkUnionSchema) type Data = | z.output | z.output | z.output | z.output | z.output | z.output | z.output | z.output | z.output | z.output | z.output | z.output | Object export function transformPageLink(data: Data) { if (data && "__typename" in data) { switch (data.__typename) { case ContentEnum.blocks.AccountPage: case ContentEnum.blocks.CampaignOverviewPage: case ContentEnum.blocks.CampaignPage: case ContentEnum.blocks.DestinationCityPage: case ContentEnum.blocks.DestinationCountryPage: case ContentEnum.blocks.DestinationOverviewPage: case ContentEnum.blocks.HotelPage: case ContentEnum.blocks.StartPage: case ContentEnum.blocks.PromoCampaignPage: return { __typename: data.__typename, system: data.system, title: data.title, url: removeMultipleSlashes(`/${data.system.locale}/${data.url}`), } case ContentEnum.blocks.CollectionPage: case ContentEnum.blocks.ContentPage: case ContentEnum.blocks.LoyaltyPage: // TODO: Once all links use this transform // `web` can be removed and not to be worried // about throughout the application return { __typename: data.__typename, system: data.system, title: data.title, url: data.web?.original_url ? data.web.original_url : removeMultipleSlashes(`/${data.system.locale}/${data.url}`), web: data.web, } } } } export const internalOrExternalLinkSchema = z .object({ is_contentstack_link: z.boolean().nullish(), external_link: z .object({ href: nullableStringValidator, title: z.string().nullish(), }) .nullish(), title: nullableStringValidator, linkConnection: z.object({ edges: z.array( z.object({ node: linkUnionSchema.transform((data) => { const link = transformPageLink(data) if (link) { return link } return data }), }) ), }), }) .transform( ({ is_contentstack_link, external_link, linkConnection, title }) => { if (is_contentstack_link !== false && linkConnection.edges.length) { const linkRef = linkConnection.edges[0].node return { title: title || linkRef.title, url: linkRef.url, } } else if (is_contentstack_link === false && external_link?.href) { return { title: title || external_link.title || "", url: external_link.href, } } } )