@revolugo/common 6.9.6 → 6.9.7-beta.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.
Files changed (63) hide show
  1. package/package.json +12 -7
  2. package/src/cancellation-policies.test.ts +12 -9
  3. package/src/cancellation-policies.ts +31 -26
  4. package/src/constants/countries.ts +0 -2515
  5. package/src/constants/currencies.ts +0 -1812
  6. package/src/constants/environment.ts +1 -0
  7. package/src/constants/hotel-offers.ts +2 -0
  8. package/src/constants/hotel.ts +3 -0
  9. package/src/constants/locales.ts +6 -0
  10. package/src/constants/measurement.ts +1 -0
  11. package/src/constants/time.ts +1 -0
  12. package/src/countries/constants.ts +2518 -0
  13. package/src/countries/index.ts +7 -0
  14. package/src/currencies/index.ts +1817 -0
  15. package/src/models/paginated-queries.ts +1 -0
  16. package/src/types/country.ts +1 -1
  17. package/src/types/elements/amenity.ts +266 -0
  18. package/src/types/elements/bed.ts +20 -0
  19. package/src/types/elements/booking-policy.ts +80 -0
  20. package/src/types/elements/booking.ts +236 -0
  21. package/src/types/elements/cancellation-policy.ts +20 -0
  22. package/src/types/elements/contact-person.ts +158 -0
  23. package/src/types/elements/currency.ts +3 -0
  24. package/src/types/elements/event-metadata.ts +38 -0
  25. package/src/types/elements/event.ts +14 -0
  26. package/src/types/elements/hotel-image.ts +44 -0
  27. package/src/types/elements/hotel-images.ts +47 -0
  28. package/src/types/elements/hotel-offer-request.ts +82 -0
  29. package/src/types/elements/hotel-offer.ts +208 -0
  30. package/src/types/elements/hotel-review-rating.ts +14 -0
  31. package/src/types/elements/hotel-room-offer-package-type.ts +8 -0
  32. package/src/types/elements/hotel-room-offer-request.ts +77 -0
  33. package/src/types/elements/hotel-room-offer-type.ts +6 -0
  34. package/src/types/elements/hotel-room-offer.ts +192 -0
  35. package/src/types/elements/hotel-room.ts +102 -0
  36. package/src/types/elements/hotel-rooming-list.ts +49 -0
  37. package/src/types/elements/hotel.ts +184 -0
  38. package/src/types/elements/index.ts +22 -0
  39. package/src/types/elements/invoice.ts +21 -0
  40. package/src/types/elements/payment-method.ts +159 -0
  41. package/src/types/elements/source-market.ts +247 -0
  42. package/src/types/elements/tag.ts +32 -0
  43. package/src/types/elements/tax.ts +52 -0
  44. package/src/types/elements/travel-times.ts +45 -0
  45. package/src/types/index.ts +1 -0
  46. package/src/utils/array-tools.ts +3 -2
  47. package/src/utils/case-transformers.ts +1 -0
  48. package/src/utils/colors.ts +4 -4
  49. package/src/utils/currency.ts +30 -18
  50. package/src/utils/dates.ts +6 -10
  51. package/src/utils/debounce.ts +2 -2
  52. package/src/utils/find-unique-keys.ts +2 -2
  53. package/src/utils/get-guest-count.ts +1 -0
  54. package/src/utils/index.ts +1 -1
  55. package/src/utils/lang-default-fallbacks.ts +1 -1
  56. package/src/utils/math.ts +3 -3
  57. package/src/utils/numbers.ts +8 -7
  58. package/src/utils/object-tools.ts +60 -2
  59. package/src/utils/poller.ts +1 -0
  60. package/src/utils/random.ts +12 -0
  61. package/src/utils/strings.ts +5 -2
  62. package/src/utils/validators.ts +1 -0
  63. package/src/utils/countries.ts +0 -4
@@ -1,6 +1,8 @@
1
- import { CURRENCIES_MAP, type Currency } from '../constants/index.ts'
1
+ import { CURRENCIES_MAP } from '../currencies/index.ts'
2
2
 
