diff --git a/server/routers/hotels/output.ts b/server/routers/hotels/output.ts index ae889441e..47c82c9b1 100644 --- a/server/routers/hotels/output.ts +++ b/server/routers/hotels/output.ts @@ -2,12 +2,11 @@ import { z } from "zod" import { toLang } from "@/server/utils" +import { imageMetaDataSchema, imageSizesSchema } from "./schemas/image" +import { roomSchema } from "./schemas/room" import { getPoiGroupByCategoryName } from "./utils" -import { - PointOfInterestCategoryNameEnum, - PointOfInterestGroupEnum, -} from "@/types/hotel" +import { PointOfInterestCategoryNameEnum } from "@/types/hotel" const ratingsSchema = z .object({ @@ -121,20 +120,6 @@ const locationSchema = z.object({ longitude: z.number(), }) -const imageMetaDataSchema = z.object({ - title: z.string(), - altText: z.string(), - altText_En: z.string(), - copyRight: z.string(), -}) - -const imageSizesSchema = z.object({ - tiny: z.string(), - small: z.string(), - medium: z.string(), - large: z.string(), -}) - const hotelContentSchema = z.object({ images: z.object({ metaData: imageMetaDataSchema, @@ -230,7 +215,6 @@ const rewardNightSchema = z.object({ }), }) -const poiGroups = z.nativeEnum(PointOfInterestGroupEnum) const poiCategoryNames = z.nativeEnum(PointOfInterestCategoryNameEnum) export const pointOfInterestSchema = z @@ -369,96 +353,6 @@ const relationshipsSchema = z.object({ }), }) -const roomContentSchema = z.object({ - images: z.array( - z.object({ - metaData: imageMetaDataSchema, - imageSizes: imageSizesSchema, - }) - ), - texts: z.object({ - descriptions: z.object({ - short: z.string(), - medium: z.string(), - }), - }), -}) - -const roomTypesSchema = z.object({ - name: z.string(), - description: z.string(), - code: z.string(), - roomCount: z.number(), - mainBed: z.object({ - type: z.string(), - description: z.string(), - widthRange: z.object({ - min: z.number(), - max: z.number(), - }), - }), - fixedExtraBed: z.object({ - type: z.string(), - description: z.string().optional(), - widthRange: z.object({ - min: z.number(), - max: z.number(), - }), - }), - roomSize: z.object({ - min: z.number(), - max: z.number(), - }), - occupancy: z.object({ - total: z.number(), - adults: z.number(), - children: z.number(), - }), - isLackingCribs: z.boolean(), - isLackingExtraBeds: z.boolean(), -}) - -const roomFacilitiesSchema = z.object({ - availableInAllRooms: z.boolean(), - name: z.string(), - isUniqueSellingPoint: z.boolean(), - sortOrder: z.number(), -}) - -export const roomSchema = z - .object({ - attributes: z.object({ - name: z.string(), - sortOrder: z.number(), - content: roomContentSchema, - roomTypes: z.array(roomTypesSchema), - roomFacilities: z.array(roomFacilitiesSchema), - occupancy: z.object({ - total: z.number(), - adults: z.number(), - children: z.number(), - }), - roomSize: z.object({ - min: z.number(), - max: z.number(), - }), - }), - id: z.string(), - type: z.enum(["roomcategories"]), - }) - .transform((data) => { - return { - descriptions: data.attributes.content.texts.descriptions, - id: data.id, - images: data.attributes.content.images, - name: data.attributes.name, - occupancy: data.attributes.occupancy, - roomSize: data.attributes.roomSize, - sortOrder: data.attributes.sortOrder, - type: data.type, - } - }) - const merchantInformationSchema = z.object({ webMerchantId: z.string(), cards: z.record(z.string(), z.boolean()).transform((val) => { diff --git a/server/routers/hotels/query.ts b/server/routers/hotels/query.ts index 1b740afb2..198219e0e 100644 --- a/server/routers/hotels/query.ts +++ b/server/routers/hotels/query.ts @@ -30,7 +30,6 @@ import { getHotelsAvailabilitySchema, getRatesSchema, getRoomsAvailabilitySchema, - roomSchema, } from "./output" import tempRatesData from "./tempRatesData.json" import { @@ -190,35 +189,7 @@ export const hotelQueryRouter = router({ const images = extractHotelImages(hotelAttributes) const roomCategories = included - ? included - .filter((item) => item.type === "roomcategories") - .map((roomCategory) => { - const validatedRoom = roomSchema.safeParse(roomCategory) - if (!validatedRoom.success) { - getHotelFailCounter.add(1, { - hotelId, - lang, - include, - error_type: "validation_error", - error: JSON.stringify( - validatedRoom.error.issues.map(({ code, message }) => ({ - code, - message, - })) - ), - }) - console.error( - "api.hotels.hotel validation error", - JSON.stringify({ - query: { hotelId, params }, - error: validatedRoom.error, - }) - ) - throw badRequestError() - } - - return validatedRoom.data - }) + ? included.filter((item) => item.type === "roomcategories") : [] const activities = contentstackData?.content diff --git a/server/routers/hotels/schemas/image.ts b/server/routers/hotels/schemas/image.ts new file mode 100644 index 000000000..296530316 --- /dev/null +++ b/server/routers/hotels/schemas/image.ts @@ -0,0 +1,15 @@ +import { z } from "zod" + +export const imageSizesSchema = z.object({ + tiny: z.string(), + small: z.string(), + medium: z.string(), + large: z.string(), +}) + +export const imageMetaDataSchema = z.object({ + title: z.string(), + altText: z.string(), + altText_En: z.string(), + copyRight: z.string(), +}) diff --git a/server/routers/hotels/schemas/room.ts b/server/routers/hotels/schemas/room.ts new file mode 100644 index 000000000..bb3f7019c --- /dev/null +++ b/server/routers/hotels/schemas/room.ts @@ -0,0 +1,93 @@ +import { z } from "zod" + +import { imageMetaDataSchema, imageSizesSchema } from "./image" + +const roomContentSchema = z.object({ + images: z.array( + z.object({ + metaData: imageMetaDataSchema, + imageSizes: imageSizesSchema, + }) + ), + texts: z.object({ + descriptions: z.object({ + short: z.string(), + medium: z.string(), + }), + }), +}) + +const roomTypesSchema = z.object({ + name: z.string(), + description: z.string(), + code: z.string(), + roomCount: z.number(), + mainBed: z.object({ + type: z.string(), + description: z.string(), + widthRange: z.object({ + min: z.number(), + max: z.number(), + }), + }), + fixedExtraBed: z.object({ + type: z.string(), + description: z.string().optional(), + widthRange: z.object({ + min: z.number(), + max: z.number(), + }), + }), + roomSize: z.object({ + min: z.number(), + max: z.number(), + }), + occupancy: z.object({ + total: z.number(), + adults: z.number(), + children: z.number(), + }), + isLackingCribs: z.boolean(), + isLackingExtraBeds: z.boolean(), +}) + +const roomFacilitiesSchema = z.object({ + availableInAllRooms: z.boolean(), + name: z.string(), + isUniqueSellingPoint: z.boolean(), + sortOrder: z.number(), +}) + +export const roomSchema = z + .object({ + attributes: z.object({ + name: z.string(), + sortOrder: z.number(), + content: roomContentSchema, + roomTypes: z.array(roomTypesSchema), + roomFacilities: z.array(roomFacilitiesSchema), + occupancy: z.object({ + total: z.number(), + adults: z.number(), + children: z.number(), + }), + roomSize: z.object({ + min: z.number(), + max: z.number(), + }), + }), + id: z.string(), + type: z.enum(["roomcategories"]), + }) + .transform((data) => { + return { + descriptions: data.attributes.content.texts.descriptions, + id: data.id, + images: data.attributes.content.images, + name: data.attributes.name, + occupancy: data.attributes.occupancy, + roomSize: data.attributes.roomSize, + sortOrder: data.attributes.sortOrder, + type: data.type, + } + }) diff --git a/types/hotel.ts b/types/hotel.ts index 203e2423f..a60204720 100644 --- a/types/hotel.ts +++ b/types/hotel.ts @@ -5,8 +5,8 @@ import { getHotelDataSchema, parkingSchema, pointOfInterestSchema, - roomSchema, } from "@/server/routers/hotels/output" +import { roomSchema } from "@/server/routers/hotels/schemas/room" export type HotelData = z.infer