@revolugo/common 6.10.6-rc.0 → 6.10.7-beta.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": "6.10.6-rc.0",
3
+ "version": "6.10.7-beta.0",
4
4
  "private": false,
5
5
  "description": "Revolugo common",
6
6
  "author": "Revolugo",
@@ -25,7 +25,7 @@
25
25
  "dependencies": {
26
26
  "change-case": "5.4.4",
27
27
  "dayjs": "1.11.18",
28
- "ky": "1.10.0",
28
+ "ky": "1.11.0",
29
29
  "lodash-es": "4.17.21",
30
30
  "slugify": "1.6.6",
31
31
  "uuid": "13.0.0"
@@ -169,6 +169,7 @@ export function sanitizeCancellationPolicies({
169
169
 
170
170
  if (
171
171
  releaseDatetimeUTC &&
172
+ compactedCancellationPolicies[0] &&
172
173
  dayjs(releaseDatetimeUTC).isBetween(
173
174
  dayjs(bookingDatetimeUTC),
174
175
  dayjs(compactedCancellationPolicies[0].dateFrom),
@@ -184,7 +185,7 @@ export function sanitizeCancellationPolicies({
184
185
  },
185
186
  {
186
187
  dateFrom: releaseDatetimeUTC,
187
- dateTo: compactedCancellationPolicies[0].dateFrom,
188
+ dateTo: compactedCancellationPolicies[0]!.dateFrom,
188
189
  penaltyPercentage: 100,
189
190
  },
190
191
  )
@@ -268,11 +269,14 @@ export function sanitizeCancellationPolicies({
268
269
  !dayjs(cp.dateFrom).isSameOrAfter(nextDayCheckInDateUTC),
269
270
  )
270
271
 
271
- sanitizedCancellationPolicies[0].dateFrom = bookingDatetimeUTC
272
+ if (sanitizedCancellationPolicies[0]) {
273
+ sanitizedCancellationPolicies[0].dateFrom = bookingDatetimeUTC
274
+ }
272
275
 
273
- sanitizedCancellationPolicies[
274
- sanitizedCancellationPolicies.length - 1
275
- ]!.dateTo = nextDayCheckInDateUTC
276
+ const lastIndex = sanitizedCancellationPolicies.length - 1
277
+ if (sanitizedCancellationPolicies[lastIndex]) {
278
+ sanitizedCancellationPolicies[lastIndex].dateTo = nextDayCheckInDateUTC
279
+ }
276
280
 
277
281
  return sanitizedCancellationPolicies
278
282
  }
@@ -340,10 +344,7 @@ export function getPenaltyPercentage({
340
344
  date: datetime,
341
345
  })
342
346
 
343
- return (
344
- matchingCancellationPolicies[0] &&
345
- matchingCancellationPolicies[0].penaltyPercentage
346
- )
347
+ return matchingCancellationPolicies[0]?.penaltyPercentage ?? 0
347
348
  }
348
349
 
349
350
  export function getCurrentPenaltyPercentage({
@@ -383,7 +384,7 @@ export function isBetterCancellationPolicies(
383
384
  return false
384
385
  }
385
386
 
386
- if (!newVal[0].dateTo) {
387
+ if (!newVal[0]?.dateTo) {
387
388
  return oldVal.every(oldCancellationPolicy => {
388
389
  const relatedNewCancellationPolicy = newVal.find(newCancellationPolicy =>
389
390
  dayjs(oldCancellationPolicy.dateTo).isBetween(
@@ -470,11 +471,17 @@ export function getSanitizedCancellationPolicies({
470
471
  export function getCurrentCancellationPolicy(
471
472
  sanitizedCancellationPolicies: ICancellationPolicy[],
472
473
  ): ICancellationPolicy {
473
- return (
474
- sanitizedCancellationPolicies.find(policy =>
475
- dayjs().isBetween(dayjs(policy.dateFrom), dayjs(policy.dateTo)),
476
- ) || sanitizedCancellationPolicies[0]
474
+ const found = sanitizedCancellationPolicies.find(policy =>
475
+ dayjs().isBetween(dayjs(policy.dateFrom), dayjs(policy.dateTo)),
477
476
  )
477
+ if (found) {
478
+ return found
479
+ }
480
+ const first = sanitizedCancellationPolicies[0]
481
+ if (!first) {
482
+ throw new Error('No cancellation policies available')
483
+ }
484
+ return first
478
485
  }
479
486
 
480
487
  function adjustIfFullHour(date: string): Dayjs {
@@ -20,3 +20,4 @@ export type * from './hotel.ts'
20
20
  export * from './hotel-offer.ts'
21
21
  export * from './contact-person.ts'
22
22
  export type * from './hotel-review-rating.ts'
23
+ export type * from './travel-times.ts'
@@ -0,0 +1,4 @@
1
+ export interface GeoCoordinates {
2
+ latitude: number
3
+ longitude: number
4
+ }
@@ -6,6 +6,7 @@ export type * from './country.ts'
6
6
  export type * from './currency.ts'
7
7
  export type * from './date.ts'
8
8
  export type * from './event.ts'
9
+ export type * from './geo-coordinates.ts'
9
10
  export type * from './hotel-contract.ts'
10
11
  export type * from './hotel-room-stock.ts'
11
12
  export type * from './money-object.ts'
@@ -7,14 +7,26 @@ export function chunk<T>(array: T[], size: number): T[][] {
7
7
  }
8
8
 
9
9
  export function getRandomElementFromArray<T>(array: readonly T[]): T {
10
- return array[Math.floor(Math.random() * array.length)]
10
+ if (array.length === 0) {
11
+ throw new Error('Cannot get random element from empty array')
12
+ }
13
+ const element = array[Math.floor(Math.random() * array.length)]
14
+ if (element === undefined) {
15
+ throw new Error('Array element is undefined')
16
+ }
17
+ return element
11
18
  }
12
19
 
13
20
  export function shuffleArray<T>(array: T[]): T[] {
14
21
  const shuffled = [...array]
15
22
  for (let i = shuffled.length - 1; i > 0; i--) {
16
23
  const j = Math.floor(Math.random() * (i + 1))
17
- ;[shuffled[i], shuffled[j]] = [shuffled[j], shuffled[i]]
24
+ const temp = shuffled[i]
25
+ const swap = shuffled[j]
26
+ if (temp !== undefined && swap !== undefined) {
27
+ shuffled[i] = swap
28
+ shuffled[j] = temp
29
+ }
18
30
  }
19
31
  return shuffled
20
32
  }
@@ -171,11 +183,11 @@ export function sortBy<T>(
171
183
  const valueA =
172
184
  typeof resolvedIteratee === 'function'
173
185
  ? resolvedIteratee(a)
174
- : a[resolvedIteratee]
186
+ : a[resolvedIteratee as keyof T]
175
187
  const valueB =
176
188
  typeof resolvedIteratee === 'function'
177
189
  ? resolvedIteratee(b)
178
- : b[resolvedIteratee]
190
+ : b[resolvedIteratee as keyof T]
179
191
 
180
192
  if (valueA === valueB) {
181
193
  if (i === normalizedIteratees.length - 1) {
@@ -9,6 +9,9 @@ export function generateRandomColorFromString(
9
9
  const hueRange = 5
10
10
  const randomIndex = Math.floor(num1 * existingColors.length)
11
11
  const baseColor = existingColors[randomIndex]
12
+ if (!baseColor) {
13
+ throw new Error('Base color not found')
14
+ }
12
15
  // extract the hue value from the base color
13
16
  const baseHue = Number.parseInt(baseColor.slice(1, 3), 16)
14
17
  const minHue = Math.max(0, baseHue - hueRange)
@@ -44,14 +44,22 @@ export function sanitizeDateRange(
44
44
  if (sortedDates.length === 2) {
45
45
  return sortedDates as [string, string]
46
46
  } else if (sortedDates.length === 1) {
47
- if (sortedDates[0] === dayjs().format('YYYY-MM-DD')) {
47
+ const firstDate = sortedDates[0]
48
+ if (!firstDate) {
48
49
  return [
49
50
  dayjs().format('YYYY-MM-DD'),
50
51
  dayjs().add(1, 'day').format('YYYY-MM-DD'),
51
52
  ]
52
53
  }
53
54
 
54
- return [dayjs().format('YYYY-MM-DD'), sortedDates[0]]
55
+ if (firstDate === dayjs().format('YYYY-MM-DD')) {
56
+ return [
57
+ dayjs().format('YYYY-MM-DD'),
58
+ dayjs().add(1, 'day').format('YYYY-MM-DD'),
59
+ ]
60
+ }
61
+
62
+ return [dayjs().format('YYYY-MM-DD'), firstDate]
55
63
  }
56
64
 
57
65
  return [
package/src/utils/math.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export function weightedMean(values: number[], weights: number[]): number {
2
2
  const sum = values.reduce(
3
- (acc: number, val: number, i: number) => acc + val * weights[i],
3
+ (acc: number, val: number, i: number) => acc + val * (weights[i] ?? 0),
4
4
  0,
5
5
  )
6
6
  const sumWeights = weights.reduce((acc: number, val: number) => acc + val, 0)
@@ -124,3 +124,43 @@ export function omitBy<T extends object>(
124
124
 
125
125
  return result
126
126
  }
127
+
128
+ /**
129
+ * Creates a shallow clone of `object` excluding the given own enumerable keys.
130
+ * Accepts a single key or an array of keys. Symbol keys are supported.
131
+ * If `object` is nullish, returns an empty object.
132
+ */
133
+ export function omit<T extends object, K extends keyof T>(
134
+ object: T | null | undefined,
135
+ keys: readonly K[] | K,
136
+ ): Omit<T, K> {
137
+ if (object === null || object === undefined) {
138
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
139
+ return {} as any
140
+ }
141
+
142
+ const keysArray = (
143
+ Array.isArray(keys) ? keys : [keys]
144
+ ) as readonly (keyof T)[]
145
+ const keysSet = new Set<keyof T>(keysArray as (keyof T)[])
146
+
147
+ const result: Partial<T> = {}
148
+
149
+ // Copy string/number keys
150
+ for (const key in object) {
151
+ if (Object.hasOwn(object, key) && !keysSet.has(key as keyof T)) {
152
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
153
+ ;(result as any)[key] = object[key as keyof T]
154
+ }
155
+ }
156
+
157
+ // Copy symbol keys
158
+ for (const sym of Object.getOwnPropertySymbols(object)) {
159
+ if (!keysSet.has(sym as keyof T)) {
160
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
161
+ ;(result as any)[sym as unknown as keyof T] = (object as any)[sym]
162
+ }
163
+ }
164
+
165
+ return result as Omit<T, K>
166
+ }
@@ -160,18 +160,17 @@ export class Poller<V extends IPollerResponse> {
160
160
  }
161
161
 
162
162
  private buildPollerOptions(options: TOptions<V>): TOptions<V> {
163
- const compactedOptions = Object.entries(options).reduce<TOptions<V>>(
164
- (acc, [key, value]) => {
165
- if (value !== undefined) {
166
- const tKey = key as keyof TOptions<V>
167
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
168
- acc[tKey] = value as any
169
- }
170
-
171
- return acc
172
- },
173
- {},
174
- )
163
+ const compactedOptions = Object.entries(options).reduce<
164
+ Record<string, unknown>
165
+ >((acc, [key, value]) => {
166
+ if (value !== undefined) {
167
+ const tKey = key as keyof TOptions<V>
168
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
169
+ acc[tKey] = value as any
170
+ }
171
+
172
+ return acc
173
+ }, {}) as TOptions<V>
175
174
 
176
175
  return {
177
176
  ...this.defaultOptions,