3
- export const getCurrencySymbol = (currency: Currency): string => {
3
+ import type { Currency } from '../constants/currencies.ts'
4
+
5
+ export function getCurrencySymbol(currency: Currency): string {
4
6
  const symbol = CURRENCIES_MAP[currency]?.symbol
5
7
 
6
8
  if (!symbol) {
@@ -10,16 +12,19 @@ export const getCurrencySymbol = (currency: Currency): string => {
10
12
  return symbol
11
13
  }
12
14
 
13
- export const isZeroDecimal = (currency: Currency): boolean =>
14
- (CURRENCIES_MAP[currency] && CURRENCIES_MAP[currency].zeroDecimal) || false
15
+ export function isZeroDecimal(currency: Currency): boolean {
16
+ return (
17
+ (CURRENCIES_MAP[currency] && CURRENCIES_MAP[currency].zeroDecimal) || false
18
+ )
19
+ }
15
20
 
16
- export const normalizeAmount = ({
21
+ export function normalizeAmount({
17
22
  amount,
18
23
  currency,
19
24
  }: {
20
25
  amount: number
21
26
  currency: Currency
22
- }): number => {
27
+ }): number {
23
28
  if (isZeroDecimal(currency)) {
24
29
  return amount
25
30
  }
@@ -27,13 +32,13 @@ export const normalizeAmount = ({
27
32
  return amount * 100
28
33
  }
29
34
 
30
- export const denormalizeAmount = ({
35
+ export function denormalizeAmount({
31
36
  amount,
32
37
  currency,
33
38
  }: {
34
39
  amount: number
35
40
  currency: Currency
36
- }): number => {
41
+ }): number {
37
42
  if (isZeroDecimal(currency)) {
38
43
  return amount
39
44
  }
@@ -41,17 +46,17 @@ export const denormalizeAmount = ({
41
46
  return amount / 100
42
47
  }
43
48
 
44
- export const formatAmount = ({
49
+ export function formatAmount({
45
50
  amount,
46
51
  currency,
47
52
  locale = 'en',
48
- space = ' ',
53
+ space = '',
49
54
  }: {
50
55
  amount: number
51
56
  currency: string
52
57
  locale?: string
53
58
  space?: string
54
- }): string => {
59
+ }): string {
55
60
  const fractionDigits = amount.toFixed(2).endsWith('.00') ? 0 : 2
56
61
 
57
62
  return (
@@ -70,6 +75,7 @@ export const formatAmount = ({
70
75
  )
71
76
  }
72
77
 
78
+ /* @__PURE__ */
73
79
  export class MoneyCalculator {
74
80
  private amount: number
75
81
  private currency: Currency
@@ -142,6 +148,12 @@ export class MoneyCalculator {
142
148
  return this
143
149
  }
144
150
 
151
+ public round(): this {
152
+ this.amount = Math.round(this.amount)
153
+
154
+ return this
155
+ }
156
+
145
157
  public format(locale?: string, space?: string): string {
146
158
  return formatAmount({
147
159
  amount: this.amount,
@@ -166,16 +178,16 @@ export class MoneyCalculator {
166
178
  return this
167
179
  }
168
180
 
169
- const { isNormalized } = this
181
+ const startingIsNormalized = this.isNormalized
170
182
 
171
- if (isNormalized) {
183
+ if (startingIsNormalized) {
172
184
  this.denormalize()
173
185
  }
174
186
 
175
187
  this.amount *= exchangeRate
176
188
  this.currency = currency
177
189
 
178
- if (isNormalized) {
190
+ if (startingIsNormalized) {
179
191
  this.normalize()
180
192
  }
181
193
 
@@ -183,13 +195,13 @@ export class MoneyCalculator {
183
195
  }
184
196
  }
185
197
 
186
- export const ceilNormalizedAmount = ({
198
+ export function ceilNormalizedAmount({
187
199
  amount,
188
200
  currency,
189
201
  }: {
190
202
  amount: number
191
203
  currency: Currency
192
- }): number => {
204
+ }): number {
193
205
  const denormalizedAmount = denormalizeAmount({
194
206
  amount,
195
207
  currency,
@@ -201,13 +213,13 @@ export const ceilNormalizedAmount = ({
201
213
  })
202
214
  }
203
215
 
204
- export const floorNormalizedAmount = ({
216
+ export function floorNormalizedAmount({
205
217
  amount,
206
218
  currency,
207
219
  }: {
208
220
  amount: number
209
221
  currency: Currency
210
- }): number => {
222
+ }): number {
211
223
  const denormalizedAmount = denormalizeAmount({
212
224
  amount,
213
225
  currency,
@@ -1,5 +1,3 @@
1
- import { uniq } from 'lodash-es'
2
-
3
1
  import { DATE_STRING_FORMAT } from '../constants/index.ts'
4
2
 
5
3
  import { dayjs } from './dayjs.ts'
@@ -20,11 +18,11 @@ export function sortDates(dates: string[]): string[] {
20
18
  return validDates.sort((a, b) => (dayjs(a).isAfter(dayjs(b), 'day') ? 1 : -1))
21
19
  }
22
20
 
23
- export const getDateRange = (
21
+ export function getDateRange(
24
22
  start: Date | string,
25
23
  end: Date | string,
26
24
  format: string = DATE_STRING_FORMAT,
27
- ): string[] => {
25
+ ): string[] {
28
26
  const dates: string[] = []
29
27
  let current = dayjs(start)
30
28
 
@@ -41,7 +39,7 @@ export function sanitizeDateRange(
41
39
  dateA: string,
42
40
  dateB: string,
43
41
  ): [string, string] {
44
- const sortedDates = uniq(sortDates([dateA, dateB]))
42
+ const sortedDates = [...new Set(sortDates([dateA, dateB]))]
45
43
 
46
44
  if (sortedDates.length === 2) {
47
45
  return sortedDates as [string, string]
@@ -80,11 +78,9 @@ export function generateDates(
80
78
  }
81
79
 
82
80
  const totalDays = end.diff(start, 'day') + 1
83
- const dates = new Array<Date>(totalDays)
84
-
85
- for (let i = 0; i < totalDays; i++) {
86
- dates[i] = start.add(i, 'day').toDate()
87
- }
81
+ const dates = Array.from({ length: totalDays }, (_, i) =>
82
+ start.add(i, 'day').toDate(),
83
+ )
88
84
 
89
85
  return dates
90
86
  }
@@ -46,7 +46,7 @@ export function debounce<Args extends any[], F extends (...args: Args) => any>(
46
46
  return waitMilliseconds
47
47
  }
48
48
 
49
- const debouncedFunction = function debouncedFunction(
49
+ function debouncedFunction(
50
50
  this: ThisParameterType<F>,
51
51
  ...args: Parameters<F>
52
52
  ) {
@@ -54,7 +54,7 @@ export function debounce<Args extends any[], F extends (...args: Args) => any>(
54
54
  const context = this
55
55
  // eslint-disable-next-line consistent-return
56
56
  return new Promise<Awaited<ReturnType<F>>>((resolve, reject) => {
57
- const invokeFunction = function invokeFunction() {
57
+ function invokeFunction() {
58
58
  timeoutId = undefined
59
59
  lastInvokeTime = Date.now()
60
60
  if (!isImmediate) {
@@ -1,6 +1,6 @@
1
- export const findUniqueKeys = (
1
+ export function findUniqueKeys(
2
2
  objects: { [key: string]: unknown }[],
3
- ): string[] => {
3
+ ): string[] {
4
4
  const objectKeys = objects.flatMap(Object.keys)
5
5
  return [...new Set(objectKeys)]
6
6
  }
@@ -1,5 +1,6 @@
1
1
  import { parseChildren } from './children-tools.ts'
2
2
 
3
+ /* @__PURE__ */
3
4
  export const CHILDREN_FREE_BREAKFAST_AGE_LIMIT = 4
4
5
 
5
6
  export function getGuestCount(
@@ -2,7 +2,6 @@ export * from './add-classes.ts'
2
2
  export * from './array-tools.ts'
3
3
  export * from './case-transformers.ts'
4
4
  export * from './colors.ts'
5
- export * from './countries.ts'
6
5
  export * from './currency.ts'
7
6
  export * from './dates.ts'
8
7
  export * from './dayjs.ts'
@@ -18,6 +17,7 @@ export * from './numbers.ts'
18
17
  export * from './object-tools.ts'
19
18
  export * from './poller.ts'
20
19
  export * from './promise-tools.ts'
20
+ export * from './random.ts'
21
21
  export * from './range.ts'
22
22
  export * from './strings.ts'
23
23
  export * from './sum.ts'
@@ -2,7 +2,7 @@ import { LOCALE_TO_LANG, Locale } from '../constants/locales.ts'
2
2
 
3
3
  import type { Lang } from '../constants/locales.ts'
4
4
 
5
- export const langDefaultFallbacks = (lang?: Locale): Lang[] => {
5
+ export function langDefaultFallbacks(lang?: Locale): Lang[] {
6
6
  if (!lang || lang === Locale.en_US) {
7
7
  return [LOCALE_TO_LANG[Locale.en_US]]
8
8
  }
package/src/utils/math.ts CHANGED
@@ -1,4 +1,4 @@
1
- export const weightedMean = (values: number[], weights: number[]): number => {
1
+ export function weightedMean(values: number[], weights: number[]): number {
2
2
  const sum = values.reduce(
3
3
  (acc: number, val: number, i: number) => acc + val * weights[i],
4
4
  0,
@@ -8,11 +8,11 @@ export const weightedMean = (values: number[], weights: number[]): number => {
8
8
  return sum / sumWeights
9
9
  }
10
10
 
11
- export const amountFromPercentage = (
11
+ export function amountFromPercentage(
12
12
  percentage: number,
13
13
  amount: number,
14
14
  roundingType: 'none' | 'round' | 'ceil' | 'floor' = 'none',
15
- ): number => {
15
+ ): number {
16
16
  if (Number.isNaN(Number(percentage)) || Number.isNaN(Number(amount))) {
17
17
  throw new TypeError(`${percentage} || ${amount} is NaN`)
18
18
  }
@@ -1,4 +1,4 @@
1
- export const generateNumbersFromStr = (str: string): [number, number] => {
1
+ export function generateNumbersFromStr(str: string): [number, number] {
2
2
  let hash = 5381
3
3
  for (let i = 0; i < str.length; i++) {
4
4
  // eslint-disable-next-line no-bitwise
@@ -14,13 +14,14 @@ export const generateNumbersFromStr = (str: string): [number, number] => {
14
14
  return [num1, num2]
15
15
  }
16
16
 
17
- export const randomInt = (min: number, max: number): number =>
18
- Math.floor(Math.random() * (max - min + 1) + min)
17
+ export function randomInt(min: number, max: number): number {
18
+ return Math.floor(Math.random() * (max - min + 1) + min)
19
+ }
19
20
 
20
- export const computeSellingPrice = (
21
+ export function computeSellingPrice(
21
22
  buyingPrice: number | string | null = 0,
22
23
  rate: number | string | null = 0,
23
- ): number => {
24
+ ): number {
24
25
  if (Number.isNaN(Number(buyingPrice)) || Number.isNaN(Number(rate))) {
25
26
  throw new TypeError('price or rate is NaN')
26
27
  }
@@ -30,10 +31,10 @@ export const computeSellingPrice = (
30
31
  return Math.ceil(Math.floor(sellingPrice * 100) / 100)
31
32
  }
32
33
 
33
- export const computeMarginRate = (
34
+ export function computeMarginRate(
34
35
  buyingPrice: number | string,
35
36
  sellingPrice: number | string,
36
- ): number => {
37
+ ): number {
37
38
  const buyingPriceNum = Number(buyingPrice)
38
39
  const sellingPriceNum = Number(sellingPrice)
39
40
 
@@ -15,10 +15,10 @@ type Merge<T, S> = {
15
15
  : never
16
16
  }
17
17
 
18
- export const customMerge = <T extends object, S extends object>(
18
+ export function customMerge<T extends object, S extends object>(
19
19
  target: T,
20
20
  source: S,
21
- ): Merge<T, S> => {
21
+ ): Merge<T, S> {
22
22
  for (const key of Object.keys(source)) {
23
23
  const sourceValue = source[key as keyof S]
24
24
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -60,3 +60,61 @@ export function compactObject<T extends object>(obj: T): Partial<T> {
60
60
  Object.entries(obj).filter(([, value]) => !isNil(value)),
61
61
  ) as Partial<T>
62
62
  }
63
+
64
+ /**
65
+ * Creates an object composed of keys generated from the results of running each element of collection through iteratee.
66
+ * The corresponding value of each key is the last element responsible for generating the key.
67
+ *
68
+ * @param collection - The collection to iterate over
69
+ * @param iteratee - The iteratee to transform keys. Can be a function or a property name
70
+ * @returns Returns the composed aggregate object
71
+ */
72
+ export function keyBy<T>(
73
+ collection: T[],
74
+ iteratee: ((value: T) => string | number) | keyof T,
75
+ ): Record<string, T> {
76
+ return collection.reduce<Record<string, T>>((acc, item) => {
77
+ const key =
78
+ typeof iteratee === 'function' ? iteratee(item) : String(item[iteratee])
79
+ acc[key] = item
80
+ return acc
81
+ }, {})
82
+ }
83
+
84
+ /**
85
+ * Creates an object composed of the own enumerable properties of object that predicate doesn't return truthy for.
86
+ * The predicate is invoked with two arguments: (value, key).
87
+ * If predicate is a string, it omits the property with that key name.
88
+ *
89
+ * @param object - The source object
90
+ * @param predicate - The function invoked per property or a string key to omit
91
+ * @returns Returns the new object
92
+ */
93
+ export function omitBy<T extends object>(
94
+ object: T,
95
+ predicate: ((value: T[keyof T], key: keyof T) => boolean) | string,
96
+ ): Partial<T> {
97
+ const result = {} as Partial<T>
98
+
99
+ for (const key in object) {
100
+ if (Object.hasOwn(object, key)) {
101
+ const value = object[key]
102
+
103
+ // If predicate is a string, check if key matches
104
+ if (typeof predicate === 'string') {
105
+ // eslint-disable-next-line max-depth
106
+ if (key !== predicate) {
107
+ result[key] = value
108
+ }
109
+ } else if (typeof predicate === 'function') {
110
+ // If predicate is a function, use it
111
+ // eslint-disable-next-line max-depth
112
+ if (!predicate(value, key)) {
113
+ result[key] = value
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ return result
120
+ }
@@ -21,6 +21,7 @@ export type TPollerEvents<V extends IPollerResponse = IPollerResponse> = {
21
21
  [k in TPollerEventName]: TPollerEventCallback<V>
22
22
  }
23
23
 
24
+ /* @__PURE__ */
24
25
  const INTERVAL = 1500
25
26
 
26
27
  export interface IPollerOptions<U> {
@@ -0,0 +1,12 @@
1
+ export function getRandomInt(min: number, max: number): number {
2
+ const roundedMin = Math.ceil(min)
3
+ const roundedMax = Math.floor(max)
4
+
5
+ return Math.floor(Math.random() * (roundedMax - roundedMin + 1)) + roundedMin
6
+ }
7
+
8
+ export function getRandomHexColor(): string {
9
+ const hex = Math.floor(Math.random() * 0xffffff).toString(16)
10
+
11
+ return hex.padStart(6, '0').toUpperCase()
12
+ }
@@ -1,6 +1,8 @@
1
- export const generatePseudoRandomString = (length: number): string =>
2
- Array.from({ length }, () => Math.random().toString(36)[2]).join('')
1
+ export function generatePseudoRandomString(length: number): string {
2
+ return Array.from({ length }, () => Math.random().toString(36)[2]).join('')
3
+ }
3
4
 
5
+ /* @__PURE__ */
4
6
  const TS_QUERY_SPECIAL_CHARS = new Set([
5
7
  '&',
6
8
  '|',
@@ -13,6 +15,7 @@ const TS_QUERY_SPECIAL_CHARS = new Set([
13
15
  '@',
14
16
  ])
15
17
 
18
+ /* @__PURE__ */
16
19
  const REGEX_SPECIAL_CHARS = new Set(['|', '(', ')'])
17
20
 
18
21
  export function prepareTsQuery(query: string): string | null {
@@ -1,3 +1,4 @@
1
+ /* @__PURE__ */
1
2
  export const validators = {
2
3
  alpha: (value: string): boolean => /[a-zA-Z]/u.test(value),
3
4
  email: (value: string): boolean => /.+@.+\..+/u.test(value),
@@ -1,4 +0,0 @@
1
- import { EU_COUNTRIES_ISO2_CODE } from '../constants/countries.ts'
2
-
3
- export const isInEu = (countryCode: string): boolean =>
4
- EU_COUNTRIES_ISO2_CODE.has(countryCode)