import { z } from "zod" import { Lang } from "@scandic-hotels/common/constants/language" import { langToApiLang } from "../../constants/apiLang" import { ChildBedTypeEnum } from "../../enums/childBedTypeEnum" const roomsSchema = z .array( z.object({ adults: z.number().int().nonnegative(), bookingCode: z.string().nullish(), childrenAges: z .array( z.object({ age: z.number().int().nonnegative(), bedType: z.nativeEnum(ChildBedTypeEnum), }) ) .default([]), rateCode: z.string(), redemptionCode: z.string().optional(), roomTypeCode: z.coerce.string(), guest: z.object({ becomeMember: z.boolean(), countryCode: z.string(), dateOfBirth: z.string().nullish(), email: z.string().email(), firstName: z.string(), lastName: z.string(), membershipNumber: z.string().nullish(), postalCode: z.string().nullish(), phoneNumber: z.string(), }), smsConfirmationRequested: z.boolean(), specialRequest: z.object({ comment: z.string().optional(), }), packages: z.object({ breakfast: z.boolean(), allergyFriendly: z.boolean(), petFriendly: z.boolean(), accessibility: z.boolean(), }), roomPrice: z.object({ memberPrice: z.number().nullish(), publicPrice: z.number().nullish(), }), }) ) .superRefine((data, ctx) => { data.forEach((room, idx) => { if (idx === 0 && room.guest.becomeMember) { if (!room.guest.dateOfBirth) { ctx.addIssue({ code: z.ZodIssueCode.invalid_type, expected: "string", received: typeof room.guest.dateOfBirth, path: ["guest", "dateOfBirth"], }) } if (!room.guest.postalCode) { ctx.addIssue({ code: z.ZodIssueCode.invalid_type, expected: "string", received: typeof room.guest.postalCode, path: ["guest", "postalCode"], }) } } }) }) const paymentSchema = z.object({ paymentMethod: z.string(), card: z .object({ alias: z.string(), expiryDate: z.string(), cardType: z.string(), }) .optional(), cardHolder: z .object({ email: z.string().email(), name: z.string(), phoneCountryCode: z.string(), phoneSubscriber: z.string(), }) .optional(), success: z.string(), error: z.string(), cancel: z.string(), }) // Mutation export const createBookingInput = z.object({ hotelId: z.string(), checkInDate: z.string(), checkOutDate: z.string(), rooms: roomsSchema, payment: paymentSchema.optional(), language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]), }) export const addPackageInput = z.object({ ancillaryComment: z.string(), ancillaryDeliveryTime: z.string().nullish(), packages: z.array( z.object({ code: z.string(), quantity: z.number(), comment: z.string().optional(), }) ), language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]), }) export const removePackageInput = z.object({ codes: z.array(z.string()), language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]), }) export const cancelBookingsInput = z.object({ language: z.nativeEnum(Lang), }) export const guaranteeBookingInput = z.object({ card: z .object({ alias: z.string(), expiryDate: z.string(), cardType: z.string(), }) .optional(), language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]), success: z.string().nullable(), error: z.string().nullable(), cancel: z.string().nullable(), }) export const createRefIdInput = z.object({ confirmationNumber: z .string() .trim() .regex(/^\s*[0-9]+(-[0-9])?\s*$/) .min(1), lastName: z.string().trim().max(250).min(1), }) export const updateBookingInput = z.object({ checkInDate: z.string().optional(), checkOutDate: z.string().optional(), guest: z .object({ email: z.string().optional(), phoneNumber: z.string().optional(), countryCode: z.string().optional(), }) .optional(), language: z.nativeEnum(Lang).transform((val) => langToApiLang[val]), }) // Query export const getBookingInput = z.object({ lang: z.nativeEnum(Lang).optional(), }) export const getLinkedReservationsInput = z.object({ lang: z.nativeEnum(Lang).optional(), }) export const findBookingInput = z.object({ confirmationNumber: z.string(), firstName: z.string(), lastName: z.string(), email: z.string(), lang: z.nativeEnum(Lang).optional(), }) export type LinkedReservationsInput = z.input export const getBookingStatusInput = z.object({ lang: z.nativeEnum(Lang).optional(), })