import { z } from "zod" import { transformedImageVaultAssetSchema } from "@scandic-hotels/common/utils/imageVault" import { removeMultipleSlashes } from "@scandic-hotels/common/utils/url" import { DestinationCityPageEnum } from "../../../types/destinationCityPage" import { isDefined } from "../../../utils" import { discriminatedUnionArray } from "../../../utils/discriminatedUnion" import { accordionRefsSchema, accordionSchema, } from "../schemas/blocks/accordion" import { contentRefsSchema, contentSchema } from "../schemas/blocks/content" import { mapLocationSchema } from "../schemas/mapLocation" import { linkRefsUnionSchema, linkUnionSchema, transformPageLink, } from "../schemas/pageLinks" import { systemSchema } from "../schemas/system" import type { ImageVaultAsset } from "@scandic-hotels/common/utils/imageVault" export const destinationCityPageDestinationSettingsSchema = z .object({ city_denmark: z.string().optional().nullable(), city_finland: z.string().optional().nullable(), city_germany: z.string().optional().nullable(), city_poland: z.string().optional().nullable(), city_norway: z.string().optional().nullable(), city_sweden: z.string().optional().nullable(), location: mapLocationSchema, }) .transform( ({ city_denmark, city_finland, city_germany, city_norway, city_poland, city_sweden, location, }) => { return { city: city_denmark || city_finland || city_germany || city_poland || city_norway || city_sweden, location, } } ) export const destinationCityListDataSchema = z .object({ all_destination_city_page: z.object({ items: z.array( z .object({ heading: z.string(), destination_settings: destinationCityPageDestinationSettingsSchema, sort_order: z.number().nullable(), preamble: z.string(), experiences: z .object({ destination_experiences: z.array(z.string()), }) .transform( ({ destination_experiences }) => destination_experiences ) .nullish(), images: z .array(z.object({ image: transformedImageVaultAssetSchema })) .transform((images) => images .map((image) => image.image) .filter((image): image is ImageVaultAsset => !!image) ) .nullish(), url: z.string(), system: systemSchema, }) .transform((data) => { return { ...data, url: removeMultipleSlashes(`/${data.system.locale}/${data.url}`), } }) ), }), }) .transform( ({ all_destination_city_page }) => all_destination_city_page.items?.[0] ) export const destinationCityPageContent = z .object({ __typename: z.literal(DestinationCityPageEnum.ContentStack.blocks.Content), }) .merge(contentSchema) export const destinationCityPageAccordion = z .object({ __typename: z.literal( DestinationCityPageEnum.ContentStack.blocks.Accordion ), }) .merge(accordionSchema) export const blocksSchema = z.discriminatedUnion("__typename", [ destinationCityPageAccordion, destinationCityPageContent, ]) export const destinationCityPageSchema = z.object({ destination_city_page: z.object({ title: z.string(), destination_settings: destinationCityPageDestinationSettingsSchema, heading: z.string(), preamble: z.string(), experiences: z .object({ destination_experiences: z.array(z.string()), }) .nullish() .transform((experiences) => experiences?.destination_experiences ?? []), images: z .array(z.object({ image: transformedImageVaultAssetSchema })) .transform((images) => images .map((image) => image.image) .filter((image): image is ImageVaultAsset => !!image) ) .nullish(), has_sidepeek: z.boolean().default(false), sidepeek_button_text: z.string().nullish().default(""), sidepeek_content: z .object({ heading: z.string(), content: z.object({ json: z.any(), embedded_itemsConnection: z.object({ edges: z.array( z.object({ node: linkUnionSchema.transform((data) => { const link = transformPageLink(data) if (link) { return link } return data }), }) ), }), }), }) .nullish(), blocks: discriminatedUnionArray(blocksSchema.options).nullable(), system: systemSchema.merge( z.object({ created_at: z.string(), updated_at: z.string(), }) ), }), trackingProps: z.object({ url: z.string(), }), }) export const cityPageCountSchema = z .object({ all_destination_city_page: z.object({ total: z.number(), }), }) .transform(({ all_destination_city_page }) => all_destination_city_page.total) export const cityPageUrlsSchema = z .object({ all_destination_city_page: z.object({ items: z .array( z .object({ url: z.string().nullish(), destination_settings: destinationCityPageDestinationSettingsSchema, system: systemSchema, }) .transform((data) => { if (!data.destination_settings.city || !data.url) { return null } return { city: data.destination_settings.city, url: removeMultipleSlashes( `/${data.system.locale}/${data.url}` ), } }) ) .transform((data) => { return data.filter(isDefined) }), }), }) .transform(({ all_destination_city_page }) => all_destination_city_page.items) export const batchedCityPageUrlsSchema = z .array( z.object({ data: cityPageUrlsSchema, }) ) .transform((allItems) => { return allItems.flatMap((item) => item.data) }) /** REFS */ const destinationCityPageContentRefs = z .object({ __typename: z.literal(DestinationCityPageEnum.ContentStack.blocks.Content), }) .merge(contentRefsSchema) const destinationCityPageAccordionRefs = z .object({ __typename: z.literal( DestinationCityPageEnum.ContentStack.blocks.Accordion ), }) .merge(accordionRefsSchema) const blocksRefsSchema = z.discriminatedUnion("__typename", [ destinationCityPageAccordionRefs, destinationCityPageContentRefs, ]) export const destinationCityPageRefsSchema = z.object({ destination_city_page: z.object({ destination_settings: destinationCityPageDestinationSettingsSchema, sidepeek_content: z .object({ content: z.object({ embedded_itemsConnection: z.object({ edges: z.array( z.object({ node: linkRefsUnionSchema, }) ), }), }), }) .nullish(), blocks: discriminatedUnionArray(blocksRefsSchema.options).nullable(), system: systemSchema, }), })