@revolugo/common 7.10.0 → 7.11.0-alpha.0

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revolugo/common",
3
- "version": "7.10.0",
3
+ "version": "7.11.0-alpha.0",
4
4
  "private": false,
5
5
  "description": "Revolugo common",
6
6
  "author": "Revolugo",
@@ -30,10 +30,10 @@
30
30
  "slugify": "1.6.9",
31
31
  "type-fest": "5.6.0",
32
32
  "uuid": "14.0.0",
33
- "zod": "4.3.6"
33
+ "zod": "4.4.3"
34
34
  },
35
35
  "engines": {
36
- "node": ">=20.18.1 <25"
36
+ "node": ">=24.15.0 <25"
37
37
  },
38
38
  "volta": {
39
39
  "extends": "../../package.json"
@@ -5,6 +5,7 @@ export * from './environment.ts'
5
5
  export * from './hotel-offers.ts'
6
6
  export * from './hotel-room-offer.ts'
7
7
  export * from './hotel.ts'
8
+ export * from './insurance.ts'
8
9
  export * from './locales.ts'
9
10
  export * from './measurement.ts'
10
11
  export * from './poller.ts'
@@ -0,0 +1,2 @@
1
+ export const MEETCH_INSURANCE_TYPE_NAME = 'Meetch Insurance'
2
+ export const MEETCH_INSURANCE_TYPE_SLUG = 'meetch-insurance'
@@ -122,7 +122,6 @@ export const STRIPE_CURRENCY_CODES = [
122
122
  CurrencyCode.SZL,
123
123
  CurrencyCode.THB,
124
124
  CurrencyCode.TJS,
125
- CurrencyCode.TND,
126
125
  CurrencyCode.TOP,
127
126
  CurrencyCode.TRY,
128
127
  CurrencyCode.TTD,
@@ -51,6 +51,7 @@ export const ICONS_NAME = Object.freeze({
51
51
  coinVertical: 'ph:coin-vertical',
52
52
  comment: 'ph:chat-teardrop',
53
53
  copy: 'ph:copy',
54
+ creditCard: 'ph:credit-card',
54
55
  cross: 'ph:cross',
55
56
  desktop: 'ph:desktop',
56
57
  deviceMobile: 'ph:device-mobile',
@@ -153,6 +154,7 @@ export const ICONS_NAME = Object.freeze({
153
154
  running: 'ph:person-simple-run',
154
155
  scissors: 'ph:scissors',
155
156
  shield: 'ph:shield',
157
+ shieldCheck: 'ph:shield-check',
156
158
  shirt: 'ph:shirt-folded',
157
159
  shoppingBag: 'ph:shopping-bag',
158
160
  shoppingCart: 'ph:shopping-cart',
@@ -13,9 +13,13 @@ import {
13
13
  IS_PRICE_INCREASED,
14
14
  } from './global.ts'
15
15
  import { HOTEL_ROOM_OFFER_SCHEMA } from './hotel-room-offer.ts'
16
+ import { ADDON_SCHEMA } from './order-addon.ts'
16
17
 
17
18
  export const BOOKING_POLICY_SCHEMA = z
18
19
  .object({
20
+ addons: z.array(ADDON_SCHEMA).optional().openapi({
21
+ description: 'Available add-ons (e.g. insurance)',
22
+ }),
19
23
  adult_count: ADULT_COUNT_SCHEMA,
20
24
  cancellation_policies: z.array(CANCELLATION_POLICY_SCHEMA).openapi({
21
25
  description:
@@ -36,7 +36,7 @@ export const FILTER_BOOKING_STATUS_SCHEMA = z
36
36
 
37
37
  export const BOOKING_METADATA_SCHEMA = z
38
38
  .record(z.string(), z.string())
39
- .openapi('bookingMetadataApi', {
39
+ .openapi({
40
40
  description:
41
41
  "You can use this parameter to attach key-value data to bookings. Metadata is useful for storing additional, structured information on a booking. As an example, you could store your user's full name and corresponding unique identifier from your system on a booking. Metadata is not used internally by the Booking Engine and won't be seen by your users unless you choose to show it to them.",
42
42
  })
@@ -0,0 +1,9 @@
1
+ import { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi'
2
+ import { z } from 'zod'
3
+
4
+ // Schemas in this package use `.openapi()` to attach OpenAPI metadata. The
5
+ // method is added to Zod's prototype via this side effect so consumers don't
6
+ // need to depend on `@hono/zod-openapi` (or remember to call this themselves).
7
+ // Imported as a side effect before any schema module so the prototype is
8
+ // patched before any `.openapi()` call evaluates.
9
+ extendZodWithOpenApi(z)
@@ -2,6 +2,7 @@
2
2
  import { z } from 'zod'
3
3
 
4
4
  import { CURRENCY_SCHEMA } from './currency.ts'
5
+ import { EVENT_SCHEMA } from './event.ts'
5
6
  import {
6
7
  ADULT_COUNT_SCHEMA,
7
8
  CHECK_IN_DATE_SCHEMA,
@@ -57,7 +58,7 @@ export const HOTEL_OFFERS_RESPONSE_SCHEMA = z
57
58
  description: 'Minimum price of available returned **Hotel Offers**',
58
59
  }),
59
60
  }),
60
- event: z.any().optional().openapi({
61
+ event: EVENT_SCHEMA.optional().openapi({
61
62
  description:
62
63
  'Event associated with the Hotel Offers response, when applicable.',
63
64
  }),
@@ -62,7 +62,7 @@ export const HOTEL_ROOM_OFFER_SCHEMA = z
62
62
  .openapi({
63
63
  description: PACKAGE_TYPES_DESCRIPTION,
64
64
  })
65
- .nullish(),
65
+ .optional(),
66
66
  price: z.number().openapi({
67
67
  description:
68
68
  'Price with taxes NOT INCLUDED of the given **Hotel Room Offer** including breakfast(s) when applicable, expressed in the requested **currency**.',
@@ -13,8 +13,12 @@ export const BED_SCHEMA = z
13
13
  })
14
14
  .openapi('bedApi')
15
15
 
16
+ export const BED_COMBINATION_SCHEMA = z
17
+ .array(BED_SCHEMA)
18
+ .openapi('bedCombinationApi')
19
+
16
20
  export const BEDS_SCHEMA = z
17
- .array(z.array(BED_SCHEMA))
21
+ .array(BED_COMBINATION_SCHEMA)
18
22
  .openapi({
19
23
  description: `Beds list.
20
24
  Each nested array of beds represents a single combination of possible beds.
@@ -277,9 +277,7 @@ export const HOTEL_SCHEMA = z
277
277
  )
278
278
  .openapi({ description: 'Hotel country code in ISO2.' })
279
279
  .nullish(),
280
- currency: CURRENCY_SCHEMA.openapi({
281
- description: 'Hotel currency.',
282
- }).nullish(),
280
+ currency: CURRENCY_SCHEMA.optional(),
283
281
  description: z
284
282
  .string()
285
283
  .openapi({ description: 'Hotel description.' })
@@ -1,3 +1,6 @@
1
+ // oxlint-disable-next-line import/no-unassigned-import
2
+ import './extend-zod.ts'
3
+
1
4
  export * from './booking-policy.ts'
2
5
  export * from './booking.ts'
3
6
  export * from './breakfast.ts'
@@ -10,6 +13,7 @@ export * from './hotel-room-offer.ts'
10
13
  export * from './hotel-room.ts'
11
14
  export * from './hotel.ts'
12
15
  export * from './list-polling-meta.ts'
16
+ export * from './order-addon.ts'
13
17
  export * from './payment-methods.ts'
14
18
  export * from './tag.ts'
15
19
  export * from './taxes.ts'
@@ -0,0 +1,20 @@
1
+ /* eslint-disable camelcase */
2
+ import { z } from 'zod'
3
+
4
+ import { AddonTypeEnum } from '../types/addon.ts'
5
+
6
+ export const ADDON_SCHEMA = z
7
+ .object({
8
+ price: z.number(),
9
+ tax_included_price: z.number(),
10
+ type: z.enum(AddonTypeEnum),
11
+ })
12
+ .openapi('OrderAddon')
13
+
14
+ export const ADDON_SELECTION_SCHEMA = z
15
+ .object({
16
+ type: z.enum(AddonTypeEnum),
17
+ })
18
+ .openapi('OrderAddonSelection')
19
+
20
+ /* eslint-enable camelcase */
@@ -63,39 +63,47 @@ export const PAYMENT_METHODS_REQUEST_SCHEMA = z
63
63
 
64
64
  export const PAYMENT_METHOD_RESPONSE_SCHEMA = z
65
65
  .discriminatedUnion('name', [
66
- z.object({
67
- name: z.literal(PaymentMethodNameEnum.CreditCard),
68
- payload: z.object({
69
- amount: z.number(),
70
- couponId: z.string().nullish(),
71
- token: z.string(),
72
- }),
73
- }),
74
- z.object({
75
- name: z.literal(PaymentMethodNameEnum.Coupon),
76
- payload: z.object({
77
- amount: z.number(),
78
- couponId: z.string(),
79
- token: z.string().nullish(),
80
- }),
81
- }),
82
- z.object({
83
- name: z.enum([PaymentMethodNameEnum.DepositAccount]),
84
- payload: z.object({
85
- amount: z.number(),
86
- couponId: z.string().nullish(),
87
- token: z.string().nullish(),
88
- }),
89
- }),
90
- z.object({
91
- name: z.literal(PaymentMethodNameEnum.PayLater),
92
- payload: z.object({
93
- amount: z.number(),
94
- couponId: z.string().nullish(),
95
- status: z.enum(PayLaterStatusEnum),
96
- token: z.string().nullish(),
97
- }),
98
- }),
66
+ z
67
+ .object({
68
+ name: z.literal(PaymentMethodNameEnum.CreditCard),
69
+ payload: z.object({
70
+ amount: z.number(),
71
+ couponId: z.string().nullish(),
72
+ token: z.string(),
73
+ }),
74
+ })
75
+ .openapi('paymentMethodCreditCardApi'),
76
+ z
77
+ .object({
78
+ name: z.literal(PaymentMethodNameEnum.Coupon),
79
+ payload: z.object({
80
+ amount: z.number(),
81
+ couponId: z.string(),
82
+ token: z.string().nullish(),
83
+ }),
84
+ })
85
+ .openapi('paymentMethodCouponApi'),
86
+ z
87
+ .object({
88
+ name: z.literal(PaymentMethodNameEnum.DepositAccount),
89
+ payload: z.object({
90
+ amount: z.number(),
91
+ couponId: z.string().nullish(),
92
+ token: z.string().nullish(),
93
+ }),
94
+ })
95
+ .openapi('paymentMethodDepositAccountApi'),
96
+ z
97
+ .object({
98
+ name: z.literal(PaymentMethodNameEnum.PayLater),
99
+ payload: z.object({
100
+ amount: z.number(),
101
+ couponId: z.string().nullish(),
102
+ status: z.enum(PayLaterStatusEnum),
103
+ token: z.string().nullish(),
104
+ }),
105
+ })
106
+ .openapi('paymentMethodPayLaterApi'),
99
107
  ])
100
108
  .openapi('paymentMethodApi')
101
109
 
@@ -108,21 +116,29 @@ export const PAYMENT_METHODS_RESPONSE_SCHEMA = z
108
116
 
109
117
  export const ALLOWED_PAYMENT_METHOD_RESPONSE_SCHEMA = z
110
118
  .discriminatedUnion('name', [
111
- z.object({
112
- name: z.literal(PaymentMethodNameEnum.CreditCard),
113
- }),
114
- z.object({
115
- name: z.literal(PaymentMethodNameEnum.Coupon),
116
- }),
117
- z.object({
118
- name: z.enum([PaymentMethodNameEnum.DepositAccount]),
119
- }),
120
- z.object({
121
- name: z.literal(PaymentMethodNameEnum.PayLater),
122
- payload: z.object({
123
- status: z.enum(PayLaterStatusEnum),
124
- }),
125
- }),
119
+ z
120
+ .object({
121
+ name: z.literal(PaymentMethodNameEnum.CreditCard),
122
+ })
123
+ .openapi('allowedPaymentMethodCreditCardApi'),
124
+ z
125
+ .object({
126
+ name: z.literal(PaymentMethodNameEnum.Coupon),
127
+ })
128
+ .openapi('allowedPaymentMethodCouponApi'),
129
+ z
130
+ .object({
131
+ name: z.literal(PaymentMethodNameEnum.DepositAccount),
132
+ })
133
+ .openapi('allowedPaymentMethodDepositAccountApi'),
134
+ z
135
+ .object({
136
+ name: z.literal(PaymentMethodNameEnum.PayLater),
137
+ payload: z.object({
138
+ status: z.enum(PayLaterStatusEnum),
139
+ }),
140
+ })
141
+ .openapi('allowedPaymentMethodPayLaterApi'),
126
142
  ])
127
143
  .openapi('allowedPaymentMethodApi')
128
144
 
@@ -7,5 +7,5 @@ export type AddonType = `${AddonTypeEnum}`
7
7
  export interface Addon {
8
8
  price: number
9
9
  taxIncludedPrice: number
10
- type: AddonType
10
+ type: AddonTypeEnum
11
11
  }
@@ -5,6 +5,7 @@ import type { Event } from './event.ts'
5
5
  import type { HotelRoomOffer } from './hotel-room-offer.ts'
6
6
  import type { HotelRoomingList } from './hotel-rooming-list.ts'
7
7
  import type { InvoiceApi } from './invoice.ts'
8
+ import type { OrderAddon } from './order-addon.ts'
8
9
  import type { PaymentMethod } from './payment-method.ts'
9
10
  import type { SourceMarket } from './source-market.ts'
10
11
  import type { Tax } from './tax.ts'
@@ -34,6 +35,12 @@ export interface Booking {
34
35
  * @memberof Booking
35
36
  */
36
37
  additionalPolicies?: string | null
38
+ /**
39
+ * Add-ons attached to the order this booking belongs to (e.g. Revolugo Flex insurance). Empty or omitted when the booking has no order-level add-ons.
40
+ * @type {Array<OrderAddon>}
41
+ * @memberof Booking
42
+ */
43
+ addons?: OrderAddon[]
37
44
  /**
38
45
  * The total number of adults who will be staying in the property.
39
46
  * @type {number}
@@ -32,6 +32,7 @@ export enum ElementsEvent {
32
32
  HotelOffersFiltersUpdated = 'hotel-offers:filters:updated',
33
33
  HotelOffersItemClick = 'hotel-offer:item:click',
34
34
  HotelOffersMarkerClick = 'hotel-offers:marker:click',
35
+ HotelOffersOpenInNewTabClick = 'hotel-offers:open-in-new-tab:click',
35
36
  HotelOffersPollingStarted = 'hotel-offers:polling:started',
36
37
  HotelOffersRetrieved = 'hotel-offers:retrieved',
37
38
  HotelRetrieved = 'hotel:retrieved',
@@ -65,6 +66,7 @@ export interface ElementsEventCallbacks {
65
66
  [ElementsEvent.HotelOffersFiltersUpdated]: Partial<HotelOffersFilters>
66
67
  [ElementsEvent.HotelOffersItemClick]: HotelOffer | [HotelOffer, number]
67
68
  [ElementsEvent.HotelOffersMarkerClick]: HotelOffer | [HotelOffer, number]
69
+ [ElementsEvent.HotelOffersOpenInNewTabClick]: string
68
70
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
71
  [ElementsEvent.HotelOffersPollingStarted]: any
70
72
  [ElementsEvent.HotelOffersRetrieved]: HotelOffer[]
@@ -1,4 +1,16 @@
1
1
  export interface Event {
2
+ /**
3
+ * Latitude of the event venue
4
+ * @type {number}
5
+ * @memberof EventApi
6
+ */
7
+ latitude?: number | null
8
+ /**
9
+ * Longitude of the event venue
10
+ * @type {number}
11
+ * @memberof EventApi
12
+ */
13
+ longitude?: number | null
2
14
  /**
3
15
  * Unique name of the event
4
16
  * @type {string}
@@ -157,7 +157,7 @@ export interface HotelRoomOffer {
157
157
  * @type {string}
158
158
  * @memberof HotelRoomOffer
159
159
  */
160
- packageType?: HotelRoomOfferPackageType | null
160
+ packageType?: HotelRoomOfferPackageType
161
161
  /**
162
162
  * Price with taxes NOT INCLUDED of the given **Hotel Room Offer** including breakfast(s) when applicable, expressed in the requested **currency**.
163
163
  * @type {number}
@@ -65,7 +65,7 @@ export interface Hotel {
65
65
  * @type {CurrencyClient}
66
66
  * @memberof HotelApi
67
67
  */
68
- currency?: CurrencyType
68
+ currency?: CurrencyType | null
69
69
  /**
70
70
  * Hotel description.
71
71
  * @type {string}
@@ -24,3 +24,13 @@ export interface OrderAddon {
24
24
  */
25
25
  type: OrderAddonType
26
26
  }
27
+
28
+ /**
29
+ * Customer-side addon selection echoed back on the prebook request body.
30
+ *
31
+ * The booking-api expects `addons: [{ type: 'insurance' }]` when the customer
32
+ * opts into Flex; the field is omitted entirely when declined.
33
+ */
34
+ export interface OrderAddonSelection {
35
+ type: OrderAddonType
36
+ }
@@ -2,6 +2,8 @@ export interface IEvent {
2
2
  id: string
3
3
  eventDateFrom?: Date
4
4
  eventDateTo?: Date
5
+ latitude?: number | null
6
+ longitude?: number | null
5
7
  name: string
6
8
  slug: string
7
9
  }
@@ -7,6 +7,7 @@ export interface IHotelContract {
7
7
  forcedTotalComissionsAmount: number
8
8
  forcedTotalPurchasedAmount: number
9
9
  forcedTotalVatComissionsAmount: number
10
+ hotelContractTaaps?: { taapId: string }[] | null
10
11
  hotelId: string
11
12
  hotelRoomStocks?: IHotelRoomStock[]
12
13
  name: string
@@ -100,3 +100,7 @@ export function keysChangeCase<T>(
100
100
  return obj
101
101
  }
102
102
  /* eslint-enable @typescript-eslint/no-explicit-any */
103
+
104
+ export function capitalize(value: string): string {
105
+ return value.replace(/^\w/u, c => c.toUpperCase())
106
+ }
@@ -68,6 +68,19 @@ export function sanitizeDateRange(
68
68
  ]
69
69
  }
70
70
 
71
+ export function isValidDateRange(range: [string, string]): boolean {
72
+ const [start, end] = range
73
+
74
+ return (
75
+ isValidDate(start) &&
76
+ isValidDate(end) &&
77
+ dayjs(start, 'YYYY-MM-DD', true).isBefore(
78
+ dayjs(end, 'YYYY-MM-DD', true),
79
+ 'day',
80
+ )
81
+ )
82
+ }
83
+
71
84
  export function isDate(value: unknown): value is Date {
72
85
  return value instanceof Date && !isNaN(value.getTime())
73
86
  }