@revolugo/common 7.1.0 → 7.1.1-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/cancellation-policies.ts +1 -1
- package/src/constants/poller.ts +6 -0
- package/src/schemas/booking-policy.ts +51 -0
- package/src/schemas/cancellation-policies.ts +18 -13
- package/src/schemas/currency.ts +1 -1
- package/src/schemas/global.ts +139 -0
- package/src/schemas/hotel-offer.ts +40 -28
- package/src/schemas/hotel-room-offer.ts +20 -6
- package/src/schemas/hotel.ts +225 -258
- package/src/schemas/index.ts +2 -1
- package/src/schemas/list-polling-meta.ts +7 -2
- package/src/schemas/tag.ts +22 -8
- package/src/schemas/taxes.ts +4 -2
- package/src/types/elements/booking-policy.ts +1 -1
- package/src/types/elements/booking.ts +1 -1
- package/src/types/elements/contact-person.ts +4 -4
- package/src/types/elements/hotel-offer.ts +1 -1
- package/src/types/elements/hotel-room-offer-request.ts +1 -0
- package/src/types/elements/hotel-room-offer.ts +2 -2
- package/src/types/elements/hotel.ts +1 -1
- package/src/utils/omit.ts +2 -0
- package/src/utils/pick.ts +2 -0
- package/src/utils/shake.ts +1 -0
- package/src/schemas/hotel-offer-request.ts +0 -43
package/package.json
CHANGED
package/src/constants/poller.ts
CHANGED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
|
|
3
|
+
import { z } from 'zod'
|
|
4
|
+
|
|
5
|
+
import { CANCELLATION_POLICY_SCHEMA } from './cancellation-policies.ts'
|
|
6
|
+
import { CURRENCY_SCHEMA } from './currency.ts'
|
|
7
|
+
import {
|
|
8
|
+
ADULT_COUNT_SCHEMA,
|
|
9
|
+
CHECK_IN_DATE_SCHEMA,
|
|
10
|
+
CHECK_OUT_DATE_SCHEMA,
|
|
11
|
+
CHILDREN_SCHEMA,
|
|
12
|
+
IS_PRICE_INCREASED,
|
|
13
|
+
} from './global.ts'
|
|
14
|
+
import { HOTEL_ROOM_OFFER_SCHEMA } from './hotel-room-offer.ts'
|
|
15
|
+
|
|
16
|
+
export const BOOKING_POLICY_SCHEMA = z
|
|
17
|
+
.object({
|
|
18
|
+
adult_count: ADULT_COUNT_SCHEMA,
|
|
19
|
+
cancellation_policies: z.array(CANCELLATION_POLICY_SCHEMA).openapi({
|
|
20
|
+
description:
|
|
21
|
+
'The list of cancellation policy date range with their corresponding penalty percentage.',
|
|
22
|
+
}),
|
|
23
|
+
check_in_date: CHECK_IN_DATE_SCHEMA,
|
|
24
|
+
check_out_date: CHECK_OUT_DATE_SCHEMA,
|
|
25
|
+
children: CHILDREN_SCHEMA.optional().nullish(),
|
|
26
|
+
currency: CURRENCY_SCHEMA,
|
|
27
|
+
expires_at: z.coerce.date().openapi({
|
|
28
|
+
description:
|
|
29
|
+
'Expiration date for this **Booking Policy**.\n\nThe returned **Booking Policy** (price and cancellation policies) is valid bookable policy up to this **expires_at** date, while it may be valid for a longer period in the case of some suppliers, this API call is equivalent to an availability check and it is important not to let long periods between retrieval of this policy and the booking confirmation call itself as this will often reduce the likelihood of a **Hotel Room Offer** being successfully booked.',
|
|
30
|
+
}),
|
|
31
|
+
has_rooming_lists: z.boolean().openapi({
|
|
32
|
+
description:
|
|
33
|
+
'Indicates whether the **Booking Policy** supports rooming lists, allowing individual guest details to be provided per room.',
|
|
34
|
+
}),
|
|
35
|
+
hotel_id: z.string().openapi({
|
|
36
|
+
description: 'Hotel id',
|
|
37
|
+
}),
|
|
38
|
+
hotel_room_offer: HOTEL_ROOM_OFFER_SCHEMA.openapi({
|
|
39
|
+
description:
|
|
40
|
+
'The **Hotel Room Offer** associated with this **Booking Policy**.',
|
|
41
|
+
}),
|
|
42
|
+
id: z.string().openapi({
|
|
43
|
+
description: '**Booking Policy** id',
|
|
44
|
+
}),
|
|
45
|
+
is_price_increased: IS_PRICE_INCREASED,
|
|
46
|
+
})
|
|
47
|
+
.openapi('bookingPoliciesApi', {
|
|
48
|
+
description:
|
|
49
|
+
'A **Booking Policy** represents a validated and bookable snapshot of a **Hotel Room Offer**, including its price, cancellation policies, and expiration date.',
|
|
50
|
+
})
|
|
51
|
+
/* eslint-enable camelcase */
|
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
|
-
export const CANCELLATION_POLICY_SCHEMA = z
|
|
5
|
-
|
|
4
|
+
export const CANCELLATION_POLICY_SCHEMA = z
|
|
5
|
+
.object({
|
|
6
|
+
date_from: z.string().openapi({
|
|
7
|
+
description:
|
|
8
|
+
'The start date and time of the cancellation policy, given in the hotel timezone.',
|
|
9
|
+
}),
|
|
10
|
+
date_to: z.string().openapi({
|
|
11
|
+
description:
|
|
12
|
+
'The end date and time of the cancellation policy, given in the hotel timezone.',
|
|
13
|
+
}),
|
|
14
|
+
penalty_percentage: z.number().min(0).max(100).openapi({
|
|
15
|
+
description:
|
|
16
|
+
'The penalty percentage that is due in case of cancellation during the **date_from** to **date_to** period range.',
|
|
17
|
+
}),
|
|
18
|
+
})
|
|
19
|
+
.openapi('CancellationPolicyApi', {
|
|
6
20
|
description:
|
|
7
|
-
'
|
|
8
|
-
})
|
|
9
|
-
date_to: z.string().openapi({
|
|
10
|
-
description:
|
|
11
|
-
'The end date and time of the cancellation policy, given in the hotel timezone.',
|
|
12
|
-
}),
|
|
13
|
-
penalty_percentage: z.number().min(0).max(100).openapi({
|
|
14
|
-
description:
|
|
15
|
-
'The penalty percentage that is due in case of cancellation during the **date_from** to **date_to** period range.',
|
|
16
|
-
}),
|
|
17
|
-
})
|
|
21
|
+
'Defines the cancellation penalty that applies within a specific date and time range, expressed as a percentage of the booking cost.',
|
|
22
|
+
})
|
|
18
23
|
/* eslint-enable camelcase */
|
package/src/schemas/currency.ts
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/* eslint-disable camelcase */
|
|
2
|
+
import { z } from 'zod'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
BreakfastOption,
|
|
6
|
+
CountryIso2Code,
|
|
7
|
+
Locale,
|
|
8
|
+
Status,
|
|
9
|
+
} from '../constants/index.ts'
|
|
10
|
+
|
|
11
|
+
export const validStringDate = (): z.ZodString =>
|
|
12
|
+
z
|
|
13
|
+
.string()
|
|
14
|
+
.regex(/^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/u)
|
|
15
|
+
|
|
16
|
+
export const ADD_BREAKFAST_SCHEMA = z
|
|
17
|
+
.boolean()
|
|
18
|
+
.nullish()
|
|
19
|
+
.openapi('addBreakfast', {
|
|
20
|
+
description: `This parameter allows to add breakfast to the booking as long as every requested Hotel Room Offers **breakfast_option = ${BreakfastOption.Optional}** .\n\nThe final breakfast count that will be included in the Hotel Room Offer will be returned in the response and is calculated as follows: \n\n - If the returned Hotel Room Offer **total room count** > **hotel_room_offer_request.adult_count** then **breakfast_count** will be equal to the **total room count** of the returned Hotel Room Offer, \n\n - Otherwise **breakfast_count** will be equal to the minimum value between related **hotel_room_offer_request.adult_count** and returned Hotel Room Offer **total occupancy**. \n\n <div style="background-color: #ffffef; padding: 20px; border: 1px solid lightgrey; border-radius: 5px;"><b style="color: red; margin-top: 10px;">🛑 DEPRECATED.</b>\n\n <b style="color: orange;">If you already use this field, don't worry as we still support it with the following behaviour:</b>\n- <span style="color: orange;">When **add_breakfast = true** then **breakfast_count = MIN(guest count, total offer occupancy)** where **guest count** is the total number of adult and children over 3.</span>\n- <span style="color: orange;">Otherwise **breakfast_count = 0**.</span></div>`,
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
export const ADULT_COUNT_SCHEMA = z
|
|
24
|
+
.number()
|
|
25
|
+
.int()
|
|
26
|
+
.min(1)
|
|
27
|
+
.max(200)
|
|
28
|
+
.openapi('adultCount', {
|
|
29
|
+
description:
|
|
30
|
+
'The total number of adults who will be staying in the property.',
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
export const BREAKFAST_COUNT = z
|
|
34
|
+
.number()
|
|
35
|
+
.optional()
|
|
36
|
+
.openapi('breakfastCount', {
|
|
37
|
+
description: `This parameter describes the quantity of breakfast / night that should be included in the **Booking**. When **breakfast_option = ${BreakfastOption.Optional}**, valid **breakfast_count** lower bound is **room count** and upper bound is **guest count**, where **guest count** is the number of adult and children over 3.\n\n⚠️ The actual breakfast count that will be included in the **Booking** is the one that is returned in the response of this endpoint and might be different from this **breakfast_count** paramater in some cases. Please, make sure to check the actual breakfast count included in the **Hotel Room Offer** returned in the response of this endpoint.`,
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
export const CHECK_IN_DATE_SCHEMA = validStringDate().openapi('checkInDate', {
|
|
41
|
+
description: 'Date of check-in formatted as YYYY-MM-DD.',
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
export const CHECK_OUT_DATE_SCHEMA = validStringDate().openapi('checkOutDate', {
|
|
45
|
+
description: 'Date of check-out formatted as YYYY-MM-DD.',
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
export const CHILDREN_SCHEMA = z
|
|
49
|
+
.string()
|
|
50
|
+
.regex(/^(([0-9]{1})|(1[0-7]){1})(,(([0-9]{1})|(1[0-7]){1}))*$|^$/u)
|
|
51
|
+
.openapi('children', {
|
|
52
|
+
description:
|
|
53
|
+
'A comma-separated list of child ages (0 up to 17). e.g.: "3,7" represents 2 children respectively 3 and 7 years old.',
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
export const IMAGES_SCHEMA = z
|
|
57
|
+
.object({
|
|
58
|
+
count: z.number().openapi({ description: 'Number of images.' }).nullish(),
|
|
59
|
+
highres: z
|
|
60
|
+
.boolean()
|
|
61
|
+
.openapi({ description: 'Whether images exist in highres format.' })
|
|
62
|
+
.nullish(),
|
|
63
|
+
|
|
64
|
+
lowres: z
|
|
65
|
+
.boolean()
|
|
66
|
+
.openapi({ description: 'Whether images exist in lowres format.' })
|
|
67
|
+
.nullish(),
|
|
68
|
+
prefix: z
|
|
69
|
+
.string()
|
|
70
|
+
.openapi({ description: 'Base URL for the images.' })
|
|
71
|
+
.nullish(),
|
|
72
|
+
suffix: z
|
|
73
|
+
.string()
|
|
74
|
+
.openapi({
|
|
75
|
+
description:
|
|
76
|
+
'This parameter usually represents the extension of the image (e.g.: .jpg, .png)',
|
|
77
|
+
})
|
|
78
|
+
.nullish(),
|
|
79
|
+
thumb: z
|
|
80
|
+
.boolean()
|
|
81
|
+
.openapi({
|
|
82
|
+
description:
|
|
83
|
+
'Whether images exist in thumb format (for thumbnails preview).',
|
|
84
|
+
})
|
|
85
|
+
.nullish(),
|
|
86
|
+
})
|
|
87
|
+
.openapi({
|
|
88
|
+
description:
|
|
89
|
+
'🛑 DEPRECATED - Hotel images details.\n\nIn order to retrieve a specific image you need to construct the complete URL from the images parameters: **[images.prefix][highres|lowres|thumb]/[index]/[images.suffix]**. If **images.count = n**, then index is in [0...n-1] range.\n\ne.g.: https://s3.eu-west-3.amazonaws.com/revolugo/hotels/yhKY/images/highres/0.jpg',
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
export const IS_PRICE_INCREASED = z.boolean().openapi({
|
|
93
|
+
description:
|
|
94
|
+
'Indicates whether the price of the **Hotel Room Offer** (without breakfast included) has increased compared to the price returned by [Retrieve Hotel Room Offers endpoint](/v1/documentation#operation/getV1Hotel_room_offers).\n\nIn some case, the returned price may increase for various reasons including: Currency rate change between the POST **Booking Policies** call and the GET **Hotel Room Offers** call, **Hotel Room Offer** price has increased since the GET **Hotel Room Offers** call.\n\nIf **is_price_increased** is **true**, it means that the actual/updated price of the **Hotel Room Offer** is greater than the price previously returned by [Retrieve Hotel Room Offers endpoint](/v1/documentation#operation/getV1Hotel_room_offers). If **is_price_increased** is **false**, the price of the **Hotel Room Offer** is equal to the price returned by [Retrieve Hotel Room Offers endpoint](/v1/documentation#operation/getV1Hotel_room_offers).\n\n⚠️ It is strongly advised to clearly inform your customer of any price increase that may occur.',
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
export const LANG_SCHEMA = z
|
|
98
|
+
.enum(Locale)
|
|
99
|
+
.openapi('Locale', {
|
|
100
|
+
description:
|
|
101
|
+
'Set the language for the returned content using a valid language code.',
|
|
102
|
+
enum: Object.values(Locale),
|
|
103
|
+
})
|
|
104
|
+
.default(Locale.en_US)
|
|
105
|
+
|
|
106
|
+
export const META = z
|
|
107
|
+
.object({
|
|
108
|
+
status: z
|
|
109
|
+
.enum(Status)
|
|
110
|
+
.openapi('Status', { description: 'Status of the response.' }),
|
|
111
|
+
})
|
|
112
|
+
.openapi('Meta', { description: 'Meta data of the response' })
|
|
113
|
+
|
|
114
|
+
export const ROOM_COUNT_SCHEMA = z
|
|
115
|
+
.number()
|
|
116
|
+
.min(1)
|
|
117
|
+
.max(200)
|
|
118
|
+
.openapi('RoomCount', {
|
|
119
|
+
description:
|
|
120
|
+
'The total number of rooms requested for the stay. Results may display offers matching a different room count than the requested one, however those results will always provide enough occupancy for the total guest count needed.\n\nConstraint: The **room_count** cannot be greater than the requested guest count (adult and children guests) and the minimum **room_count** cannot be less than the total guest count (adult and children guests) divided by 4, meaning that the maximum number of guest in a single room cannot be greeater than 4.',
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
export const COUNTRY_ISO2_CODE_SCHEMA = z
|
|
124
|
+
.enum(CountryIso2Code)
|
|
125
|
+
.refine(check => Object.values(CountryIso2Code).includes(check), {
|
|
126
|
+
message: 'Invalid ISO Alpha-2 country code.',
|
|
127
|
+
})
|
|
128
|
+
.openapi('CountryIso2Code', {
|
|
129
|
+
description: 'ISO Alpha-2 country code.',
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
export const SOURCE_MARKET_SCHEMA = COUNTRY_ISO2_CODE_SCHEMA.openapi(
|
|
133
|
+
'SourceMarket',
|
|
134
|
+
{
|
|
135
|
+
description:
|
|
136
|
+
'For sourcing availability within certain markets, a source market option may be used to get more accurate prices. You may use any valid ISO Alpha-2 country code, e.g. JP.',
|
|
137
|
+
},
|
|
138
|
+
)
|
|
139
|
+
/* eslint-enable camelcase */
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
CHECK_IN_DATE_SCHEMA,
|
|
8
8
|
CHECK_OUT_DATE_SCHEMA,
|
|
9
9
|
CHILDREN_SCHEMA,
|
|
10
|
-
} from './
|
|
10
|
+
} from './global.ts'
|
|
11
11
|
import { HOTEL_ROOM_OFFER_SCHEMA } from './hotel-room-offer.ts'
|
|
12
12
|
import { HOTEL_IMAGES, HOTEL_SCHEMA, VENUES_SCHEMA } from './hotel.ts'
|
|
13
13
|
import { LIST_POLLING_META_SCHEMA } from './list-polling-meta.ts'
|
|
@@ -23,34 +23,46 @@ List of hotel images in various sizes featuring an indicator for the primary (he
|
|
|
23
23
|
hotel_room_offers: z.array(HOTEL_ROOM_OFFER_SCHEMA),
|
|
24
24
|
tags: TAGS_SCHEMA,
|
|
25
25
|
venues: VENUES_SCHEMA,
|
|
26
|
-
}).openapi('hotelOfferApi'
|
|
26
|
+
}).openapi('hotelOfferApi', {
|
|
27
|
+
description:
|
|
28
|
+
'Hotel Offer combining hotel details with available Hotel Room Offers.',
|
|
29
|
+
})
|
|
27
30
|
|
|
28
|
-
export const HOTEL_OFFERS_SCHEMA = z.array(HOTEL_OFFER_SCHEMA)
|
|
31
|
+
export const HOTEL_OFFERS_SCHEMA = z.array(HOTEL_OFFER_SCHEMA).openapi({
|
|
32
|
+
description: 'List of Hotel Offers.',
|
|
33
|
+
})
|
|
29
34
|
|
|
30
|
-
export const HOTEL_OFFERS_RESPONSE_SCHEMA = z
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
35
|
+
export const HOTEL_OFFERS_RESPONSE_SCHEMA = z
|
|
36
|
+
.object({
|
|
37
|
+
data: z.object({
|
|
38
|
+
adult_count: ADULT_COUNT_SCHEMA,
|
|
39
|
+
check_in_date: CHECK_IN_DATE_SCHEMA,
|
|
40
|
+
check_out_date: CHECK_OUT_DATE_SCHEMA,
|
|
41
|
+
children: CHILDREN_SCHEMA.optional().nullish(),
|
|
42
|
+
currency: CURRENCY_SCHEMA,
|
|
43
|
+
hotel_offers: HOTEL_OFFERS_SCHEMA.openapi({
|
|
44
|
+
description: 'List of Hotel Offers',
|
|
45
|
+
}),
|
|
46
|
+
price_histogram: z
|
|
47
|
+
.array(z.number())
|
|
48
|
+
.openapi({
|
|
49
|
+
description:
|
|
50
|
+
'**Hotel Offers** price histogram dataset based on the price of the cheapest **Hotel Room Offer** included on each **Hotel Offer** returned. It represents the number of available **Hotel Offers** grouped by price sorted ascendingly. Each item of the list represents a price step based on returned **price_min**, **price_max** and requested **price_histogram_step_count**',
|
|
51
|
+
})
|
|
52
|
+
.nullish(),
|
|
53
|
+
price_max: z.number().nullish().openapi({
|
|
54
|
+
description: 'Maximum price of available returned **Hotel Offers**',
|
|
55
|
+
}),
|
|
56
|
+
price_min: z.number().nullish().openapi({
|
|
57
|
+
description: 'Minimum price of available returned **Hotel Offers**',
|
|
58
|
+
}),
|
|
49
59
|
}),
|
|
50
|
-
|
|
51
|
-
description:
|
|
60
|
+
event: z.any().optional().openapi({
|
|
61
|
+
description:
|
|
62
|
+
'Event associated with the Hotel Offers response, when applicable.',
|
|
52
63
|
}),
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
64
|
+
meta: LIST_POLLING_META_SCHEMA,
|
|
65
|
+
})
|
|
66
|
+
.openapi({
|
|
67
|
+
description: 'Response envelope for the Hotel Offers polling endpoint.',
|
|
68
|
+
})
|
|
@@ -10,12 +10,17 @@ import {
|
|
|
10
10
|
|
|
11
11
|
import { CANCELLATION_POLICY_SCHEMA } from './cancellation-policies.ts'
|
|
12
12
|
import { CURRENCY_SCHEMA } from './currency.ts'
|
|
13
|
-
import { SOURCE_MARKET_SCHEMA } from './
|
|
13
|
+
import { SOURCE_MARKET_SCHEMA } from './global.ts'
|
|
14
14
|
import { HOTEL_ROOMS_SCHEMA } from './hotel-room.ts'
|
|
15
|
+
import { HOTEL_IMAGE } from './hotel.ts'
|
|
15
16
|
import { LIST_POLLING_META_SCHEMA } from './list-polling-meta.ts'
|
|
16
17
|
import { TAGS_SCHEMA } from './tag.ts'
|
|
17
18
|
import { TAXES_SCHEMA } from './taxes.ts'
|
|
18
19
|
|
|
20
|
+
export const HOTEL_ROOM_OFFERS_IMAGES = z.array(z.array(HOTEL_IMAGE)).openapi({
|
|
21
|
+
description:
|
|
22
|
+
'List of hotel room offer images in various sizes featuring an indicator for the primary (hero) image',
|
|
23
|
+
})
|
|
19
24
|
export const BREAKFAST_OPTION_DESCRIPTION = `This parameter describes the breakfast option for the given **Hotel Room Offer**:
|
|
20
25
|
- **breakfast_option = "${BreakfastOption.Included}"**:
|
|
21
26
|
1. When **HotelRoomOffer.type = "${HotelRoomOfferType.Package}"**:
|
|
@@ -95,10 +100,19 @@ export const HOTEL_ROOM_OFFER_SCHEMA = z
|
|
|
95
100
|
description: 'Description of the Hotel Room Offer.',
|
|
96
101
|
})
|
|
97
102
|
|
|
98
|
-
export const HOTEL_ROOM_OFFERS_SCHEMA = z
|
|
103
|
+
export const HOTEL_ROOM_OFFERS_SCHEMA = z
|
|
104
|
+
.array(HOTEL_ROOM_OFFER_SCHEMA)
|
|
105
|
+
.openapi({
|
|
106
|
+
description: 'List of Hotel Room Offers.',
|
|
107
|
+
})
|
|
99
108
|
|
|
100
|
-
export const HOTEL_ROOM_OFFERS_RESPONSE_SCHEMA = z
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
export const HOTEL_ROOM_OFFERS_RESPONSE_SCHEMA = z
|
|
110
|
+
.object({
|
|
111
|
+
data: HOTEL_ROOM_OFFERS_SCHEMA,
|
|
112
|
+
meta: LIST_POLLING_META_SCHEMA,
|
|
113
|
+
})
|
|
114
|
+
.openapi({
|
|
115
|
+
description:
|
|
116
|
+
'Response envelope for the Hotel Room Offers polling endpoint.',
|
|
117
|
+
})
|
|
104
118
|
/* eslint-enable camelcase */
|
package/src/schemas/hotel.ts
CHANGED
|
@@ -4,159 +4,185 @@ import { z } from 'zod'
|
|
|
4
4
|
import { CountryIso2Code } from '../constants/index.ts'
|
|
5
5
|
|
|
6
6
|
import { CURRENCY_SCHEMA } from './currency.ts'
|
|
7
|
+
import { IMAGES_SCHEMA } from './global.ts'
|
|
7
8
|
|
|
8
|
-
export const AMENITIES_SCHEMA = z
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
.boolean()
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
.optional()
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
.boolean()
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
.openapi({ description: '
|
|
135
|
-
|
|
136
|
-
.boolean()
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
9
|
+
export const AMENITIES_SCHEMA = z
|
|
10
|
+
.object({
|
|
11
|
+
air_conditioning: z
|
|
12
|
+
.boolean()
|
|
13
|
+
.optional()
|
|
14
|
+
.openapi({ description: 'Air conditioning.' }),
|
|
15
|
+
airport_transportation: z
|
|
16
|
+
.boolean()
|
|
17
|
+
.optional()
|
|
18
|
+
.openapi({ description: 'Airport transportation service.' }),
|
|
19
|
+
business_center: z
|
|
20
|
+
.boolean()
|
|
21
|
+
.optional()
|
|
22
|
+
.openapi({ description: 'Business center.' }),
|
|
23
|
+
car_rent_desk: z
|
|
24
|
+
.boolean()
|
|
25
|
+
.optional()
|
|
26
|
+
.openapi({ description: 'Car rental desk service.' }),
|
|
27
|
+
children_allowed: z
|
|
28
|
+
.boolean()
|
|
29
|
+
.optional()
|
|
30
|
+
.openapi({ description: 'Children welcomed.' }),
|
|
31
|
+
clothing_iron: z
|
|
32
|
+
.boolean()
|
|
33
|
+
.optional()
|
|
34
|
+
.openapi({ description: 'Clothing iron.' }),
|
|
35
|
+
coffee_tea_maker: z
|
|
36
|
+
.boolean()
|
|
37
|
+
.optional()
|
|
38
|
+
.openapi({ description: 'Coffea/tea maker.' }),
|
|
39
|
+
combination: z
|
|
40
|
+
.boolean()
|
|
41
|
+
.optional()
|
|
42
|
+
.openapi({ description: 'Combination.' }),
|
|
43
|
+
continental_breakfast: z
|
|
44
|
+
.boolean()
|
|
45
|
+
.optional()
|
|
46
|
+
.openapi({ description: 'Continental Breakfast.' }),
|
|
47
|
+
data_ports: z
|
|
48
|
+
.boolean()
|
|
49
|
+
.optional()
|
|
50
|
+
.openapi({ description: 'Data ports in room.' }),
|
|
51
|
+
dry_cleaning: z
|
|
52
|
+
.boolean()
|
|
53
|
+
.optional()
|
|
54
|
+
.openapi({ description: 'Dry cleaning.' }),
|
|
55
|
+
electronic_room_keys: z
|
|
56
|
+
.boolean()
|
|
57
|
+
.optional()
|
|
58
|
+
.openapi({ description: 'Electornic room keys.' }),
|
|
59
|
+
exterior_room_entrance: z
|
|
60
|
+
.boolean()
|
|
61
|
+
.optional()
|
|
62
|
+
.openapi({ description: 'Exterior room entrance.' }),
|
|
63
|
+
family_rooms: z
|
|
64
|
+
.boolean()
|
|
65
|
+
.optional()
|
|
66
|
+
.openapi({ description: 'Family rooms.' }),
|
|
67
|
+
fitness_facility: z
|
|
68
|
+
.boolean()
|
|
69
|
+
.optional()
|
|
70
|
+
.openapi({ description: 'Fitness facility.' }),
|
|
71
|
+
game_room: z.boolean().optional().openapi({ description: 'Game room.' }),
|
|
72
|
+
golf_course: z
|
|
73
|
+
.boolean()
|
|
74
|
+
.optional()
|
|
75
|
+
.openapi({ description: 'Golf course.' }),
|
|
76
|
+
hair_dryer: z.boolean().optional().openapi({ description: 'Hair dryer.' }),
|
|
77
|
+
handicap_accessible: z
|
|
78
|
+
.boolean()
|
|
79
|
+
.optional()
|
|
80
|
+
.openapi({ description: 'Handicap Accessible.' }),
|
|
81
|
+
in_house_bar: z
|
|
82
|
+
.boolean()
|
|
83
|
+
.optional()
|
|
84
|
+
.openapi({ description: 'In house bar.' }),
|
|
85
|
+
in_house_dining: z
|
|
86
|
+
.boolean()
|
|
87
|
+
.optional()
|
|
88
|
+
.openapi({ description: 'In house dining.' }),
|
|
89
|
+
in_room_movies: z
|
|
90
|
+
.boolean()
|
|
91
|
+
.optional()
|
|
92
|
+
.openapi({ description: 'In room movies.' }),
|
|
93
|
+
indoor_pool: z
|
|
94
|
+
.boolean()
|
|
95
|
+
.optional()
|
|
96
|
+
.openapi({ description: 'Indoor pool.' }),
|
|
97
|
+
interior_room_entrance: z
|
|
98
|
+
.boolean()
|
|
99
|
+
.optional()
|
|
100
|
+
.openapi({ description: 'Interior room entrance.' }),
|
|
101
|
+
kitchen: z.boolean().optional().openapi({ description: 'Kitchen.' }),
|
|
102
|
+
map: z.boolean().optional().openapi({ description: 'Map.' }),
|
|
103
|
+
meeting_rooms: z
|
|
104
|
+
.boolean()
|
|
105
|
+
.optional()
|
|
106
|
+
.openapi({ description: 'Meeting rooms.' }),
|
|
107
|
+
mini_bar_in_room: z
|
|
108
|
+
.boolean()
|
|
109
|
+
.optional()
|
|
110
|
+
.openapi({ description: 'mini bar in room.' }),
|
|
111
|
+
non_smoking_rooms: z
|
|
112
|
+
.boolean()
|
|
113
|
+
.optional()
|
|
114
|
+
.openapi({ description: 'Non smoking rooms.' }),
|
|
115
|
+
outdoor_pool: z
|
|
116
|
+
.boolean()
|
|
117
|
+
.optional()
|
|
118
|
+
.openapi({ description: 'Outdoor pool.' }),
|
|
119
|
+
parking_garage: z
|
|
120
|
+
.boolean()
|
|
121
|
+
.optional()
|
|
122
|
+
.openapi({ description: 'Parking garage.' }),
|
|
123
|
+
pets_allowed: z
|
|
124
|
+
.boolean()
|
|
125
|
+
.optional()
|
|
126
|
+
.openapi({ description: 'Pets allowed.' }),
|
|
127
|
+
restricted_access: z
|
|
128
|
+
.boolean()
|
|
129
|
+
.optional()
|
|
130
|
+
.openapi({ description: 'Restricted access.' }),
|
|
131
|
+
room_service: z
|
|
132
|
+
.boolean()
|
|
133
|
+
.optional()
|
|
134
|
+
.openapi({ description: 'Room service.' }),
|
|
135
|
+
safe: z.boolean().optional().openapi({ description: 'Safe in room.' }),
|
|
136
|
+
sauna: z.boolean().optional().openapi({ description: 'Sauna.' }),
|
|
137
|
+
t_v_in_room: z.boolean().optional().openapi({ description: 'TV in room.' }),
|
|
138
|
+
tennis_court: z
|
|
139
|
+
.boolean()
|
|
140
|
+
.optional()
|
|
141
|
+
.openapi({ description: 'Tennis court.' }),
|
|
142
|
+
twenty_four_hour_security: z
|
|
143
|
+
.boolean()
|
|
144
|
+
.optional()
|
|
145
|
+
.openapi({ description: ' 24/7 security.' }),
|
|
146
|
+
valet_parking: z
|
|
147
|
+
.boolean()
|
|
148
|
+
.optional()
|
|
149
|
+
.openapi({ description: 'Valet parking.' }),
|
|
150
|
+
video_check_out: z
|
|
151
|
+
.boolean()
|
|
152
|
+
.optional()
|
|
153
|
+
.openapi({ description: 'Video check out.' }),
|
|
154
|
+
voice_mail: z.boolean().optional().openapi({ description: 'Voice mail.' }),
|
|
155
|
+
wake_up_service: z
|
|
156
|
+
.boolean()
|
|
157
|
+
.optional()
|
|
158
|
+
.openapi({ description: 'Wake up service.' }),
|
|
159
|
+
whirpool: z.boolean().optional().openapi({ description: 'Whirpool.' }),
|
|
160
|
+
})
|
|
161
|
+
.openapi('hotelAmenitiesApi', {
|
|
162
|
+
description: 'Amenities available at the hotel.',
|
|
163
|
+
})
|
|
150
164
|
|
|
151
|
-
export const HOTEL_IMAGE = z
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
165
|
+
export const HOTEL_IMAGE = z
|
|
166
|
+
.object({
|
|
167
|
+
caption: z
|
|
168
|
+
.string()
|
|
169
|
+
.nullish()
|
|
170
|
+
.openapi({ description: 'Caption of the hotel image.' }),
|
|
171
|
+
is_hero_image: z.boolean().openapi({
|
|
172
|
+
description:
|
|
173
|
+
'Whether this image is the primary (hero) image of the hotel.',
|
|
174
|
+
}),
|
|
175
|
+
l: z.string().openapi({ description: 'URL of the large-size image.' }),
|
|
176
|
+
m: z.string().openapi({ description: 'URL of the medium-size image.' }),
|
|
177
|
+
s: z.string().openapi({ description: 'URL of the small-size image.' }),
|
|
178
|
+
xl: z
|
|
179
|
+
.string()
|
|
180
|
+
.openapi({ description: 'URL of the extra-large-size image.' }),
|
|
181
|
+
xs: z
|
|
182
|
+
.string()
|
|
183
|
+
.openapi({ description: 'URL of the extra-small-size image.' }),
|
|
184
|
+
})
|
|
185
|
+
.openapi('hotelImageApi', { description: 'Hotel image in various sizes.' })
|
|
160
186
|
|
|
161
187
|
export const HOTEL_IMAGES = z.array(HOTEL_IMAGE).openapi({
|
|
162
188
|
description:
|
|
@@ -170,8 +196,7 @@ export const HOTEL_REVIEW_RATING_SCHEMA = z
|
|
|
170
196
|
.openapi({
|
|
171
197
|
description: 'Category of the collected reviews for the Hotel.',
|
|
172
198
|
})
|
|
173
|
-
.nullish()
|
|
174
|
-
.optional(),
|
|
199
|
+
.nullish(),
|
|
175
200
|
rating: z.number().openapi({
|
|
176
201
|
description: 'Rating of the collected review for the Hotel.',
|
|
177
202
|
}),
|
|
@@ -187,174 +212,116 @@ export const HOTEL_REVIEW_RATINGS_SCHEMA = z
|
|
|
187
212
|
'List of meta reviews (category and rating) that are summary of verified reviews collected across the web on the Hotel to help choose the best option.',
|
|
188
213
|
})
|
|
189
214
|
|
|
190
|
-
export const
|
|
191
|
-
.
|
|
192
|
-
|
|
193
|
-
.
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
'This parameter usually represents the extension of the image (e.g.: .jpg, .png)',
|
|
215
|
+
export const VENUES_SCHEMA = z
|
|
216
|
+
.array(
|
|
217
|
+
z
|
|
218
|
+
.object({
|
|
219
|
+
description: z.string().nullish().openapi({
|
|
220
|
+
description: 'Description of the venue or point of interest.',
|
|
221
|
+
}),
|
|
222
|
+
name: z
|
|
223
|
+
.string()
|
|
224
|
+
.openapi({ description: 'Name of the venue or point of interest.' }),
|
|
225
|
+
travel_times: z
|
|
226
|
+
.object({
|
|
227
|
+
driving: z.number().optional().openapi({
|
|
228
|
+
description: 'Driving travel time to the venue in minutes.',
|
|
229
|
+
}),
|
|
230
|
+
transit: z.number().optional().openapi({
|
|
231
|
+
description: 'Transit travel time to the venue in minutes.',
|
|
232
|
+
}),
|
|
233
|
+
walking: z.number().optional().openapi({
|
|
234
|
+
description: 'Walking travel time to the venue in minutes.',
|
|
235
|
+
}),
|
|
236
|
+
})
|
|
237
|
+
.nullish()
|
|
238
|
+
.openapi({
|
|
239
|
+
description:
|
|
240
|
+
'Estimated travel times to the venue by transport mode.',
|
|
241
|
+
}),
|
|
218
242
|
})
|
|
219
|
-
.optional()
|
|
220
|
-
.nullish(),
|
|
221
|
-
thumb: z
|
|
222
|
-
.boolean()
|
|
223
243
|
.openapi({
|
|
224
|
-
description:
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
.nullish(),
|
|
229
|
-
})
|
|
244
|
+
description: 'A venue or point of interest near the hotel.',
|
|
245
|
+
}),
|
|
246
|
+
)
|
|
247
|
+
.optional()
|
|
230
248
|
.openapi({
|
|
231
249
|
description:
|
|
232
|
-
'
|
|
250
|
+
'List of nearby venues or points of interest (e.g. airports, stadiums) with estimated travel times.',
|
|
233
251
|
})
|
|
234
252
|
|
|
235
|
-
export const VENUES_SCHEMA = z
|
|
236
|
-
.array(
|
|
237
|
-
z.object({
|
|
238
|
-
description: z.string().optional().nullish(),
|
|
239
|
-
name: z.string(),
|
|
240
|
-
travel_times: z
|
|
241
|
-
.object({
|
|
242
|
-
driving: z.number().optional(),
|
|
243
|
-
transit: z.number().optional(),
|
|
244
|
-
walking: z.number().optional(),
|
|
245
|
-
})
|
|
246
|
-
.optional()
|
|
247
|
-
.nullish(),
|
|
248
|
-
}),
|
|
249
|
-
)
|
|
250
|
-
.optional()
|
|
251
253
|
export const HOTEL_SCHEMA = z
|
|
252
254
|
.object({
|
|
253
|
-
address: z
|
|
254
|
-
.string()
|
|
255
|
-
.openapi({ description: 'Hotel address.' })
|
|
256
|
-
.optional()
|
|
257
|
-
.nullish(),
|
|
255
|
+
address: z.string().openapi({ description: 'Hotel address.' }).nullish(),
|
|
258
256
|
address2: z
|
|
259
257
|
.string()
|
|
260
258
|
.openapi({ description: 'Second part of hotel address.' })
|
|
261
|
-
.optional()
|
|
262
259
|
.nullish(),
|
|
263
|
-
amenities: AMENITIES_SCHEMA.nullish()
|
|
260
|
+
amenities: AMENITIES_SCHEMA.nullish().openapi({
|
|
261
|
+
description: 'Hotel amenities.',
|
|
262
|
+
}),
|
|
264
263
|
check_in_time: z
|
|
265
264
|
.string()
|
|
266
265
|
.openapi({ description: 'Check in time of the hotel.' })
|
|
267
|
-
.optional()
|
|
268
266
|
.nullish(),
|
|
269
267
|
check_out_time: z
|
|
270
268
|
.string()
|
|
271
269
|
.openapi({ description: 'Check out time of the hotel.' })
|
|
272
|
-
.optional()
|
|
273
|
-
.nullish(),
|
|
274
|
-
city: z.string().openapi({ description: 'City' }).optional().nullish(),
|
|
275
|
-
country: z
|
|
276
|
-
.string()
|
|
277
|
-
.openapi({ description: 'Country' })
|
|
278
|
-
.optional()
|
|
279
270
|
.nullish(),
|
|
271
|
+
city: z.string().openapi({ description: 'City' }).nullish(),
|
|
272
|
+
country: z.string().openapi({ description: 'Country' }).nullish(),
|
|
280
273
|
country_code: z
|
|
281
274
|
.string()
|
|
282
275
|
.refine(check =>
|
|
283
276
|
Object.values(CountryIso2Code).includes(check as CountryIso2Code),
|
|
284
277
|
)
|
|
285
278
|
.openapi({ description: 'Hotel country code in ISO2.' })
|
|
286
|
-
.optional()
|
|
287
|
-
.nullish(),
|
|
288
|
-
currency: CURRENCY_SCHEMA.openapi({ description: 'Hotel currency.' })
|
|
289
|
-
.optional()
|
|
290
279
|
.nullish(),
|
|
280
|
+
currency: CURRENCY_SCHEMA.openapi({
|
|
281
|
+
description: 'Hotel currency.',
|
|
282
|
+
}).nullish(),
|
|
291
283
|
description: z
|
|
292
284
|
.string()
|
|
293
285
|
.openapi({ description: 'Hotel description.' })
|
|
294
|
-
.optional()
|
|
295
286
|
.nullish(),
|
|
296
287
|
distance: z
|
|
297
288
|
.number()
|
|
298
|
-
.optional()
|
|
299
289
|
.openapi({
|
|
300
290
|
description: 'Distance from a requested location, expressed in meters',
|
|
301
291
|
})
|
|
302
|
-
.optional()
|
|
303
|
-
.nullish(),
|
|
304
|
-
email: z
|
|
305
|
-
.string()
|
|
306
|
-
.openapi({ description: 'Hotel email.' })
|
|
307
|
-
.optional()
|
|
308
|
-
.nullish(),
|
|
309
|
-
fax: z
|
|
310
|
-
.string()
|
|
311
|
-
.openapi({ description: 'Hotel fax number.' })
|
|
312
|
-
.optional()
|
|
313
292
|
.nullish(),
|
|
293
|
+
email: z.string().openapi({ description: 'Hotel email.' }).nullish(),
|
|
294
|
+
fax: z.string().openapi({ description: 'Hotel fax number.' }).nullish(),
|
|
314
295
|
hotel_images: HOTEL_IMAGES.nullish(),
|
|
315
|
-
hotel_review_ratings: HOTEL_REVIEW_RATINGS_SCHEMA.
|
|
296
|
+
hotel_review_ratings: HOTEL_REVIEW_RATINGS_SCHEMA.nullish(),
|
|
316
297
|
id: z.string().openapi({ description: 'Hotel id.' }),
|
|
317
298
|
images: IMAGES_SCHEMA.nullish(),
|
|
318
299
|
latitude: z.number().openapi({ description: 'Hotel latitude.' }),
|
|
319
300
|
longitude: z.number().openapi({ description: 'Hotel longitude.' }),
|
|
320
301
|
name: z.string().openapi({ description: 'Hotel name.' }),
|
|
321
|
-
phone: z
|
|
322
|
-
.string()
|
|
323
|
-
.openapi({ description: 'Hotel phone number.' })
|
|
324
|
-
.optional()
|
|
325
|
-
.nullish(),
|
|
302
|
+
phone: z.string().openapi({ description: 'Hotel phone number.' }).nullish(),
|
|
326
303
|
policy: z
|
|
327
304
|
.string()
|
|
328
305
|
.openapi({ description: 'Internal policy of the hotel.' })
|
|
329
|
-
.optional()
|
|
330
306
|
.nullish(),
|
|
331
307
|
postal_code: z
|
|
332
308
|
.string()
|
|
333
309
|
.openapi({ description: 'Hotel address postal code.' })
|
|
334
|
-
.optional()
|
|
335
310
|
.nullish(),
|
|
336
|
-
rating: z
|
|
337
|
-
.number()
|
|
338
|
-
.optional()
|
|
339
|
-
.nullish()
|
|
340
|
-
.openapi({ description: 'Hotel Star rating.' }),
|
|
311
|
+
rating: z.number().nullish().openapi({ description: 'Hotel Star rating.' }),
|
|
341
312
|
state: z
|
|
342
313
|
.string()
|
|
343
314
|
.openapi({ description: 'Hotel address state.' })
|
|
344
|
-
.optional()
|
|
345
315
|
.nullish(),
|
|
346
316
|
ta_id: z
|
|
347
317
|
.string()
|
|
348
|
-
.optional()
|
|
349
318
|
.openapi({ description: 'TripAdvisor property id. When applicable.' })
|
|
350
|
-
.optional()
|
|
351
319
|
.nullish(),
|
|
352
320
|
timezone: z.string().openapi({ description: 'Hotel timezone.' }),
|
|
353
321
|
venues: VENUES_SCHEMA,
|
|
354
322
|
website: z
|
|
355
323
|
.string()
|
|
356
324
|
.openapi({ description: 'Hotel website url.' })
|
|
357
|
-
.optional()
|
|
358
325
|
.nullish(),
|
|
359
326
|
})
|
|
360
|
-
.openapi('hotelApi')
|
|
327
|
+
.openapi('hotelApi', { description: 'Hotel details.' })
|
package/src/schemas/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
export * from './booking-policy.ts'
|
|
1
2
|
export * from './cancellation-policies.ts'
|
|
2
3
|
export * from './currency.ts'
|
|
3
|
-
export * from './
|
|
4
|
+
export * from './global.ts'
|
|
4
5
|
export * from './hotel-offer.ts'
|
|
5
6
|
export * from './hotel-room-offer.ts'
|
|
6
7
|
export * from './hotel-room.ts'
|
|
@@ -29,7 +29,9 @@ export const LIST_META_SCHEMA = z
|
|
|
29
29
|
ending_before: ENDING_BEFORE_SCHEMA,
|
|
30
30
|
limit: LIMIT_SCHEMA,
|
|
31
31
|
starting_after: STARTING_AFTER_SCHEMA,
|
|
32
|
-
total_count: z.number().nullish()
|
|
32
|
+
total_count: z.number().nullish().openapi({
|
|
33
|
+
description: 'Total count of items in the list.',
|
|
34
|
+
}),
|
|
33
35
|
})
|
|
34
36
|
.openapi('metaApiResponse')
|
|
35
37
|
.openapi({
|
|
@@ -43,5 +45,8 @@ export const LIST_POLLING_META_SCHEMA = LIST_META_SCHEMA.extend({
|
|
|
43
45
|
.number()
|
|
44
46
|
.optional()
|
|
45
47
|
.openapi({ description: 'Total count of the response list.' }),
|
|
46
|
-
}).openapi('metaApiPollingResponse'
|
|
48
|
+
}).openapi('metaApiPollingResponse', {
|
|
49
|
+
description:
|
|
50
|
+
'Meta information about the polling response list, including pagination cursors and the current polling status.',
|
|
51
|
+
})
|
|
47
52
|
/* eslint-enable camelcase */
|
package/src/schemas/tag.ts
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
/* eslint-disable camelcase */
|
|
2
2
|
import { z } from 'zod'
|
|
3
3
|
|
|
4
|
-
export const TAG_SCHEMA = z
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
export const TAG_SCHEMA = z
|
|
5
|
+
.object({
|
|
6
|
+
bg: z.string().optional().nullish().openapi({
|
|
7
|
+
description: 'Background color of the tag.',
|
|
8
|
+
}),
|
|
9
|
+
color: z.string().optional().nullish().openapi({
|
|
10
|
+
description: 'Text color of the tag.',
|
|
11
|
+
}),
|
|
12
|
+
description: z.string().optional().nullish().openapi({
|
|
13
|
+
description: 'Description of the tag.',
|
|
14
|
+
}),
|
|
15
|
+
fa_icon: z.string().optional().nullish().openapi({
|
|
16
|
+
description: 'Font Awesome icon identifier for the tag.',
|
|
17
|
+
}),
|
|
18
|
+
name: z.string().openapi({ description: 'Name of the tag.' }),
|
|
19
|
+
})
|
|
20
|
+
.openapi('tagApi', {
|
|
21
|
+
description: 'Tag associated with a Hotel or Hotel Room Offer.',
|
|
22
|
+
})
|
|
11
23
|
|
|
12
|
-
export const TAGS_SCHEMA = z.array(TAG_SCHEMA).optional().default([])
|
|
24
|
+
export const TAGS_SCHEMA = z.array(TAG_SCHEMA).optional().default([]).openapi({
|
|
25
|
+
description: 'List of tags associated with a Hotel or Hotel Room Offer.',
|
|
26
|
+
})
|
|
13
27
|
/* eslint-enable camelcase */
|
package/src/schemas/taxes.ts
CHANGED
|
@@ -28,7 +28,9 @@ export const TAX_SCHEMA = z
|
|
|
28
28
|
'Tax mode. Specifies if the tax applies per occupant, per booking or per room',
|
|
29
29
|
}),
|
|
30
30
|
})
|
|
31
|
-
.openapi('taxApi')
|
|
31
|
+
.openapi('taxApi', { description: 'Tax applied to the Hotel Room Offer.' })
|
|
32
32
|
|
|
33
|
-
export const TAXES_SCHEMA = z.array(TAX_SCHEMA).optional()
|
|
33
|
+
export const TAXES_SCHEMA = z.array(TAX_SCHEMA).optional().openapi({
|
|
34
|
+
description: 'List of taxes applied to the Hotel Room Offer.',
|
|
35
|
+
})
|
|
34
36
|
/* eslint-enable camelcase */
|
|
@@ -163,10 +163,6 @@ export interface PrebookFormValues {
|
|
|
163
163
|
firstName: ContactPerson['firstName']
|
|
164
164
|
lastName: ContactPerson['lastName']
|
|
165
165
|
nationality: ContactPerson['nationality']
|
|
166
|
-
phoneCountry: CountryIso2Code
|
|
167
|
-
phoneNumber: string
|
|
168
|
-
salutation: ContactPerson['salutation']
|
|
169
|
-
specialRequests: ContactPerson['remarks']
|
|
170
166
|
organizationAddress?: string
|
|
171
167
|
organizationCity?: string
|
|
172
168
|
organizationCountry?: string
|
|
@@ -174,4 +170,8 @@ export interface PrebookFormValues {
|
|
|
174
170
|
organizationState?: string
|
|
175
171
|
organizationVatNumber?: string
|
|
176
172
|
organizationZipCode?: string
|
|
173
|
+
phoneCountry: CountryIso2Code
|
|
174
|
+
phoneNumber: string
|
|
175
|
+
salutation: ContactPerson['salutation']
|
|
176
|
+
specialRequests: ContactPerson['remarks']
|
|
177
177
|
}
|
|
@@ -128,7 +128,7 @@ export interface HotelRoomOffer {
|
|
|
128
128
|
count?: number | null
|
|
129
129
|
/**
|
|
130
130
|
*
|
|
131
|
-
* @type {
|
|
131
|
+
* @type {CurrencyClient}
|
|
132
132
|
* @memberof HotelRoomOffer
|
|
133
133
|
*/
|
|
134
134
|
currency: CurrencyType
|
|
@@ -259,7 +259,7 @@ export interface HotelRoomOfferResponse {
|
|
|
259
259
|
children?: string | null
|
|
260
260
|
/**
|
|
261
261
|
*
|
|
262
|
-
* @type {
|
|
262
|
+
* @type {CurrencyClient}
|
|
263
263
|
* @memberof HotelRoomOfferResponse
|
|
264
264
|
*/
|
|
265
265
|
currency: CurrencyType
|
package/src/utils/omit.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
export function omit<T extends object, K extends keyof T>(
|
|
7
7
|
object: T | null | undefined,
|
|
8
8
|
keys: readonly K[] | K,
|
|
9
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
9
10
|
): Omit<T, K> {
|
|
10
11
|
if (object === null || object === undefined) {
|
|
11
12
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -35,5 +36,6 @@ export function omit<T extends object, K extends keyof T>(
|
|
|
35
36
|
}
|
|
36
37
|
}
|
|
37
38
|
|
|
39
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
38
40
|
return result as Omit<T, K>
|
|
39
41
|
}
|
package/src/utils/pick.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
export function pick<T extends object, K extends keyof T>(
|
|
2
2
|
obj: T,
|
|
3
3
|
keys: readonly K[],
|
|
4
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
4
5
|
): Pick<T, K> {
|
|
6
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
5
7
|
const result = {} as Pick<T, K>
|
|
6
8
|
for (const key of keys) {
|
|
7
9
|
if (Object.hasOwn(obj, key)) {
|
package/src/utils/shake.ts
CHANGED
|
@@ -7,6 +7,7 @@ export function shake<RemovedKeys extends string, T>(
|
|
|
7
7
|
obj: T,
|
|
8
8
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
9
9
|
filter: (value: any) => boolean = x => x === undefined,
|
|
10
|
+
// eslint-disable-next-line no-restricted-syntax
|
|
10
11
|
): Omit<T, RemovedKeys> {
|
|
11
12
|
if (!obj) {
|
|
12
13
|
return {} as T
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod'
|
|
2
|
-
|
|
3
|
-
import { CountryIso2Code } from '../constants/index.ts'
|
|
4
|
-
|
|
5
|
-
export const ADULT_COUNT_SCHEMA = z.number().int().min(1).max(200).openapi({
|
|
6
|
-
description:
|
|
7
|
-
'The total number of adults who will be staying in the property.',
|
|
8
|
-
})
|
|
9
|
-
|
|
10
|
-
export const CHECK_IN_DATE_SCHEMA = z
|
|
11
|
-
.string()
|
|
12
|
-
.regex(/^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/u)
|
|
13
|
-
.openapi({ description: 'Date of check-in formatted as YYYY-MM-DD.' })
|
|
14
|
-
|
|
15
|
-
export const CHECK_OUT_DATE_SCHEMA = z
|
|
16
|
-
.string()
|
|
17
|
-
.regex(/^(19|20)\d\d[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])$/u)
|
|
18
|
-
.openapi({ description: 'Date of check-out formatted as YYYY-MM-DD.' })
|
|
19
|
-
|
|
20
|
-
export const CHILDREN_SCHEMA = z
|
|
21
|
-
.string()
|
|
22
|
-
.regex(/^(([0-9]{1})|(1[0-7]){1})(,(([0-9]{1})|(1[0-7]){1}))*$|^$/u)
|
|
23
|
-
.openapi({
|
|
24
|
-
description:
|
|
25
|
-
'A comma-separated list of child ages (0 up to 17). e.g.: "3,7" represents 2 children respectively 3 and 7 years old.',
|
|
26
|
-
})
|
|
27
|
-
|
|
28
|
-
export const COUNTRY_ISO2_CODE_SCHEMA = z
|
|
29
|
-
.enum(CountryIso2Code)
|
|
30
|
-
.refine(check => Object.values(CountryIso2Code).includes(check), {
|
|
31
|
-
message: 'Invalid ISO Alpha-2 country code.',
|
|
32
|
-
})
|
|
33
|
-
.openapi({
|
|
34
|
-
description: 'ISO Alpha-2 country code.',
|
|
35
|
-
})
|
|
36
|
-
|
|
37
|
-
export const SOURCE_MARKET_SCHEMA = COUNTRY_ISO2_CODE_SCHEMA.openapi(
|
|
38
|
-
'sourceMarket',
|
|
39
|
-
{
|
|
40
|
-
description:
|
|
41
|
-
'For sourcing availability within certain markets, a source market option may be used to get more accurate prices. You may use any valid ISO Alpha-2 country code, e.g. JP.',
|
|
42
|
-
},
|
|
43
|
-
)
|