@revolugo/common 6.15.6 → 6.15.7-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 +4 -5
- package/src/icons/index.ts +8 -1
- package/src/schemas/hotel-offer-request.ts +1 -1
- package/src/schemas/hotel-room-offer.ts +3 -3
- package/src/schemas/list-polling-meta.ts +1 -1
- package/src/schemas/taxes.ts +2 -2
- package/src/types/booking.ts +2 -0
- package/src/types/elements/booking-policy.ts +8 -0
- package/src/types/elements/elements-events.ts +5 -7
- package/src/types/elements/hotel-offer-request.ts +14 -15
- package/src/types/elements/index.ts +1 -0
- package/src/types/elements/payment-method.ts +47 -39
- package/src/types/http-exception/base.exception.ts +1 -1
- package/src/utils/create-dummy-hotel-images.ts +15 -0
- package/src/utils/generate-dummy-hotel-images.ts +15 -0
- package/src/utils/generate-random-nearby-geolocation.ts +31 -0
- package/src/utils/get-night-count.ts +11 -0
- package/src/utils/index.ts +4 -0
- package/src/utils/transform-schema-keys.ts +28 -39
- package/src/assets/index.ts +0 -3
- package/src/assets/placeholder-hotel.png +0 -0
- package/src/assets/placeholder-room.png +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@revolugo/common",
|
|
3
|
-
"version": "6.15.
|
|
3
|
+
"version": "6.15.7-alpha.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Revolugo common",
|
|
6
6
|
"author": "Revolugo",
|
|
@@ -16,7 +16,6 @@
|
|
|
16
16
|
],
|
|
17
17
|
"exports": {
|
|
18
18
|
"./amenities": "./src/amenities/index.ts",
|
|
19
|
-
"./assets": "./src/assets/index.ts",
|
|
20
19
|
"./cancellation-policies": "./src/cancellation-policies.ts",
|
|
21
20
|
"./countries": "./src/countries/index.ts",
|
|
22
21
|
"./constants": "./src/constants/index.ts",
|
|
@@ -32,11 +31,11 @@
|
|
|
32
31
|
"dependencies": {
|
|
33
32
|
"change-case": "5.4.4",
|
|
34
33
|
"dayjs": "1.11.19",
|
|
35
|
-
"ky": "1.14.
|
|
34
|
+
"ky": "1.14.2",
|
|
36
35
|
"slugify": "1.6.6",
|
|
37
|
-
"type-fest": "5.3.
|
|
36
|
+
"type-fest": "5.3.1",
|
|
38
37
|
"uuid": "13.0.0",
|
|
39
|
-
"zod": "3.
|
|
38
|
+
"zod": "4.3.5"
|
|
40
39
|
},
|
|
41
40
|
"scripts": {
|
|
42
41
|
"test": "vitest"
|
package/src/icons/index.ts
CHANGED
|
@@ -39,6 +39,7 @@ export const ICONS_NAME = Object.freeze({
|
|
|
39
39
|
circle: 'ph:circle',
|
|
40
40
|
circleNotch: 'ph:circle-notch',
|
|
41
41
|
clock: 'ph:clock',
|
|
42
|
+
clockClockwise: 'ph:clock-clockwise',
|
|
42
43
|
close: 'ph:x',
|
|
43
44
|
closeCircle: 'ph:x-circle',
|
|
44
45
|
cloud: 'ph:cloud',
|
|
@@ -100,16 +101,19 @@ export const ICONS_NAME = Object.freeze({
|
|
|
100
101
|
images: 'ph:images',
|
|
101
102
|
imagesSquare: 'ph:images-square',
|
|
102
103
|
info: 'ph:info',
|
|
104
|
+
instagram: 'ph:instagram-logo',
|
|
103
105
|
key: 'ph:key',
|
|
104
106
|
leaf: 'ph:leaf',
|
|
105
107
|
lightning: 'ph:lightning',
|
|
106
108
|
link: 'ph:link',
|
|
107
109
|
linkBreak: 'ph:link-break',
|
|
110
|
+
linkedin: 'ph:linkedin-logo',
|
|
108
111
|
lock: 'ph:lock',
|
|
109
112
|
lockKey: 'ph:lock-key',
|
|
110
113
|
lockKeyOpen: 'ph:lock-key-open',
|
|
111
114
|
lockOpen: 'ph:lock-open',
|
|
112
115
|
magnifyingGlass: 'ph:magnifying-glass',
|
|
116
|
+
magnifyingGlassList: 'ph:list-magnifying-glass',
|
|
113
117
|
mapPin: 'ph:map-pin',
|
|
114
118
|
mapPinArea: 'ph:map-pin-area',
|
|
115
119
|
mapPinSimpleArea: 'ph:map-pin-simple-area',
|
|
@@ -137,11 +141,13 @@ export const ICONS_NAME = Object.freeze({
|
|
|
137
141
|
policeCar: 'ph:police-car',
|
|
138
142
|
praying: 'ph:hands-praying',
|
|
139
143
|
questionMark: 'ph:question-mark',
|
|
144
|
+
receiptFail: 'ph:receipt-x',
|
|
140
145
|
refresh: 'ph:arrows-counter-clockwise',
|
|
141
146
|
running: 'ph:person-simple-run',
|
|
142
147
|
scissors: 'ph:scissors',
|
|
143
148
|
shield: 'ph:shield',
|
|
144
149
|
shirt: 'ph:shirt-folded',
|
|
150
|
+
shoppingBag: 'ph:shopping-bag',
|
|
145
151
|
shoppingCart: 'ph:shopping-cart',
|
|
146
152
|
shrink: 'ph:arrows-in-simple',
|
|
147
153
|
signOut: 'ph:sign-out',
|
|
@@ -165,7 +171,7 @@ export const ICONS_NAME = Object.freeze({
|
|
|
165
171
|
thumbsUp: 'ph:thumbs-up',
|
|
166
172
|
tooth: 'ph:tooth',
|
|
167
173
|
train: 'ph:train',
|
|
168
|
-
trash: 'ph:trash',
|
|
174
|
+
trash: 'ph:trash-simple',
|
|
169
175
|
tree: 'ph:tree',
|
|
170
176
|
trendDown: 'ph:trend-down',
|
|
171
177
|
trendUp: 'ph:trend-up',
|
|
@@ -178,6 +184,7 @@ export const ICONS_NAME = Object.freeze({
|
|
|
178
184
|
van: 'ph:van',
|
|
179
185
|
vault: 'ph:vault',
|
|
180
186
|
walking: 'ph:person-simple-walk',
|
|
187
|
+
wallet: 'ph:wallet',
|
|
181
188
|
warning: 'ph:warning',
|
|
182
189
|
warningCircle: 'ph:warning-circle',
|
|
183
190
|
wheelchair: 'ph:wheelchair',
|
|
@@ -26,7 +26,7 @@ export const CHILDREN_SCHEMA = z
|
|
|
26
26
|
})
|
|
27
27
|
|
|
28
28
|
export const COUNTRY_ISO2_CODE_SCHEMA = z
|
|
29
|
-
.
|
|
29
|
+
.enum(CountryIso2Code)
|
|
30
30
|
.refine(check => Object.values(CountryIso2Code).includes(check), {
|
|
31
31
|
message: 'Invalid ISO Alpha-2 country code.',
|
|
32
32
|
})
|
|
@@ -31,7 +31,7 @@ export const HOTEL_ROOM_OFFER_SCHEMA = z
|
|
|
31
31
|
description:
|
|
32
32
|
'Quantity of breakfast per night included in the given **Hotel Room Offer**',
|
|
33
33
|
}),
|
|
34
|
-
breakfast_option: z.
|
|
34
|
+
breakfast_option: z.enum(BreakfastOption).openapi({
|
|
35
35
|
description: BREAKFAST_OPTION_DESCRIPTION,
|
|
36
36
|
}),
|
|
37
37
|
breakfast_price_per_guest_per_night: z
|
|
@@ -69,7 +69,7 @@ export const HOTEL_ROOM_OFFER_SCHEMA = z
|
|
|
69
69
|
}),
|
|
70
70
|
id: z.string().openapi({ description: 'Hotel Room Offer id.' }).optional(),
|
|
71
71
|
package_type: z
|
|
72
|
-
.
|
|
72
|
+
.enum(PackageType)
|
|
73
73
|
.openapi({
|
|
74
74
|
description: PACKAGE_TYPES_DESCRIPTION,
|
|
75
75
|
})
|
|
@@ -86,7 +86,7 @@ export const HOTEL_ROOM_OFFER_SCHEMA = z
|
|
|
86
86
|
}),
|
|
87
87
|
taxes: TAXES_SCHEMA,
|
|
88
88
|
type: z
|
|
89
|
-
.
|
|
89
|
+
.enum(HotelRoomOfferType)
|
|
90
90
|
.openapi({
|
|
91
91
|
description: `Hotel Room Offer type.\n\n **Hotel Room Offers** with **type = "${HotelRoomOfferType.Package}"** are **Hotel Room Offers** that are already bookable and you'll be able to follow the next step of the **Booking Flow** calling **[Create Booking Policies endpoint](/v1/documentation#operation/postV1Booking_policies)**. \n\n Otherwise, you'll be able to create a new **Hotel Room Offer** with **type = "${HotelRoomOfferType.Package}"** from multiple **Hotel Room Offers** with **type = "${HotelRoomOfferType.HotelRoom}"**. See **[Create Hotel Room Offer endpoint](/v1/documentation#operation/postV1Hotel_room_offers)** for details.`,
|
|
92
92
|
})
|
|
@@ -14,7 +14,7 @@ export const STARTING_AFTER_SCHEMA = z.string().optional().nullable().openapi({
|
|
|
14
14
|
})
|
|
15
15
|
|
|
16
16
|
export const STATUS_SCHEMA = z
|
|
17
|
-
.
|
|
17
|
+
.enum(PollerStatus)
|
|
18
18
|
.openapi({ description: 'Status of the response data.' })
|
|
19
19
|
.openapi('pollerStatus')
|
|
20
20
|
|
package/src/schemas/taxes.ts
CHANGED
|
@@ -19,11 +19,11 @@ export const TAX_SCHEMA = z
|
|
|
19
19
|
.optional()
|
|
20
20
|
.nullish()
|
|
21
21
|
.openapi({ description: 'Tax percentage on the total amount.' }),
|
|
22
|
-
tax_frequency: z.
|
|
22
|
+
tax_frequency: z.enum(TaxFrequency).openapi({
|
|
23
23
|
description:
|
|
24
24
|
'Tax frequency. Specifies if the tax applies per stay or per night',
|
|
25
25
|
}),
|
|
26
|
-
tax_mode: z.
|
|
26
|
+
tax_mode: z.enum(TaxMode).openapi({
|
|
27
27
|
description:
|
|
28
28
|
'Tax mode. Specifies if the tax applies per occupant, per booking or per room',
|
|
29
29
|
}),
|
package/src/types/booking.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import type { PayLaterStatusApi } from '../booking.ts'
|
|
1
2
|
import type { CancellationPolicy } from './cancellation-policy.ts'
|
|
2
3
|
import type { CurrencyType } from './currency.ts'
|
|
3
4
|
import type { HotelRoomOffer } from './hotel-room-offer.ts'
|
|
5
|
+
import type { PaymentMethodApi } from './payment-method.ts'
|
|
4
6
|
|
|
5
7
|
export interface BookingPolicies {
|
|
6
8
|
/**
|
|
@@ -47,6 +49,8 @@ export interface BookingPolicies {
|
|
|
47
49
|
* @memberof BookingPolicies
|
|
48
50
|
*/
|
|
49
51
|
expiresAt: string | null
|
|
52
|
+
|
|
53
|
+
hasRoomingLists: boolean
|
|
50
54
|
/**
|
|
51
55
|
* Hotel id
|
|
52
56
|
* @type {string}
|
|
@@ -77,4 +81,8 @@ export interface BookingPolicies {
|
|
|
77
81
|
* @memberof BookingPolicies
|
|
78
82
|
*/
|
|
79
83
|
isPriceIncreased: boolean
|
|
84
|
+
|
|
85
|
+
payLater?: PayLaterStatusApi
|
|
86
|
+
|
|
87
|
+
paymentMethods?: PaymentMethodApi[]
|
|
80
88
|
}
|
|
@@ -34,7 +34,6 @@ export enum ElementsEvent {
|
|
|
34
34
|
HotelOffersMarkerClick = 'hotel-offers:marker:click',
|
|
35
35
|
HotelOffersPollingStarted = 'hotel-offers:polling:started',
|
|
36
36
|
HotelOffersRetrieved = 'hotel-offers:retrieved',
|
|
37
|
-
HotelOffersViewShowMap = 'hotel-offers-view:show-map',
|
|
38
37
|
HotelRetrieved = 'hotel:retrieved',
|
|
39
38
|
HotelRoomOfferRequestCreated = 'hotel-room-offer-request:created',
|
|
40
39
|
HotelRoomOfferRequestRetrieved = 'hotel-room-offer-request:retrieved',
|
|
@@ -57,18 +56,17 @@ export interface ElementsEventCallbacks {
|
|
|
57
56
|
[ElementsEvent.BookingPolicyCreated]: BookingPolicies
|
|
58
57
|
[ElementsEvent.CancellationPoliciesUpdated]: CancellationPolicy[]
|
|
59
58
|
[ElementsEvent.CurrencyUpdated]: CurrencyType
|
|
60
|
-
[ElementsEvent.HotelOfferItemMouseleave]: [HotelOffer, number]
|
|
61
|
-
[ElementsEvent.HotelOfferItemMouseover]: [HotelOffer, number]
|
|
62
|
-
[ElementsEvent.HotelOfferItemVisible]: [HotelOffer, number]
|
|
59
|
+
[ElementsEvent.HotelOfferItemMouseleave]: HotelOffer | [HotelOffer, number]
|
|
60
|
+
[ElementsEvent.HotelOfferItemMouseover]: HotelOffer | [HotelOffer, number]
|
|
61
|
+
[ElementsEvent.HotelOfferItemVisible]: HotelOffer | [HotelOffer, number]
|
|
63
62
|
[ElementsEvent.HotelOfferRequestCreated]: HotelOfferRequestResponse
|
|
64
63
|
[ElementsEvent.HotelOfferRequestRetrieved]: HotelOfferRequestResponse
|
|
65
64
|
[ElementsEvent.HotelOffersFiltersUpdated]: Partial<HotelOffersFilters>
|
|
66
|
-
[ElementsEvent.HotelOffersItemClick]: [HotelOffer, number]
|
|
67
|
-
[ElementsEvent.HotelOffersMarkerClick]: HotelOffer
|
|
65
|
+
[ElementsEvent.HotelOffersItemClick]: HotelOffer | [HotelOffer, number]
|
|
66
|
+
[ElementsEvent.HotelOffersMarkerClick]: HotelOffer | [HotelOffer, number]
|
|
68
67
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
69
68
|
[ElementsEvent.HotelOffersPollingStarted]: any
|
|
70
69
|
[ElementsEvent.HotelOffersRetrieved]: HotelOffer[]
|
|
71
|
-
[ElementsEvent.HotelOffersViewShowMap]: boolean
|
|
72
70
|
[ElementsEvent.HotelRetrieved]: Hotel
|
|
73
71
|
[ElementsEvent.HotelRoomOfferRequestCreated]: HotelRoomOfferRequestResponse
|
|
74
72
|
[ElementsEvent.HotelRoomOfferRequestRetrieved]: HotelRoomOfferRequestResponse
|
|
@@ -40,14 +40,14 @@ export interface HotelOfferRequest {
|
|
|
40
40
|
* <b style="color: red;"> when no address parameter passed.</b>
|
|
41
41
|
* @type {number}
|
|
42
42
|
*/
|
|
43
|
-
latitude
|
|
43
|
+
latitude: number
|
|
44
44
|
/**
|
|
45
45
|
* Search location longitude.
|
|
46
46
|
*
|
|
47
47
|
* <b style="color: red;"> when no address parameter passed.</b>
|
|
48
48
|
* @type {number}
|
|
49
49
|
*/
|
|
50
|
-
longitude
|
|
50
|
+
longitude: number
|
|
51
51
|
/**
|
|
52
52
|
* 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.
|
|
53
53
|
*
|
|
@@ -156,16 +156,15 @@ export interface HotelOfferRequestResponse {
|
|
|
156
156
|
id: string
|
|
157
157
|
}
|
|
158
158
|
|
|
159
|
-
export
|
|
160
|
-
HotelOfferRequest
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
>
|
|
159
|
+
export interface HotelOfferRequestCreate {
|
|
160
|
+
address?: HotelOfferRequest['address']
|
|
161
|
+
adultCount: HotelOfferRequest['adultCount']
|
|
162
|
+
checkInDate: HotelOfferRequest['checkInDate']
|
|
163
|
+
checkOutDate: HotelOfferRequest['checkOutDate']
|
|
164
|
+
children?: HotelOfferRequest['children']
|
|
165
|
+
eventMetadata?: HotelOfferRequest['eventMetadata']
|
|
166
|
+
latitude?: HotelOfferRequest['latitude']
|
|
167
|
+
longitude?: HotelOfferRequest['longitude']
|
|
168
|
+
roomCount: HotelOfferRequest['roomCount']
|
|
169
|
+
sourceMarket: HotelOfferRequest['sourceMarket']
|
|
170
|
+
}
|
|
@@ -22,7 +22,25 @@ export interface PaymentMethodRequestApi {
|
|
|
22
22
|
payload?: PaymentMethodRequestPayloadApi
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export
|
|
25
|
+
export type PaymentMethodApi =
|
|
26
|
+
| PaymentMethodApiOneOf
|
|
27
|
+
| PaymentMethodApiOneOf1
|
|
28
|
+
| PaymentMethodApiOneOf2
|
|
29
|
+
|
|
30
|
+
export enum PaymentMethodApiNameEnum {
|
|
31
|
+
CreditCard = 'CREDIT_CARD',
|
|
32
|
+
Coupon = 'COUPON',
|
|
33
|
+
DepositAccount = 'DEPOSIT_ACCOUNT',
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type PaymentMethodApiName = `${PaymentMethodApiNameEnum}`
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
*
|
|
40
|
+
* @export
|
|
41
|
+
* @interface PaymentMethodApiOneOf
|
|
42
|
+
*/
|
|
43
|
+
export interface PaymentMethodApiOneOf {
|
|
26
44
|
/**
|
|
27
45
|
*
|
|
28
46
|
* @type {string}
|
|
@@ -34,20 +52,9 @@ export interface PaymentMethodApi {
|
|
|
34
52
|
* @type {PaymentMethodApiOneOfPayload}
|
|
35
53
|
* @memberof PaymentMethodApiOneOf
|
|
36
54
|
*/
|
|
37
|
-
payload:
|
|
38
|
-
| PaymentMethodApiOneOfPayload
|
|
39
|
-
| PaymentMethodApiOneOf1Payload
|
|
40
|
-
| PaymentMethodApiOneOf2Payload
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export enum PaymentMethodApiNameEnum {
|
|
44
|
-
CreditCard = 'CREDIT_CARD',
|
|
45
|
-
Coupon = 'COUPON',
|
|
46
|
-
DepositAccount = 'DEPOSIT_ACCOUNT',
|
|
55
|
+
payload: PaymentMethodApiOneOfPayload
|
|
47
56
|
}
|
|
48
57
|
|
|
49
|
-
type PaymentMethodApiName = `${PaymentMethodApiNameEnum}`
|
|
50
|
-
|
|
51
58
|
/**
|
|
52
59
|
*
|
|
53
60
|
* @export
|
|
@@ -67,6 +74,25 @@ export interface PaymentMethodApiOneOf1 {
|
|
|
67
74
|
*/
|
|
68
75
|
payload: PaymentMethodApiOneOf1Payload
|
|
69
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
*
|
|
79
|
+
* @export
|
|
80
|
+
* @interface PaymentMethodApiOneOf2
|
|
81
|
+
*/
|
|
82
|
+
export interface PaymentMethodApiOneOf2 {
|
|
83
|
+
/**
|
|
84
|
+
*
|
|
85
|
+
* @type {string}
|
|
86
|
+
* @memberof PaymentMethodApiOneOf2
|
|
87
|
+
*/
|
|
88
|
+
name: PaymentMethodApiName
|
|
89
|
+
/**
|
|
90
|
+
*
|
|
91
|
+
* @type {PaymentMethodApiOneOf2Payload}
|
|
92
|
+
* @memberof PaymentMethodApiOneOf2
|
|
93
|
+
*/
|
|
94
|
+
payload: PaymentMethodApiOneOf2Payload
|
|
95
|
+
}
|
|
70
96
|
|
|
71
97
|
/**
|
|
72
98
|
*
|
|
@@ -93,31 +119,13 @@ export interface PaymentMethodApiOneOf1Payload {
|
|
|
93
119
|
*/
|
|
94
120
|
token: string
|
|
95
121
|
}
|
|
96
|
-
/**
|
|
97
|
-
*
|
|
98
|
-
* @export
|
|
99
|
-
* @interface PaymentMethodApiOneOf2
|
|
100
|
-
*/
|
|
101
|
-
export interface PaymentMethodApiOneOf2 {
|
|
102
|
-
/**
|
|
103
|
-
*
|
|
104
|
-
* @type {string}
|
|
105
|
-
* @memberof PaymentMethodApiOneOf2
|
|
106
|
-
*/
|
|
107
|
-
name: PaymentMethodApiName
|
|
108
|
-
/**
|
|
109
|
-
*
|
|
110
|
-
* @type {PaymentMethodApiOneOf2Payload}
|
|
111
|
-
* @memberof PaymentMethodApiOneOf2
|
|
112
|
-
*/
|
|
113
|
-
payload: PaymentMethodApiOneOf2Payload
|
|
114
|
-
}
|
|
115
122
|
|
|
116
123
|
/**
|
|
117
124
|
*
|
|
118
125
|
* @export
|
|
119
126
|
* @interface PaymentMethodApiOneOf2Payload
|
|
120
127
|
*/
|
|
128
|
+
|
|
121
129
|
export interface PaymentMethodApiOneOf2Payload {
|
|
122
130
|
/**
|
|
123
131
|
*
|
|
@@ -131,12 +139,6 @@ export interface PaymentMethodApiOneOf2Payload {
|
|
|
131
139
|
* @memberof PaymentMethodApiOneOf2Payload
|
|
132
140
|
*/
|
|
133
141
|
couponId?: string | null
|
|
134
|
-
/**
|
|
135
|
-
*
|
|
136
|
-
* @type {string}
|
|
137
|
-
* @memberof PaymentMethodApiOneOf2Payload
|
|
138
|
-
*/
|
|
139
|
-
token?: string | null
|
|
140
142
|
}
|
|
141
143
|
/**
|
|
142
144
|
*
|
|
@@ -155,5 +157,11 @@ export interface PaymentMethodApiOneOfPayload {
|
|
|
155
157
|
* @type {string}
|
|
156
158
|
* @memberof PaymentMethodApiOneOfPayload
|
|
157
159
|
*/
|
|
158
|
-
couponId
|
|
160
|
+
couponId?: string | null
|
|
161
|
+
/**
|
|
162
|
+
*
|
|
163
|
+
* @type {string}
|
|
164
|
+
* @memberof PaymentMethodApiOneOfPayload
|
|
165
|
+
*/
|
|
166
|
+
token: string
|
|
159
167
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getRandomHexColor } from './get-random-hex-color.ts'
|
|
2
|
+
import { getRandomInt } from './get-random-int.ts'
|
|
3
|
+
|
|
4
|
+
import type { HotelImage } from '../types/index.ts'
|
|
5
|
+
|
|
6
|
+
export function createDummyHotelImage(count: number): HotelImage[] {
|
|
7
|
+
return Array.from({ length: count }, () => ({
|
|
8
|
+
isHeroImage: false,
|
|
9
|
+
l: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
10
|
+
m: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
11
|
+
s: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
12
|
+
xl: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
13
|
+
xs: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
14
|
+
}))
|
|
15
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getRandomHexColor } from './get-random-hex-color.ts'
|
|
2
|
+
import { getRandomInt } from './get-random-int.ts'
|
|
3
|
+
|
|
4
|
+
import type { HotelImage } from '../types/index.ts'
|
|
5
|
+
|
|
6
|
+
export function generateDummyHotelImages(): HotelImage {
|
|
7
|
+
return {
|
|
8
|
+
isHeroImage: false,
|
|
9
|
+
l: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
10
|
+
m: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
11
|
+
s: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
12
|
+
xl: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
13
|
+
xs: `https://dummyimage.com/${getRandomInt(300, 900)}x${getRandomInt(300, 900)}/${getRandomHexColor()}/${getRandomHexColor()}`,
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GeoCoordinates } from '../types/geo-coordinates.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Generate random coordinates near a given latitude and longitude.
|
|
5
|
+
*
|
|
6
|
+
* @param lat - Base latitude
|
|
7
|
+
* @param lon - Base longitude
|
|
8
|
+
* @param radiusInMeters - Max distance from base point, in meters
|
|
9
|
+
* @returns { lat: number, lon: number }
|
|
10
|
+
*/
|
|
11
|
+
export function generateRandomNearbyGeolocation(
|
|
12
|
+
{ latitude: lat, longitude: lon }: GeoCoordinates,
|
|
13
|
+
radiusInMeters: number,
|
|
14
|
+
): GeoCoordinates {
|
|
15
|
+
// Convert radius from meters to degrees
|
|
16
|
+
const radiusInDegrees = radiusInMeters / 111_320
|
|
17
|
+
|
|
18
|
+
// Random distance and angle
|
|
19
|
+
const u = Math.random()
|
|
20
|
+
const v = Math.random()
|
|
21
|
+
const w = radiusInDegrees * Math.sqrt(u)
|
|
22
|
+
const t = 2 * Math.PI * v
|
|
23
|
+
|
|
24
|
+
const deltaLat = w * Math.cos(t)
|
|
25
|
+
const deltaLon = (w * Math.sin(t)) / Math.cos((lat * Math.PI) / 180)
|
|
26
|
+
|
|
27
|
+
const newLat = lat + deltaLat
|
|
28
|
+
const newLon = lon + deltaLon
|
|
29
|
+
|
|
30
|
+
return { latitude: newLat, longitude: newLon }
|
|
31
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { dayjs } from './dayjs.ts'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get the number of nights between two dates.
|
|
5
|
+
* @param startDate - The start date
|
|
6
|
+
* @param endDate - The end date
|
|
7
|
+
* @returns The number of nights
|
|
8
|
+
*/
|
|
9
|
+
export function getNightCount(startDate: string, endDate: string): number {
|
|
10
|
+
return dayjs(endDate).diff(dayjs(startDate), 'day')
|
|
11
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -15,9 +15,12 @@ export * from './debounce.ts'
|
|
|
15
15
|
export * from './defaults-deep.ts'
|
|
16
16
|
export * from './delay.ts'
|
|
17
17
|
export * from './find-unique-keys.ts'
|
|
18
|
+
export * from './generate-dummy-hotel-images.ts'
|
|
18
19
|
export * from './generate-numbers-from-str.ts'
|
|
19
20
|
export * from './generate-pseudo-random-string.ts'
|
|
21
|
+
export * from './generate-random-nearby-geolocation.ts'
|
|
20
22
|
export * from './get-guest-count.ts'
|
|
23
|
+
export * from './get-night-count.ts'
|
|
21
24
|
export * from './get-random-element-from-array.ts'
|
|
22
25
|
export * from './get-random-hex-color.ts'
|
|
23
26
|
export * from './get-random-int.ts'
|
|
@@ -54,3 +57,4 @@ export * from './uniq-by.ts'
|
|
|
54
57
|
export * from './uniq-with.ts'
|
|
55
58
|
export * from './validators.ts'
|
|
56
59
|
export * from './weighted-mean.ts'
|
|
60
|
+
export * from './create-dummy-hotel-images.ts'
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { z } from 'zod'
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
4
|
CASE_TRANSFORMERS_MAPPING,
|
|
5
5
|
type CaseTransformer,
|
|
6
6
|
} from './case-transformers.ts'
|
|
7
7
|
|
|
8
|
+
import type { $ZodType } from 'zod/v4/core'
|
|
9
|
+
|
|
8
10
|
/* eslint-disable no-underscore-dangle, max-statements */
|
|
9
11
|
|
|
10
12
|
function transformSchemaKeysWithTransformer(
|
|
11
|
-
schema:
|
|
13
|
+
schema: z.ZodType,
|
|
12
14
|
transformer: (str: string) => string,
|
|
13
|
-
):
|
|
14
|
-
let result:
|
|
15
|
+
): z.ZodType {
|
|
16
|
+
let result: z.ZodType = schema
|
|
15
17
|
|
|
16
18
|
// Handle ZodObject
|
|
17
19
|
if (schema instanceof z.ZodObject) {
|
|
18
|
-
const shape = schema.
|
|
19
|
-
const transformedShape: Record<string,
|
|
20
|
+
const { shape } = schema.def
|
|
21
|
+
const transformedShape: Record<string, $ZodType> = {}
|
|
20
22
|
|
|
21
23
|
for (const key in shape) {
|
|
22
24
|
if (Object.hasOwn(shape, key)) {
|
|
@@ -28,83 +30,70 @@ function transformSchemaKeysWithTransformer(
|
|
|
28
30
|
}
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
result = z.object(transformedShape) as
|
|
33
|
+
result = z.object(transformedShape) as z.ZodType
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
// Handle ZodArray
|
|
35
37
|
else if (schema instanceof z.ZodArray) {
|
|
36
|
-
const {
|
|
38
|
+
const { element } = schema.def
|
|
37
39
|
result = z.array(
|
|
38
|
-
transformSchemaKeysWithTransformer(
|
|
40
|
+
transformSchemaKeysWithTransformer(element as z.ZodType, transformer),
|
|
39
41
|
)
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
// Handle ZodOptional
|
|
43
45
|
else if (schema instanceof z.ZodOptional) {
|
|
44
|
-
const { innerType: innerSchema } = schema.
|
|
46
|
+
const { innerType: innerSchema } = schema.def
|
|
45
47
|
result = transformSchemaKeysWithTransformer(
|
|
46
|
-
innerSchema,
|
|
48
|
+
innerSchema as z.ZodType,
|
|
47
49
|
transformer,
|
|
48
50
|
).optional()
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
// Handle ZodNullable
|
|
52
54
|
else if (schema instanceof z.ZodNullable) {
|
|
53
|
-
const { innerType: innerSchema } = schema.
|
|
55
|
+
const { innerType: innerSchema } = schema.def
|
|
54
56
|
result = transformSchemaKeysWithTransformer(
|
|
55
|
-
innerSchema,
|
|
57
|
+
innerSchema as z.ZodType,
|
|
56
58
|
transformer,
|
|
57
59
|
).nullable()
|
|
58
60
|
}
|
|
59
61
|
|
|
60
62
|
// Handle ZodDefault
|
|
61
63
|
else if (schema instanceof z.ZodDefault) {
|
|
62
|
-
const { defaultValue, innerType: innerSchema } = schema.
|
|
64
|
+
const { defaultValue, innerType: innerSchema } = schema.def
|
|
63
65
|
result = transformSchemaKeysWithTransformer(
|
|
64
|
-
innerSchema,
|
|
65
|
-
transformer,
|
|
66
|
-
).default(defaultValue())
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Handle ZodEffects (includes .refine(), .transform(), etc.)
|
|
70
|
-
else if (schema instanceof z.ZodEffects) {
|
|
71
|
-
const { schema: innerSchema } = schema._def
|
|
72
|
-
const transformedInner = transformSchemaKeysWithTransformer(
|
|
73
|
-
innerSchema,
|
|
66
|
+
innerSchema as z.ZodType,
|
|
74
67
|
transformer,
|
|
75
|
-
)
|
|
76
|
-
|
|
77
|
-
// We need to reconstruct the effects
|
|
78
|
-
// This is a simplified version - effects are not transformed, just passed through
|
|
79
|
-
result = transformedInner
|
|
68
|
+
).default((defaultValue as () => unknown)())
|
|
80
69
|
}
|
|
81
70
|
|
|
82
71
|
// Handle ZodUnion
|
|
83
72
|
else if (schema instanceof z.ZodUnion) {
|
|
84
|
-
const { options } = schema.
|
|
85
|
-
const transformedOptions = options.map((option:
|
|
86
|
-
transformSchemaKeysWithTransformer(option, transformer),
|
|
73
|
+
const { options } = schema.def
|
|
74
|
+
const transformedOptions = options.map((option: $ZodType) =>
|
|
75
|
+
transformSchemaKeysWithTransformer(option as z.ZodType, transformer),
|
|
87
76
|
)
|
|
88
77
|
result = z.union(
|
|
89
|
-
transformedOptions as [
|
|
78
|
+
transformedOptions as [z.ZodType, z.ZodType, ...z.ZodType[]],
|
|
90
79
|
)
|
|
91
80
|
}
|
|
92
81
|
|
|
93
82
|
// Handle ZodIntersection
|
|
94
83
|
else if (schema instanceof z.ZodIntersection) {
|
|
95
|
-
const { left, right } = schema.
|
|
84
|
+
const { left, right } = schema.def
|
|
96
85
|
result = z.intersection(
|
|
97
|
-
transformSchemaKeysWithTransformer(left, transformer),
|
|
98
|
-
transformSchemaKeysWithTransformer(right, transformer),
|
|
86
|
+
transformSchemaKeysWithTransformer(left as z.ZodType, transformer),
|
|
87
|
+
transformSchemaKeysWithTransformer(right as z.ZodType, transformer),
|
|
99
88
|
)
|
|
100
89
|
}
|
|
101
90
|
|
|
102
91
|
// Propagate openapi metadata
|
|
103
92
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
104
|
-
const { openapi } = schema.
|
|
93
|
+
const { openapi } = schema.def as any
|
|
105
94
|
if (openapi && result !== schema) {
|
|
106
95
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
107
|
-
;(result.
|
|
96
|
+
;(result.def as any).openapi = openapi
|
|
108
97
|
}
|
|
109
98
|
|
|
110
99
|
return result
|
|
@@ -129,7 +118,7 @@ function transformSchemaKeysWithTransformer(
|
|
|
129
118
|
* // Results in: { firstName: z.string(), lastName: z.string() }
|
|
130
119
|
* ```
|
|
131
120
|
*/
|
|
132
|
-
export function transformSchemaKeys<T extends
|
|
121
|
+
export function transformSchemaKeys<T extends z.ZodType>(
|
|
133
122
|
schema: T,
|
|
134
123
|
toCase: CaseTransformer,
|
|
135
124
|
): T {
|
package/src/assets/index.ts
DELETED
|
Binary file
|
|
Binary file
|