setsuzoku 0.10.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.
- checksums.yaml +7 -0
- data/.gitattributes +2 -0
- data/.gitignore +13 -0
- data/.rspec +3 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +82 -0
- data/LICENSE.txt +21 -0
- data/README.md +93 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/lib/setsuzoku.rb +37 -0
- data/lib/setsuzoku/api_response.rb +11 -0
- data/lib/setsuzoku/api_strategy.rb +124 -0
- data/lib/setsuzoku/auth_strategy.rb +72 -0
- data/lib/setsuzoku/credential.rb +37 -0
- data/lib/setsuzoku/exception.rb +18 -0
- data/lib/setsuzoku/external_api_handler.rb +19 -0
- data/lib/setsuzoku/pluggable.rb +87 -0
- data/lib/setsuzoku/plugin.rb +128 -0
- data/lib/setsuzoku/rspec.rb +2 -0
- data/lib/setsuzoku/rspec/dynamic_spec_helper.rb +281 -0
- data/lib/setsuzoku/service.rb +70 -0
- data/lib/setsuzoku/service/web_service.rb +21 -0
- data/lib/setsuzoku/service/web_service/api_strategies/rest_api_request.rb +17 -0
- data/lib/setsuzoku/service/web_service/api_strategies/rest_strategy.rb +155 -0
- data/lib/setsuzoku/service/web_service/api_strategy.rb +169 -0
- data/lib/setsuzoku/service/web_service/auth_strategies/basic_auth_strategy.rb +50 -0
- data/lib/setsuzoku/service/web_service/auth_strategies/o_auth_strategy.rb +173 -0
- data/lib/setsuzoku/service/web_service/auth_strategy.rb +48 -0
- data/lib/setsuzoku/service/web_service/credentials/basic_auth_credential.rb +52 -0
- data/lib/setsuzoku/service/web_service/credentials/o_auth_credential.rb +83 -0
- data/lib/setsuzoku/service/web_service/service.rb +31 -0
- data/lib/setsuzoku/utilities.rb +7 -0
- data/lib/setsuzoku/version.rb +6 -0
- data/setsuzoku.gemspec +50 -0
- data/sorbet/config +2 -0
- data/sorbet/rbi/gems/activesupport.rbi +1125 -0
- data/sorbet/rbi/gems/addressable.rbi +199 -0
- data/sorbet/rbi/gems/concurrent-ruby.rbi +1586 -0
- data/sorbet/rbi/gems/crack.rbi +62 -0
- data/sorbet/rbi/gems/faraday.rbi +615 -0
- data/sorbet/rbi/gems/hashdiff.rbi +66 -0
- data/sorbet/rbi/gems/httparty.rbi +401 -0
- data/sorbet/rbi/gems/i18n.rbi +133 -0
- data/sorbet/rbi/gems/mime-types-data.rbi +17 -0
- data/sorbet/rbi/gems/mime-types.rbi +218 -0
- data/sorbet/rbi/gems/multi_xml.rbi +35 -0
- data/sorbet/rbi/gems/multipart-post.rbi +53 -0
- data/sorbet/rbi/gems/nokogiri.rbi +1011 -0
- data/sorbet/rbi/gems/public_suffix.rbi +104 -0
- data/sorbet/rbi/gems/rake.rbi +646 -0
- data/sorbet/rbi/gems/rspec-core.rbi +1893 -0
- data/sorbet/rbi/gems/rspec-expectations.rbi +1123 -0
- data/sorbet/rbi/gems/rspec-mocks.rbi +1090 -0
- data/sorbet/rbi/gems/rspec-support.rbi +280 -0
- data/sorbet/rbi/gems/rspec.rbi +15 -0
- data/sorbet/rbi/gems/safe_yaml.rbi +124 -0
- data/sorbet/rbi/gems/thread_safe.rbi +82 -0
- data/sorbet/rbi/gems/tzinfo.rbi +406 -0
- data/sorbet/rbi/gems/webmock.rbi +532 -0
- data/sorbet/rbi/hidden-definitions/hidden.rbi +13722 -0
- data/sorbet/rbi/sorbet-typed/lib/activesupport/all/activesupport.rbi +1431 -0
- data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +8684 -0
- data/sorbet/rbi/sorbet-typed/lib/httparty/all/httparty.rbi +427 -0
- data/sorbet/rbi/sorbet-typed/lib/minitest/all/minitest.rbi +108 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +111 -0
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +543 -0
- data/sorbet/rbi/todo.rbi +11 -0
- metadata +255 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Setsuzoku
|
5
|
+
module Service
|
6
|
+
module WebService
|
7
|
+
module AuthStrategies
|
8
|
+
# The API OAuth Authentication Interface definition.
|
9
|
+
# Any Plugin that implements this must implement all methods required for OAuth.
|
10
|
+
#
|
11
|
+
# Defines all necessary methods for handling authentication for any authentication strategy.
|
12
|
+
class OAuthStrategy < WebService::AuthStrategy
|
13
|
+
extend T::Sig
|
14
|
+
extend T::Helpers
|
15
|
+
|
16
|
+
def self.required_instance_methods
|
17
|
+
[]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.credential_class
|
21
|
+
Setsuzoku::Service::WebService::Credentials::OAuthCredential
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.token_valid_for
|
25
|
+
24.hours
|
26
|
+
end
|
27
|
+
|
28
|
+
# Any api request headers that this service needs to set.
|
29
|
+
#
|
30
|
+
# @return [Hash]
|
31
|
+
sig { override.returns(T::Hash[Symbol, T.untyped]) }
|
32
|
+
def auth_headers
|
33
|
+
{
|
34
|
+
headers: {
|
35
|
+
'Authorization': "Bearer #{self.credential.token}"
|
36
|
+
}
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get a new credential.
|
41
|
+
# Exchanges code for token, refresh_token and expires_on.
|
42
|
+
#
|
43
|
+
# @param args [Hash] the code from the initial auth response { code: 'abcdefg' }.
|
44
|
+
#
|
45
|
+
# @return void
|
46
|
+
sig { override.params(args: T.untyped).void }
|
47
|
+
def new_credential!(**args)
|
48
|
+
# get a token object based on the code retrieved from login
|
49
|
+
get_token!(params(grant_type: 'authorization_code',
|
50
|
+
code: args[:code]), :new_token)
|
51
|
+
end
|
52
|
+
|
53
|
+
# If the auth credentials are valid for this instance and auth_strategy.
|
54
|
+
#
|
55
|
+
# If the token is invalid we should refresh it. And verify that the credentials are now valid.
|
56
|
+
# Otherwise the credentials are already valid.
|
57
|
+
#
|
58
|
+
# @return [Boolean] true if the auth token is valid for the auth_strategy.
|
59
|
+
sig { override.returns(T::Boolean) }
|
60
|
+
def auth_credential_valid?
|
61
|
+
if token_is_invalid?
|
62
|
+
refresh_expired_token!
|
63
|
+
!token_is_invalid?
|
64
|
+
else
|
65
|
+
true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
# Determine whether the token is no longer valid.
|
72
|
+
#
|
73
|
+
# @return [Boolean] true if the token is invalid.
|
74
|
+
sig { returns(T::Boolean) }
|
75
|
+
def token_is_invalid?
|
76
|
+
active = self.credential.respond_to?(:"status") ? self.credential.status != 'disabled' : true
|
77
|
+
active && !self.credential.expires_on.blank? &&
|
78
|
+
!self.credential.refresh_token.blank? &&
|
79
|
+
(self.credential.expires_on < refresh_before_expiration_time)
|
80
|
+
end
|
81
|
+
|
82
|
+
sig { returns(DateTime) }
|
83
|
+
def refresh_before_expiration_time
|
84
|
+
45.minutes.from_now.to_datetime
|
85
|
+
end
|
86
|
+
|
87
|
+
# Exchange refresh_token for a new token and expires_on.
|
88
|
+
#
|
89
|
+
# @return [Boolean] true if the credential was refreshed successfully
|
90
|
+
sig { void }
|
91
|
+
def refresh_expired_token!
|
92
|
+
get_token!(params(grant_type: 'refresh_token',
|
93
|
+
refresh_token: self.credential.refresh_token), :refresh_token)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Exchange code for token, refresh_token and expires_on
|
97
|
+
#
|
98
|
+
# @return void
|
99
|
+
sig { params(code: String, redirect_url: String).void }
|
100
|
+
def custom_token!(code: nil, redirect_url: nil)
|
101
|
+
get_token!(params(grant_type: 'authorization_code',
|
102
|
+
code: code,
|
103
|
+
redirect_uri: redirect_url), :refresh_token)
|
104
|
+
end
|
105
|
+
|
106
|
+
# Exchange code for a new token via POST request to API token url,
|
107
|
+
# and set token, expiry, and status on the integration
|
108
|
+
#
|
109
|
+
# @param [Hash] body the request body for the token POST request
|
110
|
+
#
|
111
|
+
# @return void
|
112
|
+
sig { params(body: T::Hash[Symbol, String], action: Symbol).void }
|
113
|
+
def get_token!(body, action)
|
114
|
+
success = false
|
115
|
+
request = self.api_strategy.request_class.new(action: action, body: body)
|
116
|
+
|
117
|
+
resp = self.api_strategy.call_external_api(request: request, strategy: :auth)
|
118
|
+
|
119
|
+
if resp.data && resp.data[:access_token]
|
120
|
+
self.credential.status = 'active' if self.credential.respond_to?(:"status=")
|
121
|
+
self.credential.token = resp.data[:access_token]
|
122
|
+
self.credential.refresh_token = resp.data[:refresh_token] if resp.data.key?(:refresh_token)
|
123
|
+
self.credential.expires_on = if resp.data[:expires_in]
|
124
|
+
resp.data[:expires_in].to_i.seconds.from_now
|
125
|
+
# elsif resp.data[:issued_at] && self.class.token_valid_for
|
126
|
+
# Time.at(resp.data[:issued_at].to_i / 1000) + self.class.token_valid_for
|
127
|
+
end
|
128
|
+
|
129
|
+
self.plugin.set_credential_fields!(resp) if self.plugin.respond_to?(:set_credential_fields!)
|
130
|
+
|
131
|
+
#TODO: figure out a better way to do this when we add other integrations...
|
132
|
+
#
|
133
|
+
# if self.is_a?(FacebookIntegration)
|
134
|
+
# resp = self.exchange_for_long_lived_token
|
135
|
+
# if resp && resp.data['access_token']
|
136
|
+
# self.token = resp.data['access_token']
|
137
|
+
# self.refresh_token = resp.data['access_token']
|
138
|
+
# self.expires_on = 59.days.from_now
|
139
|
+
# end
|
140
|
+
# end
|
141
|
+
else
|
142
|
+
self.credential.status = 'error' if self.credential.respond_to?(:"status=")
|
143
|
+
end
|
144
|
+
|
145
|
+
if self.credential.respond_to?(:"save")
|
146
|
+
self.credential.save && resp.success
|
147
|
+
else
|
148
|
+
resp.success
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
# Add some default params to the params hash.
|
153
|
+
#
|
154
|
+
# @param params [Hash] the original params hash.
|
155
|
+
#
|
156
|
+
# @return [Hash] the merged params hash.
|
157
|
+
sig { params(params: T::Hash[T.untyped, T.untyped]).returns(T::Hash[T.untyped, T.untyped]) }
|
158
|
+
def params(params)
|
159
|
+
if params.key?(:redirect_uri)
|
160
|
+
params.merge(client_id: self.credential.client_id,
|
161
|
+
client_secret: self.credential.client_secret)
|
162
|
+
else
|
163
|
+
params.merge(client_id: self.credential.client_id,
|
164
|
+
client_secret: self.credential.client_secret,
|
165
|
+
redirect_uri: self.credential.redirect_url_override.nil? ? self.credential.redirect_url : self.credential.redirect_url_override)
|
166
|
+
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Setsuzoku
|
5
|
+
module Service
|
6
|
+
# The Token-based API Authentication Interface definition.
|
7
|
+
# Any Plugin that implements this must implement all methods defined here.
|
8
|
+
#
|
9
|
+
# Defines all necessary methods for handling authentication for any token-based authentication.
|
10
|
+
module WebService
|
11
|
+
|
12
|
+
class AuthStrategy
|
13
|
+
include Setsuzoku::AuthStrategy
|
14
|
+
extend T::Sig
|
15
|
+
extend T::Helpers
|
16
|
+
abstract!
|
17
|
+
|
18
|
+
# The authorization headers that need to be defined for this authentication strategy.
|
19
|
+
#
|
20
|
+
# @return [Hash(String)] the authorization key/values needed for authentication.
|
21
|
+
sig { abstract.returns(T::Hash[Symbol, T.untyped]) }
|
22
|
+
def auth_headers;end
|
23
|
+
|
24
|
+
# These are interface methods that a plugin that implements this strategy must implement.
|
25
|
+
module InterfaceMethods
|
26
|
+
extend T::Sig
|
27
|
+
extend T::Helpers
|
28
|
+
abstract!
|
29
|
+
|
30
|
+
# All auth actions that are implemented.
|
31
|
+
#
|
32
|
+
# @return [Hash] all auth endpoint definitions for the API.
|
33
|
+
sig { abstract.returns(T::Hash[T.untyped, T.untyped]) }
|
34
|
+
def auth_actions; end
|
35
|
+
|
36
|
+
# The base auth url for the plugin.
|
37
|
+
#
|
38
|
+
# @return [String] the auth url.
|
39
|
+
sig { overridable.returns(String) }
|
40
|
+
def auth_base_url
|
41
|
+
self.plugin.api_base_url
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Setsuzoku
|
5
|
+
module Service
|
6
|
+
module WebService
|
7
|
+
module Credentials
|
8
|
+
module BasicAuthCredential
|
9
|
+
include Setsuzoku::Credential
|
10
|
+
extend T::Sig
|
11
|
+
extend T::Helpers
|
12
|
+
abstract!
|
13
|
+
|
14
|
+
# The username to use for the credential.
|
15
|
+
#
|
16
|
+
# @return [String] the credential's token.
|
17
|
+
sig{ abstract.returns(T.nilable(String)) }
|
18
|
+
def username; end
|
19
|
+
|
20
|
+
# The username to set for the credential.
|
21
|
+
#
|
22
|
+
# @return [String] the credential's token to set.
|
23
|
+
#
|
24
|
+
sig{ abstract.params(val: String).returns(T.nilable(String)) }
|
25
|
+
def username=(val); end
|
26
|
+
|
27
|
+
# The password to use for the credential.
|
28
|
+
#
|
29
|
+
# @return [String] the credential's token.
|
30
|
+
sig{ abstract.returns(T.nilable(String)) }
|
31
|
+
def password; end
|
32
|
+
|
33
|
+
# The password to set for the credential.
|
34
|
+
#
|
35
|
+
# @return [String] the credential's token to set.
|
36
|
+
#
|
37
|
+
sig{ abstract.params(val: String).returns(T.nilable(String)) }
|
38
|
+
def password=(val); end
|
39
|
+
|
40
|
+
# Stub a basic_auth_credential-like instance.
|
41
|
+
#
|
42
|
+
# @return [Struct] a stubbed basic_auth_credential-like struct.
|
43
|
+
sig { returns(Struct) }
|
44
|
+
def self.stub_credential
|
45
|
+
s = Struct.new(:username, :password)
|
46
|
+
s.new('stubbed_username', 'stubbed_password')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'active_support/core_ext/numeric/time'
|
5
|
+
|
6
|
+
module Setsuzoku
|
7
|
+
module Service
|
8
|
+
module WebService
|
9
|
+
module Credentials
|
10
|
+
module OAuthCredential
|
11
|
+
extend T::Sig
|
12
|
+
extend T::Helpers
|
13
|
+
abstract!
|
14
|
+
|
15
|
+
# The application's client_id to o_auth with.
|
16
|
+
#
|
17
|
+
# @return [String] the client_id for o_auth.
|
18
|
+
sig { abstract.returns(T.nilable(String)) }
|
19
|
+
def client_id; end
|
20
|
+
|
21
|
+
# The application's client_secret to o_auth with.
|
22
|
+
#
|
23
|
+
# @return [String] the client_secret for o_auth.
|
24
|
+
sig { abstract.returns(T.nilable(String)) }
|
25
|
+
def client_secret; end
|
26
|
+
|
27
|
+
# The application's redirect url to handle an o_auth redirect
|
28
|
+
#
|
29
|
+
# @return [String] the redirect url.
|
30
|
+
sig { abstract.returns(T.nilable(String)) }
|
31
|
+
def redirect_url; end
|
32
|
+
|
33
|
+
# The token to use for the credential.
|
34
|
+
#
|
35
|
+
# @return [String] the credential's token.
|
36
|
+
sig{ abstract.returns(T.nilable(String)) }
|
37
|
+
def token; end
|
38
|
+
|
39
|
+
# The token to set for the credential.
|
40
|
+
#
|
41
|
+
# @return [String] the credential's token to set.
|
42
|
+
#
|
43
|
+
sig{ abstract.params(val: String).returns(T.nilable(String)) }
|
44
|
+
def token=(val); end
|
45
|
+
|
46
|
+
# The refresh token to use for the credential.
|
47
|
+
#
|
48
|
+
# @return [String] the credential's refresh token.
|
49
|
+
sig{ abstract.returns(T.nilable(String)) }
|
50
|
+
def refresh_token; end
|
51
|
+
|
52
|
+
# The refresh token to set for the credential.
|
53
|
+
#
|
54
|
+
# @return [String] the credential's refresh token to set.
|
55
|
+
#
|
56
|
+
sig{ abstract.params(val: String).returns(T.nilable(String)) }
|
57
|
+
def refresh_token=(val); end
|
58
|
+
|
59
|
+
# The time the currently valid token expires on.
|
60
|
+
#
|
61
|
+
# @return [Datetime] the time the current token expires.
|
62
|
+
sig{ abstract.returns(T.nilable(DateTime)) }
|
63
|
+
def expires_on; end
|
64
|
+
|
65
|
+
# The time to set for when the token expires on.
|
66
|
+
#
|
67
|
+
# @return [Datetime] the time to set for the current token's expiry.
|
68
|
+
sig{ abstract.params(val: DateTime).returns(T.nilable(DateTime)) }
|
69
|
+
def expires_on=(val); end
|
70
|
+
|
71
|
+
# Stub an o_auth_credential-like instance.
|
72
|
+
#
|
73
|
+
# @return [Struct] a stubbed o_auth_credential-like struct.
|
74
|
+
sig { returns(Struct) }
|
75
|
+
def self.stub_credential
|
76
|
+
s = Struct.new(:client_id, :client_secret, :redirect_url, :token, :refresh_token, :expires_on, :settings)
|
77
|
+
s.new('stubbed_client_id', 'stubbed_client_secret', 'stubbed_redirect_url', 'stubbed_token', 'refresh_token', (Time.now + 30.days), 'extension': 'test')
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Setsuzoku
|
5
|
+
module Service
|
6
|
+
module WebService
|
7
|
+
# WebService's Service should define all available auth and api strategies.
|
8
|
+
class Service
|
9
|
+
extend T::Sig
|
10
|
+
extend T::Helpers
|
11
|
+
include Setsuzoku::Service
|
12
|
+
|
13
|
+
# The api and auth strategies available for WebService.
|
14
|
+
#
|
15
|
+
# @return [Hash(Hash(Class))] the available_strategies object for WebService.
|
16
|
+
sig { override.returns(T::Hash[Symbol, T::Hash[Symbol, Class]]) }
|
17
|
+
def self.available_strategies
|
18
|
+
{
|
19
|
+
auth: {
|
20
|
+
basic: Setsuzoku::Service::WebService::AuthStrategies::BasicAuthStrategy,
|
21
|
+
o_auth: Setsuzoku::Service::WebService::AuthStrategies::OAuthStrategy
|
22
|
+
},
|
23
|
+
api: {
|
24
|
+
rest: ApiStrategies::RestStrategy
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/setsuzoku.gemspec
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "setsuzoku/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'setsuzoku'
|
8
|
+
spec.version = Setsuzoku::VERSION
|
9
|
+
spec.authors = ['Luke Stadtler']
|
10
|
+
spec.email = ['luke@rocketreferrals.com']
|
11
|
+
spec.homepage = 'https://github.com/rocketreferrals/setsuzoku'
|
12
|
+
spec.summary = 'Extensible 3rd-party interface and functionality plugins'
|
13
|
+
spec.description = 'Easily build generic, reusable 3rd party SDK-like plugins (intended to share).
|
14
|
+
Future functionality will include dynamic UIs and other functionality around the plugin.'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
# if spec.respond_to?(:metadata)
|
20
|
+
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
21
|
+
#
|
22
|
+
# spec.metadata["homepage_uri"] = spec.homepage
|
23
|
+
# spec.metadata["source_code_uri"] = "TODO: Put your gem's public repo URL here."
|
24
|
+
# spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
|
25
|
+
# else
|
26
|
+
# raise "RubyGems 2.0 or newer is required to protect against " \
|
27
|
+
# "public gem pushes."
|
28
|
+
# end
|
29
|
+
|
30
|
+
# Specify which files should be added to the gem when it is released.
|
31
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
32
|
+
spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
|
33
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
34
|
+
end
|
35
|
+
spec.bindir = "exe"
|
36
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
+
spec.require_paths = ["lib"]
|
38
|
+
|
39
|
+
spec.add_development_dependency "bundler", "~> 1.17"
|
40
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
41
|
+
spec.add_development_dependency "rspec", "~> 3.0"
|
42
|
+
spec.add_development_dependency "webmock", "~> 3.8"
|
43
|
+
spec.add_runtime_dependency "activesupport", "~> 5.0"
|
44
|
+
spec.add_development_dependency "sorbet", "~> 0.5"
|
45
|
+
spec.add_runtime_dependency "sorbet-runtime", "~> 0.5"
|
46
|
+
#TODO: we should remove httparty if we can just use faraday
|
47
|
+
spec.add_runtime_dependency "httparty", "~> 0.16.4"
|
48
|
+
spec.add_runtime_dependency "faraday", "~> 0.11"
|
49
|
+
spec.add_runtime_dependency "nokogiri", "~> 1.10"
|
50
|
+
end
|