Files
web/server/routers/hotels/query.ts
2024-08-23 12:33:28 +02:00

170 lines
5.0 KiB
TypeScript

import * as api from "@/lib/api"
import { badRequestError } from "@/server/errors/trpc"
import { publicProcedure, router, serviceProcedure } from "@/server/trpc"
import { toApiLang } from "@/server/utils"
import {
getFiltersInputSchema,
getHotelInputSchema,
getRatesInputSchema,
} from "./input"
import {
getFiltersSchema,
getHotelDataSchema,
getRatesSchema,
roomSchema,
} from "./output"
import tempFilterData from "./tempFilterData.json"
import tempRatesData from "./tempRatesData.json"
export const hotelQueryRouter = router({
getHotel: serviceProcedure
.input(getHotelInputSchema)
.query(async ({ ctx, input }) => {
const { hotelId, language, include } = input
const apiLang = toApiLang(language)
const params: Record<string, string> = {
hotelId,
language: apiLang,
}
if (include) {
params.include = include.join(",")
}
console.info(
"api.hotels.hotel start",
JSON.stringify({
query: { hotelId, params: params.toString() },
})
)
const apiResponse = await api.get(
`${api.endpoints.v1.hotels}/${hotelId}`,
{
cache: "no-store",
headers: {
Authorization: `Bearer ${ctx.serviceToken}`,
},
},
params
)
if (!apiResponse.ok) {
const text = await apiResponse.text()
console.error(
"api.hotels.hotel error",
JSON.stringify({
query: { hotelId, params: params.toString() },
error: {
status: apiResponse.status,
statusText: apiResponse.statusText,
text,
},
})
)
return null
}
const apiJson = await apiResponse.json()
const validatedHotelData = getHotelDataSchema.safeParse(apiJson)
if (!validatedHotelData.success) {
console.error(
"api.hotels.hotel validation error",
JSON.stringify({
query: { hotelId, params: params.toString() },
error: validatedHotelData.error,
})
)
throw badRequestError()
}
const included = validatedHotelData.data.included || []
const roomCategories = included
? included
.filter((item) => item.type === "roomcategories")
.map((roomCategory) => {
const validatedRoom = roomSchema.safeParse(roomCategory)
if (!validatedRoom.success) {
console.error(
"api.hotels.hotel validation error",
JSON.stringify({
query: { hotelId, params: params.toString() },
error: validatedRoom.error,
})
)
throw badRequestError()
}
return validatedRoom.data
})
: []
console.info(
"api.hotels.hotel success",
JSON.stringify({
query: { hotelId, params: params.toString() },
})
)
return {
hotel: validatedHotelData.data.data.attributes,
roomCategories: roomCategories,
}
}),
getRates: publicProcedure
.input(getRatesInputSchema)
.query(async ({ input, ctx }) => {
// TODO: Do a real API call when the endpoint is ready
// const { hotelId } = input
// const params = new URLSearchParams()
// const apiLang = toApiLang(language)
// params.set("hotelId", hotelId.toString())
// params.set("language", apiLang)
console.info("api.hotels.rates start", JSON.stringify({}))
const validatedHotelData = getRatesSchema.safeParse(tempRatesData)
if (!tempRatesData) {
console.error("api.hotels.rates error", JSON.stringify({ error: null }))
//Can't return null here since consuming component does not handle null yet
// return null
}
if (!validatedHotelData.success) {
console.error(
"api.hotels.rates validation error",
JSON.stringify({
error: validatedHotelData.error,
})
)
throw badRequestError()
}
console.info("api.hotels.rates success", JSON.stringify({}))
return validatedHotelData.data
}),
getFilters: publicProcedure
.input(getFiltersInputSchema)
.query(async ({ input, ctx }) => {
console.info("api.hotels.filters start", JSON.stringify({}))
if (!tempFilterData) {
console.error(
"api.hotels.filters error",
JSON.stringify({ error: null })
)
//Can't return null here since consuming component does not handle null yet
// return null
}
const validateFilterData = getFiltersSchema.safeParse(tempFilterData)
if (!validateFilterData.success) {
console.error(
"api.hotels.filters validation error",
JSON.stringify({
error: validateFilterData.error,
})
)
throw badRequestError()
}
console.info("api.hotels.rates success", JSON.stringify({}))
return validateFilterData.data
}),
})