guesty-client 0.1.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.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +34 -0
  3. data/LICENSE +21 -0
  4. data/README.md +178 -0
  5. data/lib/guesty/access_tokens/upsert.rb +61 -0
  6. data/lib/guesty/api_error.rb +73 -0
  7. data/lib/guesty/client.rb +138 -0
  8. data/lib/guesty/config.rb +29 -0
  9. data/lib/guesty/conversations/attachments/index.rb +42 -0
  10. data/lib/guesty/conversations/index.rb +58 -0
  11. data/lib/guesty/conversations/messages/reply.rb +55 -0
  12. data/lib/guesty/conversations/posts/index.rb +121 -0
  13. data/lib/guesty/conversations/posts/since.rb +37 -0
  14. data/lib/guesty/conversations/search.rb +31 -0
  15. data/lib/guesty/conversations/show.rb +25 -0
  16. data/lib/guesty/conversations.rb +15 -0
  17. data/lib/guesty/error.rb +32 -0
  18. data/lib/guesty/guest_folio/invoice_items/index.rb +61 -0
  19. data/lib/guesty/guests/profiles/create.rb +25 -0
  20. data/lib/guesty/guests/profiles/show.rb +23 -0
  21. data/lib/guesty/guests/profiles/update.rb +36 -0
  22. data/lib/guesty/guests.rb +5 -0
  23. data/lib/guesty/homes/calendars/show.rb +134 -0
  24. data/lib/guesty/homes/search.rb +46 -0
  25. data/lib/guesty/memory_rate_limiter.rb +28 -0
  26. data/lib/guesty/memory_token_store.rb +33 -0
  27. data/lib/guesty/operation.rb +37 -0
  28. data/lib/guesty/rate_limiter_middleware.rb +23 -0
  29. data/lib/guesty/reservations/accommodation_fare/update.rb +44 -0
  30. data/lib/guesty/reservations/approve.rb +23 -0
  31. data/lib/guesty/reservations/create.rb +50 -0
  32. data/lib/guesty/reservations/custom_fields/update.rb +26 -0
  33. data/lib/guesty/reservations/dates/update.rb +41 -0
  34. data/lib/guesty/reservations/decline.rb +30 -0
  35. data/lib/guesty/reservations/flags/update.rb +33 -0
  36. data/lib/guesty/reservations/payments/create.rb +72 -0
  37. data/lib/guesty/reservations/pre_approve.rb +23 -0
  38. data/lib/guesty/reservations/recover.rb +27 -0
  39. data/lib/guesty/reservations/reviews/extractors/airbnb.rb +66 -0
  40. data/lib/guesty/reservations/reviews/extractors/base.rb +36 -0
  41. data/lib/guesty/reservations/reviews/extractors/booking_com.rb +35 -0
  42. data/lib/guesty/reservations/reviews/extractors/vrbo.rb +46 -0
  43. data/lib/guesty/reservations/reviews/index.rb +67 -0
  44. data/lib/guesty/reservations/search.rb +63 -0
  45. data/lib/guesty/reservations/show.rb +28 -0
  46. data/lib/guesty/reservations/status/cancel.rb +34 -0
  47. data/lib/guesty/reservations/status/update.rb +21 -0
  48. data/lib/guesty/reservations/stays/update.rb +42 -0
  49. data/lib/guesty/reservations/update.rb +19 -0
  50. data/lib/guesty/reservations.rb +13 -0
  51. data/lib/guesty/reviews/respond.rb +19 -0
  52. data/lib/guesty/version.rb +3 -0
  53. data/lib/guesty/views/create.rb +19 -0
  54. data/lib/guesty/views/update.rb +33 -0
  55. data/lib/guesty/webhooks/create.rb +21 -0
  56. data/lib/guesty/webhooks/index.rb +18 -0
  57. data/lib/guesty/webhooks/signatures/verify.rb +76 -0
  58. data/lib/guesty/webhooks/sync.rb +36 -0
  59. data/lib/guesty/webhooks/update.rb +22 -0
  60. data/lib/guesty-client.rb +1 -0
  61. data/lib/guesty.rb +78 -0
  62. data/sig/guesty.rbs +427 -0
  63. metadata +191 -0
