duffel_api 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/.DS_Store +0 -0
- data/.gitignore +1 -0
- data/Appraisals +11 -0
- data/CHANGELOG.md +6 -0
- data/Gemfile +3 -2
- data/README.md +34 -1
- data/duffel_api.gemspec +6 -4
- data/examples/book_with_extra_baggage.rb +83 -0
- data/examples/book_with_seat.rb +1 -2
- data/lib/duffel_api/api_response.rb +35 -5
- data/lib/duffel_api/api_service.rb +18 -4
- data/lib/duffel_api/client.rb +24 -1
- data/lib/duffel_api/errors/error.rb +44 -1
- data/lib/duffel_api/list_response.rb +17 -0
- data/lib/duffel_api/middlewares/raise_duffel_errors.rb +18 -2
- data/lib/duffel_api/paginator.rb +11 -3
- data/lib/duffel_api/request.rb +32 -16
- data/lib/duffel_api/resources/aircraft.rb +7 -6
- data/lib/duffel_api/resources/airline.rb +7 -6
- data/lib/duffel_api/resources/airport.rb +21 -6
- data/lib/duffel_api/resources/base_resource.rb +3 -0
- data/lib/duffel_api/resources/offer_passenger.rb +11 -0
- data/lib/duffel_api/resources/offer_request.rb +15 -6
- data/lib/duffel_api/response.rb +24 -5
- data/lib/duffel_api/services/aircraft_service.rb +18 -0
- data/lib/duffel_api/services/airlines_service.rb +17 -0
- data/lib/duffel_api/services/airports_service.rb +18 -0
- data/lib/duffel_api/services/base_service.rb +17 -4
- data/lib/duffel_api/services/offer_passengers_service.rb +7 -0
- data/lib/duffel_api/services/offer_requests_service.rb +24 -0
- data/lib/duffel_api/services/offers_service.rb +18 -0
- data/lib/duffel_api/services/order_cancellations_service.rb +28 -0
- data/lib/duffel_api/services/order_change_offers_service.rb +18 -0
- data/lib/duffel_api/services/order_change_requests_service.rb +11 -0
- data/lib/duffel_api/services/order_changes_service.rb +17 -0
- data/lib/duffel_api/services/orders_service.rb +28 -0
- data/lib/duffel_api/services/payment_intents_service.rb +15 -0
- data/lib/duffel_api/services/payments_service.rb +5 -0
- data/lib/duffel_api/services/refunds_service.rb +10 -0
- data/lib/duffel_api/services/seat_maps_service.rb +6 -0
- data/lib/duffel_api/services/webhooks_service.rb +23 -2
- data/lib/duffel_api/version.rb +1 -1
- data/lib/duffel_api/webhook_event.rb +119 -0
- data/lib/duffel_api.rb +1 -0
- metadata +36 -6
- data/.circleci/config.yml +0 -82
- data/.github/dependabot.yml +0 -6
@@ -3,6 +3,12 @@
|
|
3
3
|
module DuffelAPI
|
4
4
|
module Services
|
5
5
|
class OrderChangeOffersService < BaseService
|
6
|
+
# Lists order change offers, returning a single page of results.
|
7
|
+
#
|
8
|
+
# @option [Hash] :params Parameters to include in the HTTP querystring, including
|
9
|
+
# any filters
|
10
|
+
# @return [ListResponse]
|
11
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
6
12
|
def list(options = {})
|
7
13
|
path = "/air/order_change_offers"
|
8
14
|
|
@@ -15,6 +21,13 @@ module DuffelAPI
|
|
15
21
|
)
|
16
22
|
end
|
17
23
|
|
24
|
+
# Returns an `Enumerator` which can automatically cycle through multiple
|
25
|
+
# pages of `Resources;:OrderChangeOffer`s
|
26
|
+
#
|
27
|
+
# @param options [Hash] options passed to `#list`, for example `:params` to
|
28
|
+
# send an HTTP querystring with filters
|
29
|
+
# @return [Enumerator]
|
30
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
18
31
|
def all(options = {})
|
19
32
|
Paginator.new(
|
20
33
|
service: self,
|
@@ -22,6 +35,11 @@ module DuffelAPI
|
|
22
35
|
).enumerator
|
23
36
|
end
|
24
37
|
|
38
|
+
# Retrieves a single order change offer by ID
|
39
|
+
#
|
40
|
+
# @param id [String]
|
41
|
+
# @return [Resources::OrderChangeOffer]
|
42
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
25
43
|
def get(id, options = {})
|
26
44
|
path = substitute_url_pattern("/air/order_change_offers/:id", "id" => id)
|
27
45
|
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module DuffelAPI
|
4
4
|
module Services
|
5
5
|
class OrderChangeRequestsService < BaseService
|
6
|
+
# Creates an order change request
|
7
|
+
#
|
8
|
+
# @option [required, Hash] :params the payload for creating the order change
|
9
|
+
# request
|
10
|
+
# @return [Resources::OrderChangeRequest]
|
11
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
6
12
|
def create(options = {})
|
7
13
|
path = "/air/order_change_requests"
|
8
14
|
|
@@ -23,6 +29,11 @@ module DuffelAPI
|
|
23
29
|
Resources::OrderChangeRequest.new(unenvelope_body(response.parsed_body), response)
|
24
30
|
end
|
25
31
|
|
32
|
+
# Retrieves a single order change request by ID
|
33
|
+
#
|
34
|
+
# @param id [String]
|
35
|
+
# @return [Resources::OrderChangeRequest]
|
36
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
26
37
|
def get(id, options = {})
|
27
38
|
path = substitute_url_pattern("/air/order_change_requests/:id", "id" => id)
|
28
39
|
|
@@ -3,6 +3,11 @@
|
|
3
3
|
module DuffelAPI
|
4
4
|
module Services
|
5
5
|
class OrderChangesService < BaseService
|
6
|
+
# Creates an order chnage
|
7
|
+
#
|
8
|
+
# @option [required, Hash] :params the payload for creating the order change
|
9
|
+
# @return [Resources::OrderChange]
|
10
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
6
11
|
def create(options = {})
|
7
12
|
path = "/air/order_changes"
|
8
13
|
|
@@ -22,6 +27,13 @@ module DuffelAPI
|
|
22
27
|
Resources::OrderChange.new(unenvelope_body(response.parsed_body), response)
|
23
28
|
end
|
24
29
|
|
30
|
+
# Confirms an order change by ID, passing across extra data required for
|
31
|
+
# confirmation
|
32
|
+
#
|
33
|
+
# @param id [String]
|
34
|
+
# @option [required, Hash] :params
|
35
|
+
# @return [Resources::OrderChange] the payload for confirming the order change
|
36
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
25
37
|
def confirm(id, options = {})
|
26
38
|
path = substitute_url_pattern("/air/order_changes/:id/actions/confirm",
|
27
39
|
"id" => id)
|
@@ -42,6 +54,11 @@ module DuffelAPI
|
|
42
54
|
Resources::OrderChange.new(unenvelope_body(response.parsed_body), response)
|
43
55
|
end
|
44
56
|
|
57
|
+
# Retrieves a single order change by ID
|
58
|
+
#
|
59
|
+
# @param id [String]
|
60
|
+
# @return [Resources::OrderChange]
|
61
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
45
62
|
def get(id, options = {})
|
46
63
|
path = substitute_url_pattern("/air/order_changes/:id", "id" => id)
|
47
64
|
|
@@ -3,6 +3,11 @@
|
|
3
3
|
module DuffelAPI
|
4
4
|
module Services
|
5
5
|
class OrdersService < BaseService
|
6
|
+
# Creates an order
|
7
|
+
#
|
8
|
+
# @option [required, Hash] :params the payload for creating the order
|
9
|
+
# @return [Resources::Order]
|
10
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
6
11
|
def create(options = {})
|
7
12
|
path = "/air/orders"
|
8
13
|
|
@@ -22,6 +27,11 @@ module DuffelAPI
|
|
22
27
|
Resources::Order.new(unenvelope_body(response.parsed_body), response)
|
23
28
|
end
|
24
29
|
|
30
|
+
# Updates an order
|
31
|
+
#
|
32
|
+
# @option [required, Hash] :params the payload for updating the order
|
33
|
+
# @return [Resources::Order]
|
34
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
25
35
|
def update(id, options = {})
|
26
36
|
path = substitute_url_pattern("/air/orders/:id", "id" => id)
|
27
37
|
|
@@ -41,6 +51,12 @@ module DuffelAPI
|
|
41
51
|
Resources::Order.new(unenvelope_body(response.parsed_body), response)
|
42
52
|
end
|
43
53
|
|
54
|
+
# Lists orders, returning a single page of results.
|
55
|
+
#
|
56
|
+
# @option [Hash] :params Parameters to include in the HTTP querystring, including
|
57
|
+
# any filters
|
58
|
+
# @return [ListResponse]
|
59
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
44
60
|
def list(options = {})
|
45
61
|
path = "/air/orders"
|
46
62
|
|
@@ -53,6 +69,13 @@ module DuffelAPI
|
|
53
69
|
)
|
54
70
|
end
|
55
71
|
|
72
|
+
# Returns an `Enumerator` which can automatically cycle through multiple
|
73
|
+
# pages of `Resources;:Order`s
|
74
|
+
#
|
75
|
+
# @param options [Hash] options passed to `#list`, for example `:params` to
|
76
|
+
# send an HTTP querystring with filters
|
77
|
+
# @return [Enumerator]
|
78
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
56
79
|
def all(options = {})
|
57
80
|
Paginator.new(
|
58
81
|
service: self,
|
@@ -60,6 +83,11 @@ module DuffelAPI
|
|
60
83
|
).enumerator
|
61
84
|
end
|
62
85
|
|
86
|
+
# Retrieves a single order by ID
|
87
|
+
#
|
88
|
+
# @param id [String]
|
89
|
+
# @return [Resources::Order]
|
90
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
63
91
|
def get(id, options = {})
|
64
92
|
path = substitute_url_pattern("/air/orders/:id", "id" => id)
|
65
93
|
|
@@ -3,6 +3,11 @@
|
|
3
3
|
module DuffelAPI
|
4
4
|
module Services
|
5
5
|
class PaymentIntentsService < BaseService
|
6
|
+
# Creates an payment intent
|
7
|
+
#
|
8
|
+
# @option [required, Hash] :params the payload for creating the payment intent
|
9
|
+
# @return [Resources::PaymentIntent]
|
10
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
6
11
|
def create(options = {})
|
7
12
|
path = "/payments/payment_intents"
|
8
13
|
|
@@ -22,6 +27,11 @@ module DuffelAPI
|
|
22
27
|
Resources::PaymentIntent.new(unenvelope_body(response.parsed_body), response)
|
23
28
|
end
|
24
29
|
|
30
|
+
# Confirms a payment intent by ID
|
31
|
+
#
|
32
|
+
# @param id [String]
|
33
|
+
# @return [Resources::PaymentIntent]
|
34
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
25
35
|
def confirm(id, options = {})
|
26
36
|
path = substitute_url_pattern("/payments/payment_intents/:id/actions/confirm",
|
27
37
|
"id" => id)
|
@@ -42,6 +52,11 @@ module DuffelAPI
|
|
42
52
|
Resources::PaymentIntent.new(unenvelope_body(response.parsed_body), response)
|
43
53
|
end
|
44
54
|
|
55
|
+
# Retrieves a single payment intent by ID
|
56
|
+
#
|
57
|
+
# @param id [String]
|
58
|
+
# @return [Resources::PaymentIntent]
|
59
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
45
60
|
def get(id, options = {})
|
46
61
|
path = substitute_url_pattern("/payments/payment_intents/:id", "id" => id)
|
47
62
|
|
@@ -3,6 +3,11 @@
|
|
3
3
|
module DuffelAPI
|
4
4
|
module Services
|
5
5
|
class PaymentsService < BaseService
|
6
|
+
# Creates an payment
|
7
|
+
#
|
8
|
+
# @option [required, Hash] :params the payload for creating the payment
|
9
|
+
# @return [Resources::Payment]
|
10
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
6
11
|
def create(options = {})
|
7
12
|
path = "/air/payments"
|
8
13
|
|
@@ -3,6 +3,11 @@
|
|
3
3
|
module DuffelAPI
|
4
4
|
module Services
|
5
5
|
class RefundsService < BaseService
|
6
|
+
# Creates a refund
|
7
|
+
#
|
8
|
+
# @option [required, Hash] :params the payload for creating the refund
|
9
|
+
# @return [Resources::Refund]
|
10
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
6
11
|
def create(options = {})
|
7
12
|
path = "/payments/refunds"
|
8
13
|
|
@@ -22,6 +27,11 @@ module DuffelAPI
|
|
22
27
|
Resources::Refund.new(unenvelope_body(response.parsed_body), response)
|
23
28
|
end
|
24
29
|
|
30
|
+
# Retrieves a single refund by ID
|
31
|
+
#
|
32
|
+
# @param id [String]
|
33
|
+
# @return [Resources::Refund]
|
34
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
25
35
|
def get(id, options = {})
|
26
36
|
path = substitute_url_pattern("/payments/refunds/:id", "id" => id)
|
27
37
|
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module DuffelAPI
|
4
4
|
module Services
|
5
5
|
class SeatMapsService < BaseService
|
6
|
+
# Lists all seat maps for an offer. This data is __not__ paginated.
|
7
|
+
#
|
8
|
+
# @option [Hash] :params Parameters to include in the HTTP querystring, including
|
9
|
+
# any filters
|
10
|
+
# @return [ListResponse]
|
11
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
6
12
|
def list(options = {})
|
7
13
|
path = "/air/seat_maps"
|
8
14
|
|
@@ -4,19 +4,29 @@ module DuffelAPI
|
|
4
4
|
module Services
|
5
5
|
class WebhooksService < BaseService
|
6
6
|
class PingResult
|
7
|
+
# Returns the raw API response this resource originated from
|
8
|
+
#
|
9
|
+
# @return [APIResponse]
|
7
10
|
attr_reader :api_response
|
8
11
|
|
9
12
|
def initialize(api_response)
|
10
13
|
@api_response = api_response
|
11
14
|
end
|
12
15
|
|
13
|
-
#
|
14
|
-
#
|
16
|
+
# Returns whether the ping was successful. This is always true, because if the
|
17
|
+
# ping fails, we raise an error.
|
18
|
+
#
|
19
|
+
# @return [Boolean]
|
15
20
|
def succeeded
|
16
21
|
true
|
17
22
|
end
|
18
23
|
end
|
19
24
|
|
25
|
+
# Creates an webhook
|
26
|
+
#
|
27
|
+
# @option [required, Hash] :params the payload for creating the webhook
|
28
|
+
# @return [Resources::Webhook]
|
29
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
20
30
|
def create(options = {})
|
21
31
|
path = "/air/webhooks"
|
22
32
|
|
@@ -36,6 +46,12 @@ module DuffelAPI
|
|
36
46
|
Resources::Webhook.new(unenvelope_body(response.parsed_body), response)
|
37
47
|
end
|
38
48
|
|
49
|
+
# Updates a webhook by ID
|
50
|
+
#
|
51
|
+
# @param id [String]
|
52
|
+
# @option [required, Hash] :params the payload for updating the webhook
|
53
|
+
# @return [Resources::Webhook]
|
54
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
39
55
|
def update(id, options = {})
|
40
56
|
path = substitute_url_pattern("/air/webhooks/:id", "id" => id)
|
41
57
|
|
@@ -55,6 +71,11 @@ module DuffelAPI
|
|
55
71
|
Resources::Webhook.new(unenvelope_body(response.parsed_body), response)
|
56
72
|
end
|
57
73
|
|
74
|
+
# Pings a webhook by ID
|
75
|
+
#
|
76
|
+
# @param id [String]
|
77
|
+
# @return [PingResult]
|
78
|
+
# @raise [Errors::Error] when the Duffel API returns an error
|
58
79
|
def ping(id, options = {})
|
59
80
|
path = substitute_url_pattern("/air/webhooks/:id/actions/ping", "id" => id)
|
60
81
|
|
data/lib/duffel_api/version.rb
CHANGED
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "base16"
|
4
|
+
require "openssl"
|
5
|
+
|
6
|
+
module DuffelAPI
|
7
|
+
module WebhookEvent
|
8
|
+
# An exception raised internally within the library - but not exposed - if the
|
9
|
+
# webhook signature provided does not match the format of a valid signature
|
10
|
+
class InvalidRequestSignatureError < StandardError; end
|
11
|
+
|
12
|
+
SIGNATURE_REGEXP = /\At=(.+),v1=(.+)\z/.freeze
|
13
|
+
|
14
|
+
SHA_256 = OpenSSL::Digest.new("sha256")
|
15
|
+
|
16
|
+
class << self
|
17
|
+
# Checks if a webhook event you received was a genuine webhook event from Duffel by
|
18
|
+
# checking that it was signed with your shared secret.
|
19
|
+
#
|
20
|
+
# Assuming that you've kept that secret secure and only shared it with Duffel,
|
21
|
+
# this can give you confidence that a webhook event was genuinely sent by Duffel.
|
22
|
+
#
|
23
|
+
# @param request_body [String] The raw body of the received request
|
24
|
+
# @param request_signature [String] The signature provided with the received
|
25
|
+
# request, found in the `X-Duffel-Signature` request header
|
26
|
+
# @param webhook_secret [String] The secret of the webhook, registered with Duffel
|
27
|
+
# @return [Boolean] whether the webhook signature matches
|
28
|
+
def genuine?(request_body:, request_signature:, webhook_secret:)
|
29
|
+
parsed_signature = parse_signature!(request_signature)
|
30
|
+
|
31
|
+
calculated_hmac = calculate_hmac(
|
32
|
+
payload: request_body,
|
33
|
+
secret: webhook_secret,
|
34
|
+
timestamp: parsed_signature[:timestamp],
|
35
|
+
)
|
36
|
+
|
37
|
+
secure_compare(calculated_hmac, parsed_signature[:v1])
|
38
|
+
rescue InvalidRequestSignatureError
|
39
|
+
# If the signature doesn't even look like a valid one, then the webhook
|
40
|
+
# event can't be genuine
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
# Calculates the signature for a request body in the same way that the Duffel API
|
47
|
+
# does it
|
48
|
+
#
|
49
|
+
# @param secret [String]
|
50
|
+
# @param payload [String]
|
51
|
+
# @param timestamp [String]
|
52
|
+
# @return [String]
|
53
|
+
def calculate_hmac(secret:, payload:, timestamp:)
|
54
|
+
signed_payload = %(#{timestamp}.#{payload})
|
55
|
+
Base16.encode16(OpenSSL::HMAC.digest(SHA_256, secret,
|
56
|
+
signed_payload)).strip.downcase
|
57
|
+
end
|
58
|
+
|
59
|
+
# Parses a webhook signature and extracts the `v1` and `timestamp` values, if
|
60
|
+
# available.
|
61
|
+
#
|
62
|
+
# @param signature [String] A webhook event signature received in a request
|
63
|
+
# @return [Hash]
|
64
|
+
# @raise InvalidRequestSignatureError when the signature isn't valid
|
65
|
+
def parse_signature!(signature)
|
66
|
+
matches = signature.match(SIGNATURE_REGEXP)
|
67
|
+
|
68
|
+
if matches
|
69
|
+
{
|
70
|
+
v1: matches[2],
|
71
|
+
timestamp: matches[1],
|
72
|
+
}
|
73
|
+
else
|
74
|
+
raise InvalidRequestSignatureError
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Taken from `Rack::Utils`
|
79
|
+
# (<https://github.com/rack/rack/blob/03b4b9708f375db46ee214b219f709d08ed6eeb0/lib/rack/utils.rb#L371-L393>).
|
80
|
+
#
|
81
|
+
# Licensed under the MIT License
|
82
|
+
# (<https://github.com/rack/rack/blob/master/MIT-LICENSE>).
|
83
|
+
if defined?(OpenSSL.fixed_length_secure_compare)
|
84
|
+
# Checks if two strings are equal, performing a constant time string comparison
|
85
|
+
# resistant to timing attacks.
|
86
|
+
#
|
87
|
+
# @param a [String]
|
88
|
+
# @param b [String]
|
89
|
+
# @return [Boolean] whether the two strings are equal
|
90
|
+
# rubocop:disable Naming/MethodParameterName
|
91
|
+
def secure_compare(a, b)
|
92
|
+
# rubocop:enable Naming/MethodParameterName
|
93
|
+
return false unless a.bytesize == b.bytesize
|
94
|
+
|
95
|
+
OpenSSL.fixed_length_secure_compare(a, b)
|
96
|
+
end
|
97
|
+
else
|
98
|
+
# Checks if two strings are equal, performing a constant time string comparison
|
99
|
+
# resistant to timing attacks.
|
100
|
+
#
|
101
|
+
# @param [String] a
|
102
|
+
# @param [String] b
|
103
|
+
# @return [Boolean] whether the two strings are equal
|
104
|
+
# rubocop:disable Naming/MethodParameterName
|
105
|
+
def secure_compare(a, b)
|
106
|
+
# rubocop:enable Naming/MethodParameterName
|
107
|
+
return false unless a.bytesize == b.bytesize
|
108
|
+
|
109
|
+
l = a.unpack("C*")
|
110
|
+
|
111
|
+
r = 0
|
112
|
+
i = -1
|
113
|
+
b.each_byte { |v| r |= v ^ l[i += 1] }
|
114
|
+
r.zero?
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/duffel_api.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: duffel_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Duffel team
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: base16
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.2
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: faraday
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -19,7 +33,7 @@ dependencies:
|
|
19
33
|
version: 0.9.2
|
20
34
|
- - "<"
|
21
35
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
36
|
+
version: '3'
|
23
37
|
type: :runtime
|
24
38
|
prerelease: false
|
25
39
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +43,21 @@ dependencies:
|
|
29
43
|
version: 0.9.2
|
30
44
|
- - "<"
|
31
45
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
46
|
+
version: '3'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: appraisal
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.4'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '2.4'
|
33
61
|
description:
|
34
62
|
email:
|
35
63
|
- help@duffel.com
|
@@ -37,11 +65,11 @@ executables: []
|
|
37
65
|
extensions: []
|
38
66
|
extra_rdoc_files: []
|
39
67
|
files:
|
40
|
-
- ".
|
41
|
-
- ".github/dependabot.yml"
|
68
|
+
- ".DS_Store"
|
42
69
|
- ".gitignore"
|
43
70
|
- ".rspec"
|
44
71
|
- ".rubocop.yml"
|
72
|
+
- Appraisals
|
45
73
|
- CHANGELOG.md
|
46
74
|
- CODE_OF_CONDUCT.md
|
47
75
|
- Gemfile
|
@@ -52,6 +80,7 @@ files:
|
|
52
80
|
- bin/setup
|
53
81
|
- duffel_api.gemspec
|
54
82
|
- examples/book_and_change.rb
|
83
|
+
- examples/book_with_extra_baggage.rb
|
55
84
|
- examples/book_with_seat.rb
|
56
85
|
- examples/exploring_data.rb
|
57
86
|
- examples/hold_and_pay_later.rb
|
@@ -108,6 +137,7 @@ files:
|
|
108
137
|
- lib/duffel_api/services/seat_maps_service.rb
|
109
138
|
- lib/duffel_api/services/webhooks_service.rb
|
110
139
|
- lib/duffel_api/version.rb
|
140
|
+
- lib/duffel_api/webhook_event.rb
|
111
141
|
homepage: https://github.com/duffelhq/duffel-api-ruby
|
112
142
|
licenses:
|
113
143
|
- MIT
|
data/.circleci/config.yml
DELETED
@@ -1,82 +0,0 @@
|
|
1
|
-
version: 2.1
|
2
|
-
|
3
|
-
commands:
|
4
|
-
setup_ruby:
|
5
|
-
steps:
|
6
|
-
- run:
|
7
|
-
name: Install bundler gem
|
8
|
-
command: gem install bundler --version '~> 2.2'
|
9
|
-
- run:
|
10
|
-
name: Install Ruby dependencies
|
11
|
-
command: bundle check || bundle install
|
12
|
-
|
13
|
-
executors:
|
14
|
-
ruby:
|
15
|
-
parameters:
|
16
|
-
image:
|
17
|
-
default: "cimg/ruby:3.0"
|
18
|
-
type: string
|
19
|
-
docker:
|
20
|
-
- image: << parameters.image >>
|
21
|
-
resource_class: small
|
22
|
-
|
23
|
-
orbs:
|
24
|
-
ruby: circleci/ruby@1.2
|
25
|
-
|
26
|
-
jobs:
|
27
|
-
test:
|
28
|
-
parameters:
|
29
|
-
ruby-image:
|
30
|
-
type: string
|
31
|
-
executor:
|
32
|
-
name: ruby
|
33
|
-
image: << parameters.ruby-image >>
|
34
|
-
steps:
|
35
|
-
- checkout
|
36
|
-
- setup_ruby
|
37
|
-
- ruby/rubocop-check
|
38
|
-
- ruby/rspec-test
|
39
|
-
coverage:
|
40
|
-
executor: ruby
|
41
|
-
environment:
|
42
|
-
COVERAGE: true
|
43
|
-
steps:
|
44
|
-
- checkout
|
45
|
-
- setup_ruby
|
46
|
-
- run:
|
47
|
-
name: Run tests with Simplecov enabled
|
48
|
-
command: bundle exec rspec spec
|
49
|
-
- store_artifacts:
|
50
|
-
path: coverage
|
51
|
-
code_examples:
|
52
|
-
executor: ruby
|
53
|
-
steps:
|
54
|
-
- checkout
|
55
|
-
- setup_ruby
|
56
|
-
- run:
|
57
|
-
name: Run "search and book" example
|
58
|
-
command: bundle exec ruby examples/search_and_book.rb
|
59
|
-
- run:
|
60
|
-
name: Run "hold and pay later" example
|
61
|
-
command: bundle exec ruby examples/hold_and_pay_later.rb
|
62
|
-
- run:
|
63
|
-
name: Run "exploring data" example
|
64
|
-
command: bundle exec ruby examples/exploring_data.rb
|
65
|
-
- run:
|
66
|
-
name: Run "book with seat" example
|
67
|
-
command: bundle exec ruby examples/book_with_seat.rb
|
68
|
-
- run:
|
69
|
-
name: Run "book and change" example
|
70
|
-
command: bundle exec ruby examples/book_and_change.rb
|
71
|
-
workflows:
|
72
|
-
version: 2
|
73
|
-
build_and_test:
|
74
|
-
jobs:
|
75
|
-
- test:
|
76
|
-
matrix:
|
77
|
-
parameters:
|
78
|
-
ruby-image: ["cimg/ruby:2.6", "cimg/ruby:2.7", "cimg/ruby:3.0", "cimg/ruby:3.1"]
|
79
|
-
- coverage
|
80
|
-
- code_examples:
|
81
|
-
requires:
|
82
|
-
- test
|