@@ -0,0 +1,67 @@
1
+ module Guesty
2
+ module Reservations
3
+ module Reviews
4
+ # startDate/endDate filter on the review's updatedAt, newest update first.
5
+ class Index
6
+ include Guesty::Operation
7
+
8
+ # @rbs (since: ::Time, ?skip: ::Integer, ?take: ::Integer) -> Dry::Monads::Result[::Array[::Hash[::Symbol, untyped]]]
9
+ def call(since:, skip: 0, take: 100)
10
+ argument! take: :invalid if take.blank? || take <= 0
11
+
12
+ response = Guesty.do_request(:get, 'reviews', query(since, skip, take))
13
+
14
+ return response unless response.success?
15
+
16
+ reviews = parse_reviews(response.value!.body[:data])
17
+
18
+ Success(reviews)
19
+ end
20
+
21
+ private
22
+
23
+ # @rbs (::Time since, ::Integer skip, ::Integer take) -> ::Hash[::Symbol, untyped]
24
+ def query(since, skip, take)
25
+ {
26
+ startDate: since.utc.iso8601,
27
+ skip:,
28
+ limit: take
29
+ }
30
+ end
31
+
32
+ # @rbs (::Array[::Hash[::Symbol, untyped]] guesty_reviews_data) -> ::Array[::Hash[::Symbol, untyped]]
33
+ def parse_reviews(guesty_reviews_data)
34
+ return [] unless guesty_reviews_data.is_a?(Array)
35
+
36
+ guesty_reviews_data.map do |review_data|
37
+ next unless review_data[:rawReview].is_a?(Hash)
38
+
39
+ extractor = get_extractor_for_channel(review_data[:channelId]&.downcase)
40
+ result = extractor.new.call(raw_review: review_data[:rawReview])
41
+ next unless result.success?
42
+
43
+ result.value!.merge(
44
+ created_at: review_data[:createdAt],
45
+ guesty_review_id: review_data[:_id],
46
+ guesty_reservation_id: review_data[:reservationId]
47
+ )
48
+ end.compact
49
+ end
50
+
51
+ # @rbs (::String? channel) -> untyped
52
+ def get_extractor_for_channel(channel)
53
+ case channel.to_s.downcase
54
+ when /airbnb/i
55
+ Extractors::Airbnb
56
+ when /booking/i
57
+ Extractors::BookingCom
58
+ when /vrbo|homeaway/i
59
+ Extractors::Vrbo
60
+ else
61
+ error! "Unsupported channel: #{channel}"
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,63 @@
1
+ module Guesty
2
+ module Reservations
3
+ # Searches the legacy /reservations index (deprecated, switching off at the
4
+ # end of 2026 — new reservation calls use reservations-v3).
5
+ class Search
6
+ include Guesty::Operation
7
+
8
+ FILTER_MAPPINGS = {
9
+ ids: { field: '_id', operator: '$in' },
10
+ updated_at: { field: 'lastUpdatedAt', operator: '$gt' },
11
+ conversation_id: { field: 'conversationId', operator: '$eq' },
12
+ status: { field: 'status', operator: '$eq' },
13
+ confirmation_code: { field: 'confirmationCode', operator: '$eq' }
14
+ }.freeze
15
+
16
+ # @rbs (::Hash[::Symbol, untyped] attributes) -> ::Array[::Hash[::Symbol, untyped]]
17
+ def self.filters(attributes)
18
+ attributes.map do |key, value|
19
+ normalized = key == :updated_at ? value&.strftime('%Y-%m-%d') : value
20
+
21
+ FILTER_MAPPINGS.fetch(key).merge(value: normalized)
22
+ end
23
+ end
24
+
25
+ # @rbs (fields: ::Array[::String], attributes: ::Hash[::Symbol, untyped], ?skip: ::Integer, ?take: ::Integer) -> Dry::Monads::Result[::Hash[::Symbol, untyped]]
26
+ def call(fields:, attributes:, skip: 0, take: 100)
27
+ validate_arguments!(fields:, attributes:, take:)
28
+
29
+ response = Guesty.do_request(:get, 'reservations', params(fields:, attributes:, skip:, take:))
30
+ return response unless response.success?
31
+
32
+ body = response.value!.body
33
+ result = {
34
+ results: body[:results],
35
+ count: body[:count]
36
+ }
37
+
38
+ Success(result)
39
+ end
40
+
41
+ private
42
+
43
+ def validate_arguments!(fields:, attributes:, take:)
44
+ argument! fields: :required, fatal: true if fields.blank?
45
+ argument! attributes: :required if attributes.blank?
46
+ argument! take: :invalid if take && take <= 0
47
+ argument! attributes: :invalid unless attributes.keys.all? { |name| FILTER_MAPPINGS.key?(name) }
48
+ argument! updated_at: :required if attributes.key?(:updated_at) && attributes[:updated_at].blank?
49
+ argument! ids: :required if attributes.key?(:ids) && attributes[:ids].empty?
50
+ end
51
+
52
+ def params(fields:, attributes:, skip:, take:)
53
+ {
54
+ filters: self.class.filters(attributes).to_json,
55
+ sort: 'createdAt',
56
+ limit: take,
57
+ skip:,
58
+ fields: fields.join(' ')
59
+ }
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,28 @@
1
+ module Guesty
2
+ module Reservations
3
+ class Show
4
+ include Guesty::Operation
5
+
6
+ # @rbs (reservation_id: ::String, fields: ::Array[::String]) -> Dry::Monads::Result[::Hash[::Symbol, untyped]]
7
+ def call(reservation_id:, fields: [])
8
+ argument! reservation_id: :required if reservation_id.blank?
9
+ argument! fields: :required if fields.blank?
10
+
11
+ attributes = {} #: ::Hash[::Symbol, ::String]
12
+ attributes[:fields] = fields.join(' ') if fields.present?
13
+
14
+ response = Guesty.do_request :get, "reservations/#{reservation_id}", attributes
15
+
16
+ Success(handle_response(response))
17
+ end
18
+
19
+ private
20
+
21
+ def handle_response(response)
22
+ raise response.failure unless response.success?
23
+
24
+ response.value!.body
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,34 @@
1
+ module Guesty
2
+ module Reservations
3
+ module Status
4
+ class Cancel
5
+ include Guesty::Operation
6
+
7
+ CANCELLED_BY = {
8
+ guest: 'GUEST',
9
+ owner: 'OWNER',
10
+ staff: 'TEAM_MEMBER'
11
+ }.freeze #: ::Hash[::Symbol, ::String]
12
+
13
+ # @rbs (reservation_id: ::String, note: ::String, cancelled_by: ::Symbol) -> Dry::Monads::Result[bool]
14
+ def call(reservation_id:, note:, cancelled_by:)
15
+ argument! reservation_id: :required if reservation_id.blank?
16
+ argument! note: :required if note.blank?
17
+ argument! cancelled_by: :invalid unless CANCELLED_BY.key?(cancelled_by)
18
+
19
+ Update.new.call!(
20
+ reservation_id:,
21
+ attributes: {
22
+ status: CANCELLED_STATUS,
23
+ cancellationReason: 'No Reason Provided',
24
+ cancellationNote: note,
25
+ canceledBy: CANCELLED_BY.fetch(cancelled_by)
26
+ }
27
+ )
28
+
29
+ Success(true)
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ module Guesty
2
+ module Reservations
3
+ module Status
4
+ class Update
5
+ include Guesty::Operation
6
+
7
+ # @rbs (reservation_id: ::String, attributes: ::Hash[::Symbol, untyped]) -> Dry::Monads::Result[bool]
8
+ def call(reservation_id:, attributes:)
9
+ argument! reservation_id: :required if reservation_id.blank?
10
+ argument! attributes: :required if attributes.blank?
11
+
12
+ response = Guesty.do_request :put, "reservations-v3/#{reservation_id}/status", attributes
13
+
14
+ raise response.failure unless response.success?
15
+
16
+ Success(true)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,42 @@
1
+ module Guesty
2
+ module Reservations
3
+ module Stays
4
+ class Update
5
+ include Guesty::Operation
6
+
7
+ # @rbs (reservation_id: ::String, stay: ::Hash[::Symbol, untyped]) -> Dry::Monads::Result[bool]
8
+ def call(reservation_id:, stay:)
9
+ response = Guesty.do_request(
10
+ :put,
11
+ "reservations/#{reservation_id}",
12
+ stay_attributes(stay)
13
+ )
14
+
15
+ raise response.failure if response.failure?
16
+
17
+ Success(true)
18
+ end
19
+
20
+ private
21
+
22
+ # @rbs (::Hash[::Symbol, untyped] stay) -> ::Hash[::Symbol, untyped]
23
+ def stay_attributes(stay)
24
+ {
25
+ checkInDateLocalized: stay.fetch(:start_date).iso8601,
26
+ checkOutDateLocalized: stay.fetch(:end_date).iso8601,
27
+ plannedArrival: stay.fetch(:check_in).strftime('%H:%M'),
28
+ plannedDeparture: stay.fetch(:check_out).strftime('%H:%M'),
29
+ guestsCount: stay.fetch(:num_guests),
30
+ numberOfGuests: {
31
+ numberOfAdults: stay.fetch(:adults),
32
+ numberOfChildren: stay.fetch(:children)
33
+ },
34
+ ignoreCalendar: stay.fetch(:ignore_calendar),
35
+ ignoreTerms: true,
36
+ listingId: stay.fetch(:listing_external_id)
37
+ }
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,19 @@
1
+ module Guesty
2
+ module Reservations
3
+ class Update
4
+ include Guesty::Operation
5
+
6
+ # @rbs (reservation_id: ::String, attributes: ::Hash[::Symbol, untyped]) -> Dry::Monads::Result[bool]
7
+ def call(reservation_id:, attributes:)
8
+ argument! reservation_id: :required if reservation_id.blank?
9
+ argument! attributes: :required if attributes.blank?
10
+
11
+ response = Guesty.do_request :put, "reservations/#{reservation_id}", attributes
12
+
13
+ raise response.failure unless response.success?
14
+
15
+ Success(true)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ module Guesty
2
+ module Reservations
3
+ CANCELLED_STATUS = 'canceled'.freeze #: ::String
4
+ CLOSED_STATUSES = %w[canceled closed declined expired].freeze #: ::Array[::String]
5
+
6
+ # @rbs (untyped conversation) -> ::Array[::Hash[::Symbol, untyped]]
7
+ def self.from_conversation(conversation)
8
+ (conversation.dig(:meta, :reservations) || []).filter_map do |reservation|
9
+ { id: reservation[:_id], closed: CLOSED_STATUSES.include?(reservation[:status]) } if reservation[:_id]
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ module Guesty
2
+ module Reviews
3
+ class Respond
4
+ include Guesty::Operation
5
+
6
+ # @rbs (review_id: ::String, text: ::String) -> Dry::Monads::Result[bool]
7
+ def call(review_id:, text:)
8
+ argument! review_id: :required if review_id.blank?
9
+ argument! text: :required if text.blank?
10
+
11
+ response = Guesty.do_request(:put, "reviews/#{review_id}/reply", { reviewReply: text })
12
+
13
+ raise response.failure unless response.success?
14
+
15
+ Success(true)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,3 @@
1
+ module Guesty
2
+ VERSION = '0.1.0'.freeze
3
+ end
@@ -0,0 +1,19 @@
1
+ module Guesty
2
+ module Views
3
+ class Create
4
+ include Guesty::Operation
5
+
6
+ # @rbs (title: ::String, section: ::String) -> Dry::Monads::Result[::Hash[::Symbol, untyped]]
7
+ def call(title:, section:)
8
+ argument! title: :required if title.blank?
9
+ argument! section: :required if section.blank?
10
+
11
+ response = Guesty.do_request :post, 'views', { title:, section: }
12
+
13
+ raise response.failure unless response.success?
14
+
15
+ Success(response.value!.body)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,33 @@
1
+ module Guesty
2
+ module Views
3
+ class Update
4
+ include Guesty::Operation
5
+
6
+ # @rbs (id: ::String, ?title: ::String?, ?fields: ::String?, ?filters: ::Array[::Hash[::Symbol, untyped]]?, ?sort: ::String?) -> Dry::Monads::Result[untyped]
7
+ def call(id:, title: nil, fields: nil, filters: nil, sort: nil)
8
+ argument! id: :required if id.blank?
9
+ argument! attributes: :invalid if [title, fields, filters, sort].all?(&:nil?)
10
+
11
+ response = Guesty.do_request :put,
12
+ "views/#{id}",
13
+ payload(
14
+ id,
15
+ title:,
16
+ fields:,
17
+ filters:,
18
+ sort:
19
+ )
20
+
21
+ raise response.failure unless response.success?
22
+
23
+ Success(response.value!.body)
24
+ end
25
+
26
+ private
27
+
28
+ def payload(id, title:, fields:, filters:, sort:)
29
+ { _id: id, title:, fields:, filters:, sort: }.compact
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,21 @@
1
+ module Guesty
2
+ module Webhooks
3
+ class Create
4
+ include Guesty::Operation
5
+
6
+ # @rbs (url: ::String, events: ::Array[::String]) -> Dry::Monads::Result[::Hash[::Symbol, untyped]]
7
+ def call(url:, events:)
8
+ argument! url: :required if url.blank?
9
+ argument! events: :required if events.blank?
10
+
11
+ response = Guesty.do_request :post, 'webhooks', { url:, events: }
12
+
13
+ if response.success?
14
+ Success(response.value!.body)
15
+ else
16
+ response
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,18 @@
1
+ module Guesty
2
+ module Webhooks
3
+ class Index
4
+ include Guesty::Operation
5
+
6
+ # @rbs () -> Dry::Monads::Result[::Array[untyped]]
7
+ def call
8
+ response = Guesty.do_request :get, 'webhooks'
9
+
10
+ if response.success?
11
+ Success(response.value!.body)
12
+ else
13
+ response
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,76 @@
1
+ require 'base64'
2
+ require 'openssl'
3
+
4
+ module Guesty
5
+ module Webhooks
6
+ # Guesty delivers webhooks through Svix, which signs every request. The secret is the
7
+ # base64 after the optional whsec_ prefix of the account signing key, the signed content is
8
+ # "<svix-id>.<svix-timestamp>.<raw body>", and svix-signature lists space-separated
9
+ # "version,base64-HMAC-SHA256" entries, one per active key.
10
+ module Signatures
11
+ class Verify
12
+ include Guesty::Operation
13
+
14
+ SECRET_PREFIX = 'whsec_'.freeze
15
+ SIGNATURE_VERSION = 'v1'.freeze
16
+ TOLERANCE = 5.minutes.freeze #: ActiveSupport::Duration
17
+
18
+ # @rbs (payload: ::String, headers: untyped) -> Dry::Monads::Result[bool]
19
+ def call(payload:, headers:)
20
+ argument! payload: :required if payload.nil?
21
+ argument! headers: :required if headers.nil?
22
+
23
+ id = headers['svix-id']
24
+ timestamp = headers['svix-timestamp']
25
+ signatures = headers['svix-signature']
26
+
27
+ error! 'Missing Svix headers' if id.blank? || timestamp.blank? || signatures.blank?
28
+
29
+ verify_timestamp!(timestamp)
30
+ error! 'No matching Svix signature' unless signed?(signatures, sign(id, timestamp, payload))
31
+
32
+ Success(true)
33
+ end
34
+
35
+ private
36
+
37
+ # A timestamp outside the tolerance fails even with a valid signature, so a captured
38
+ # delivery cannot be replayed later.
39
+ # @rbs (untyped header) -> void
40
+ def verify_timestamp!(header)
41
+ timestamp = Integer(header, exception: false)
42
+ error! 'Invalid Svix timestamp' if timestamp.nil?
43
+ error! 'Svix timestamp is outside the tolerance' unless timestamp.between?(TOLERANCE.ago.to_i, TOLERANCE.from_now.to_i)
44
+ end
45
+
46
+ # @rbs (::String id, ::String timestamp, ::String payload) -> ::String
47
+ def sign(id, timestamp, payload)
48
+ Base64.strict_encode64(
49
+ OpenSSL::HMAC.digest(
50
+ 'sha256',
51
+ secret,
52
+ "#{id}.#{timestamp}.#{payload}"
53
+ )
54
+ )
55
+ end
56
+
57
+ # @rbs (::String header, ::String expected) -> bool
58
+ def signed?(header, expected)
59
+ header.split.any? do |versioned_signature|
60
+ version, signature = versioned_signature.split(',', 2)
61
+
62
+ version == SIGNATURE_VERSION && signature && ActiveSupport::SecurityUtils.secure_compare(signature, expected)
63
+ end
64
+ end
65
+
66
+ # @rbs () -> ::String
67
+ def secret
68
+ decoded = Base64.decode64(Guesty.webhook_key.to_s.delete_prefix(SECRET_PREFIX))
69
+ error! 'Guesty webhook signing key is not configured' if decoded.empty?
70
+
71
+ decoded
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,36 @@
1
+ module Guesty
2
+ module Webhooks
3
+ # Subscribes the urls to the events: creates the missing, updates the
4
+ # drifted, leaves the rest. Returns the urls grouped by :created, :updated,
5
+ # :unchanged.
6
+ class Sync
7
+ include Guesty::Operation
8
+
9
+ # @rbs (urls: ::Array[::String], events: ::Array[::String]) -> Dry::Monads::Result[::Hash[::Symbol, ::Array[::String]]]
10
+ def call(urls:, events:)
11
+ argument! urls: :required if urls.blank?
12
+ argument! events: :required if events.blank?
13
+
14
+ webhooks = Index.new.call!.value!
15
+ existing = webhooks.index_by { |webhook| webhook[:url].strip }
16
+
17
+ Success(urls.group_by { |url| reconcile(url, events, existing[url]) })
18
+ end
19
+
20
+ private
21
+
22
+ # @rbs (::String url, ::Array[::String] events, ::Hash[::Symbol, untyped]? current) -> ::Symbol
23
+ def reconcile(url, events, current)
24
+ if current.nil?
25
+ Create.new.call!(url:, events:)
26
+ :created
27
+ elsif current[:events].to_set != events.to_set
28
+ Update.new.call!(id: current[:_id], url:, events:)
29
+ :updated
30
+ else
31
+ :unchanged
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,22 @@
1
+ module Guesty
2
+ module Webhooks
3
+ class Update
4
+ include Guesty::Operation
5
+
6
+ # @rbs (id: ::String, url: ::String, events: ::Array[::String]) -> Dry::Monads::Result[::Hash[::Symbol, untyped]]
7
+ def call(id:, url:, events:)
8
+ argument! id: :required if id.blank?
9
+ argument! url: :required if url.blank?
10
+ argument! events: :required if events.blank?
11
+
12
+ response = Guesty.do_request :put, "webhooks/#{id}", { url:, events: }
13
+
14
+ if response.success?
15
+ Success(response.value!.body)
16
+ else
17
+ response
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1 @@
1
+ require_relative 'guesty'
data/lib/guesty.rb ADDED
@@ -0,0 +1,78 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext'
3
+ require 'active_support/security_utils'
4
+ require 'dry/monads'
5
+ require 'faraday'
6
+ require 'faraday/retry'
7
+ require 'mini_mime'
8
+ require 'oj'
9
+
10
+ require_relative 'guesty/version'
11
+ require_relative 'guesty/error'
12
+ require_relative 'guesty/memory_token_store'
13
+ require_relative 'guesty/memory_rate_limiter'
14
+ require_relative 'guesty/config'
15
+ require_relative 'guesty/operation'
16
+ require_relative 'guesty/rate_limiter_middleware'
17
+ require_relative 'guesty/api_error'
18
+ require_relative 'guesty/client'
19
+ require_relative 'guesty/access_tokens/upsert'
20
+ require_relative 'guesty/conversations'
21
+ require_relative 'guesty/conversations/attachments/index'
22
+ require_relative 'guesty/conversations/index'
23
+ require_relative 'guesty/conversations/messages/reply'
24
+ require_relative 'guesty/conversations/posts/index'
25
+ require_relative 'guesty/conversations/posts/since'
26
+ require_relative 'guesty/conversations/search'
27
+ require_relative 'guesty/conversations/show'
28
+ require_relative 'guesty/guest_folio/invoice_items/index'
29
+ require_relative 'guesty/guests'
30
+ require_relative 'guesty/guests/profiles/create'
31
+ require_relative 'guesty/guests/profiles/show'
32
+ require_relative 'guesty/guests/profiles/update'
33
+ require_relative 'guesty/homes/calendars/show'
34
+ require_relative 'guesty/homes/search'
35
+ require_relative 'guesty/reservations'
36
+ require_relative 'guesty/reservations/accommodation_fare/update'
37
+ require_relative 'guesty/reservations/approve'
38
+ require_relative 'guesty/reservations/create'
39
+ require_relative 'guesty/reservations/custom_fields/update'
40
+ require_relative 'guesty/reservations/dates/update'
41
+ require_relative 'guesty/reservations/decline'
42
+ require_relative 'guesty/reservations/flags/update'
43
+ require_relative 'guesty/reservations/payments/create'
44
+ require_relative 'guesty/reservations/pre_approve'
45
+ require_relative 'guesty/reservations/recover'
46
+ require_relative 'guesty/reservations/reviews/extractors/base'
47
+ require_relative 'guesty/reservations/reviews/extractors/airbnb'
48
+ require_relative 'guesty/reservations/reviews/extractors/booking_com'
49
+ require_relative 'guesty/reservations/reviews/extractors/vrbo'
50
+ require_relative 'guesty/reservations/reviews/index'
51
+ require_relative 'guesty/reservations/search'
52
+ require_relative 'guesty/reservations/show'
53
+ require_relative 'guesty/reservations/status/cancel'
54
+ require_relative 'guesty/reservations/status/update'
55
+ require_relative 'guesty/reservations/stays/update'
56
+ require_relative 'guesty/reservations/update'
57
+ require_relative 'guesty/reviews/respond'
58
+ require_relative 'guesty/views/create'
59
+ require_relative 'guesty/views/update'
60
+ require_relative 'guesty/webhooks/create'
61
+ require_relative 'guesty/webhooks/index'
62
+ require_relative 'guesty/webhooks/signatures/verify'
63
+ require_relative 'guesty/webhooks/sync'
64
+ require_relative 'guesty/webhooks/update'
65
+
66
+ module Guesty
67
+ class << self
68
+ # @rbs () { (Config) -> void } -> void
69
+ def configure
70
+ yield(config)
71
+ end
72
+
73
+ # @rbs () -> Config
74
+ def config
75
+ @config ||= Config.new
76
+ end
77
+ end
78
+ end