supergood 0.1.0 → 0.1.2
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/.github/workflows/test.yml +26 -0
- data/.tool-versions +1 -0
- data/Gemfile.lock +2 -2
- data/README.md +18 -4
- data/lib/supergood/api.rb +31 -36
- data/lib/supergood/client.rb +35 -25
- data/lib/supergood/constants.rb +10 -2
- data/lib/supergood/utils.rb +4 -0
- data/lib/supergood/vendors/http.rb +49 -23
- data/lib/supergood/vendors/net-http.rb +53 -28
- data/lib/supergood/version.rb +1 -1
- data/supergood.gemspec +1 -1
- metadata +23 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a0cdb2377e5748a6ed76d61765fe3b15b648f397a97d6c9cdd28b592d68fd323
|
4
|
+
data.tar.gz: '099acaa41f71ef93c745960d9ec046b6643f68501fd95d140a1dd7c62eec76d1'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c15df0347deb5fcb0a0fdf04054595f8c4c9ef8b4da4fabc7879d6098fbe9595c507902ed6f7ccab95b47877f139d9121a1ecea885cb5f814ec86942cb37b3b
|
7
|
+
data.tar.gz: 97beed9cd863cd1175756b3084601a40f53928c205b3a3583ca04931a88f6a4804041b8506dfd7277f4232ed1bb7bad3a6eaf5494fe847955dff22439e1882c7
|
@@ -0,0 +1,26 @@
|
|
1
|
+
name: Unit Tests
|
2
|
+
env:
|
3
|
+
DATABASE_URL: ${{ secrets.STAGING_DATABASE_URL }}
|
4
|
+
SUPERGOOD_CLIENT_ID: ${{ secrets.STAGING_SUPERGOOD_CLIENT_ID }}
|
5
|
+
SUPERGOOD_CLIENT_SECRET: ${{ secrets.STAGING_SUPERGOOD_CLIENT_SECRET }}
|
6
|
+
SUPERGOOD_BASE_URL: 'http://localhost:3000'
|
7
|
+
SUPERGOOD_ORGANIZATION_ID: ${{ vars.SUPERGOOD_ORGANIZATION_ID }}
|
8
|
+
on:
|
9
|
+
push:
|
10
|
+
branches:
|
11
|
+
- master
|
12
|
+
pull_request:
|
13
|
+
branches: [master]
|
14
|
+
jobs:
|
15
|
+
test:
|
16
|
+
runs-on: ubuntu-latest
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v3
|
19
|
+
- name: Set up Ruby
|
20
|
+
uses: ruby/setup-ruby@359bebbc29cbe6c87da6bc9ea3bc930432750108
|
21
|
+
with:
|
22
|
+
ruby-version: '3.1'
|
23
|
+
- name: Install dependencies
|
24
|
+
run: bundle install
|
25
|
+
- name: Run tests
|
26
|
+
run: bundle exec rspec spec/client_spec.rb
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 3.2.1
|
data/Gemfile.lock
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
supergood (0.
|
5
|
-
faraday (~> 2.7, >= 2.7.4)
|
4
|
+
supergood (0.1.1)
|
6
5
|
rudash (~> 4.0, >= 4.0.2)
|
7
6
|
|
8
7
|
GEM
|
@@ -92,6 +91,7 @@ DEPENDENCIES
|
|
92
91
|
base64
|
93
92
|
digest
|
94
93
|
dotenv
|
94
|
+
faraday (~> 2.7, >= 2.7.4)
|
95
95
|
http (~> 5.1, >= 5.1.1)
|
96
96
|
httparty (~> 0.21.0)
|
97
97
|
json
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Supergood
|
2
2
|
|
3
|
-
|
3
|
+
Monitor the cost and performance of your external API's with two lines of code.
|
4
4
|
|
5
|
-
|
5
|
+
Interested in learning more? Check us out at https://supergood.ai or Reach out to alex@supergood.ai .
|
6
|
+
|
7
|
+
Not built on Ruby? We've got a node client, python client and golang client as well.
|
6
8
|
|
7
9
|
## Installation
|
8
10
|
|
@@ -22,7 +24,19 @@ Or install it yourself as:
|
|
22
24
|
|
23
25
|
## Usage
|
24
26
|
|
25
|
-
|
27
|
+
1. Head over to https://dashboard.supergood.ai and make an account, make sure to use your work email address!
|
28
|
+
2. Click on the tab labeled "API Keys" and generate a client id and client secret.
|
29
|
+
3. Head back to your code and initialize the Supergood client one of two ways:
|
30
|
+
|
31
|
+
```
|
32
|
+
require 'supergood'
|
33
|
+
|
34
|
+
Supergood.init(<client_id>, <client_secret>)
|
35
|
+
```
|
36
|
+
OR
|
37
|
+
|
38
|
+
set `SUPERGOOD_CLIENT_ID` and `SUPERGOOD_CLIENT_SECRET` as environment variables and leave the init function as `Supergood.init`
|
39
|
+
|
26
40
|
|
27
41
|
## Development
|
28
42
|
|
@@ -32,5 +46,5 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
32
46
|
|
33
47
|
## Contributing
|
34
48
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
49
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/supergoodsystems/supergood-rb.
|
36
50
|
|
data/lib/supergood/api.rb
CHANGED
@@ -1,13 +1,20 @@
|
|
1
|
-
require 'faraday'
|
2
1
|
require 'dotenv'
|
3
2
|
|
4
3
|
Dotenv.load
|
5
4
|
|
6
5
|
module Supergood
|
7
6
|
class Api
|
8
|
-
def initialize(
|
7
|
+
def initialize(client_id, client_secret, base_url)
|
9
8
|
@base_url = base_url
|
10
|
-
@header_options =
|
9
|
+
@header_options = {
|
10
|
+
'Content-Type' => 'application/json',
|
11
|
+
'Authorization' => 'Basic ' + Base64.encode64(client_id + ':' + client_secret).gsub(/\n/, '')
|
12
|
+
}
|
13
|
+
@local_only = client_id == LOCAL_CLIENT_ID && client_secret == LOCAL_CLIENT_SECRET
|
14
|
+
end
|
15
|
+
|
16
|
+
def header_options
|
17
|
+
@header_options
|
11
18
|
end
|
12
19
|
|
13
20
|
def log
|
@@ -18,45 +25,33 @@ module Supergood
|
|
18
25
|
@log = logger
|
19
26
|
end
|
20
27
|
|
21
|
-
def set_event_sink_endpoint(endpoint)
|
22
|
-
@event_sink_endpoint = endpoint
|
23
|
-
end
|
24
|
-
|
25
|
-
def set_error_sink_endpoint(endpoint)
|
26
|
-
@error_sink_endpoint = endpoint
|
27
|
-
end
|
28
|
-
|
29
28
|
def post_events(payload)
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
29
|
+
if @local_only
|
30
|
+
@log.debug(payload)
|
31
|
+
else
|
32
|
+
uri = URI(@base_url + '/api/events')
|
33
|
+
response = Net::HTTP.post(uri, payload.to_json, @header_options)
|
34
|
+
if response.code == '200'
|
35
|
+
return JSON.parse(response.body, symbolize_names: true)
|
36
|
+
elsif response.code == '401'
|
37
|
+
raise SupergoodException.new ERRORS[:UNAUTHORIZED]
|
38
|
+
elsif response.code != '200' && response.code != '201'
|
39
|
+
raise SupergoodException.new ERRORS[:POSTING_EVENTS]
|
40
|
+
end
|
38
41
|
end
|
39
42
|
end
|
40
43
|
|
41
44
|
def post_errors(payload)
|
42
|
-
|
43
|
-
|
44
|
-
if response.status == 200
|
45
|
-
return JSON.parse(response.body, symbolize_names: true)
|
45
|
+
if @local_only
|
46
|
+
@log.debug(payload)
|
46
47
|
else
|
47
|
-
@
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
if response.status == 200
|
55
|
-
return JSON.parse(response.body, symbolize_names: true)
|
56
|
-
elsif response.status == 401
|
57
|
-
raise SupergoodException.new ERRORS[:UNAUTHORIZED]
|
58
|
-
elsif response.status != 200 && response.status != 201
|
59
|
-
raise SupergoodException.new ERRORS[:FETCHING_CONFIG]
|
48
|
+
uri = URI(@base_url + '/api/errors')
|
49
|
+
response = Net::HTTP.post(uri, payload.to_json, @header_options)
|
50
|
+
if response.code == '200'
|
51
|
+
return JSON.parse(response.body, symbolize_names: true)
|
52
|
+
else
|
53
|
+
@log.warn(ERRORS[:POSTING_ERRORS])
|
54
|
+
end
|
60
55
|
end
|
61
56
|
end
|
62
57
|
end
|
data/lib/supergood/client.rb
CHANGED
@@ -12,11 +12,10 @@ Dotenv.load
|
|
12
12
|
module Supergood
|
13
13
|
|
14
14
|
DEFAULT_SUPERGOOD_BASE_URL = 'https://dashboard.supergood.ai'
|
15
|
-
|
16
15
|
class << self
|
17
|
-
def init(
|
18
|
-
supergood_client_id =
|
19
|
-
supergood_client_secret =
|
16
|
+
def init(config={})
|
17
|
+
supergood_client_id = config[:client_id] || ENV['SUPERGOOD_CLIENT_ID']
|
18
|
+
supergood_client_secret = config[:client_secret] || ENV['SUPERGOOD_CLIENT_SECRET']
|
20
19
|
|
21
20
|
if !supergood_client_id
|
22
21
|
raise SupergoodException.new ERRORS[:NO_CLIENT_ID]
|
@@ -26,27 +25,27 @@ module Supergood
|
|
26
25
|
raise SupergoodException.new ERRORS[:NO_CLIENT_SECRET]
|
27
26
|
end
|
28
27
|
|
29
|
-
@base_url =
|
30
|
-
|
31
|
-
|
32
|
-
'Authorization' => 'Basic ' + Base64.encode64(supergood_client_id + ':' + supergood_client_secret).gsub(/\n/, '')
|
33
|
-
}
|
28
|
+
@base_url = ENV['SUPERGOOD_BASE_URL'] || DEFAULT_SUPERGOOD_BASE_URL
|
29
|
+
@api = Supergood::Api.new(supergood_client_id, supergood_client_secret, @base_url)
|
30
|
+
@config = Supergood::Utils.make_config(config)
|
34
31
|
|
35
|
-
@api = Supergood::Api.new(header_options, @base_url)
|
36
|
-
@config = @api.fetch_config
|
37
32
|
@ignored_domains = @config[:ignoredDomains]
|
38
33
|
@keys_to_hash = @config[:keysToHash]
|
39
|
-
@logger = Supergood::Logger.new(@api, @config, header_options)
|
34
|
+
@logger = Supergood::Logger.new(@api, @config, @api.header_options)
|
40
35
|
|
41
|
-
@api.set_error_sink_endpoint(@config[:errorSinkEndpoint])
|
42
|
-
@api.set_event_sink_endpoint(@config[:eventSinkEndpoint])
|
43
36
|
@api.set_logger(@logger)
|
44
37
|
|
45
38
|
@request_cache = {}
|
46
39
|
@response_cache = {}
|
47
40
|
|
48
41
|
@interval_thread = set_interval(@config[:flushInterval]) { flush_cache }
|
49
|
-
|
42
|
+
|
43
|
+
@http_clients = [
|
44
|
+
Supergood::Vendor::NetHTTP,
|
45
|
+
Supergood::Vendor::HTTPrb
|
46
|
+
]
|
47
|
+
|
48
|
+
patch_all()
|
50
49
|
self
|
51
50
|
end
|
52
51
|
|
@@ -76,6 +75,7 @@ module Supergood
|
|
76
75
|
api.post_events(data)
|
77
76
|
rescue => e
|
78
77
|
log.error(data, e, e.message)
|
78
|
+
cleanup()
|
79
79
|
ensure
|
80
80
|
@response_cache.clear
|
81
81
|
@request_cache.clear if force
|
@@ -83,10 +83,27 @@ module Supergood
|
|
83
83
|
|
84
84
|
end
|
85
85
|
|
86
|
+
def cleanup()
|
87
|
+
@interval_thread.kill
|
88
|
+
unpatch_all()
|
89
|
+
end
|
90
|
+
|
86
91
|
def close(force = true)
|
87
92
|
log.debug('Cleaning up, flushing cache gracefully.')
|
88
|
-
@interval_thread.kill
|
89
93
|
flush_cache(force)
|
94
|
+
cleanup()
|
95
|
+
end
|
96
|
+
|
97
|
+
def patch_all
|
98
|
+
@http_clients.each do |client|
|
99
|
+
client.patch
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def unpatch_all
|
104
|
+
@http_clients.each do |client|
|
105
|
+
client.unpatch
|
106
|
+
end
|
90
107
|
end
|
91
108
|
|
92
109
|
def set_interval(delay)
|
@@ -98,14 +115,6 @@ module Supergood
|
|
98
115
|
end
|
99
116
|
end
|
100
117
|
|
101
|
-
def self.intercept(*args, &block)
|
102
|
-
instance.intercept(*args, &block)
|
103
|
-
end
|
104
|
-
|
105
|
-
def self.instance
|
106
|
-
@instance ||= Supergood.new
|
107
|
-
end
|
108
|
-
|
109
118
|
def intercept(request)
|
110
119
|
request_id = SecureRandom.uuid
|
111
120
|
requested_at = Time.now
|
@@ -138,6 +147,7 @@ module Supergood
|
|
138
147
|
}
|
139
148
|
rescue => e
|
140
149
|
log.error({ request: request }, e, ERRORS[:CACHING_REQUEST])
|
150
|
+
cleanup()
|
141
151
|
end
|
142
152
|
end
|
143
153
|
|
@@ -159,11 +169,11 @@ module Supergood
|
|
159
169
|
}), @keys_to_hash)
|
160
170
|
@request_cache.delete(request_id)
|
161
171
|
rescue => e
|
162
|
-
puts e
|
163
172
|
log.error(
|
164
173
|
{ request: request_payload, response: response_payload },
|
165
174
|
e, ERRORS[:CACHING_RESPONSE]
|
166
175
|
)
|
176
|
+
cleanup()
|
167
177
|
end
|
168
178
|
end
|
169
179
|
|
data/lib/supergood/constants.rb
CHANGED
@@ -4,9 +4,8 @@ ERRORS = {
|
|
4
4
|
DUMPING_DATA_TO_DISK: 'Error Dumping Data to Disk',
|
5
5
|
POSTING_EVENTS: 'Error Posting Events',
|
6
6
|
POSTING_ERRORS: 'Error Posting Errors',
|
7
|
-
FETCHING_CONFIG: 'Error Fetching Config',
|
8
7
|
WRITING_TO_DISK: 'Error writing to disk',
|
9
|
-
TEST_ERROR: 'Test Error for Testing
|
8
|
+
TEST_ERROR: 'Test Error for Testing Purpos es',
|
10
9
|
UNAUTHORIZED: 'Unauthorized: Invalid Client ID or Secret. Exiting.',
|
11
10
|
NO_CLIENT_ID:
|
12
11
|
'No Client ID Provided, set SUPERGOOD_CLIENT_ID or pass it as an argument',
|
@@ -14,8 +13,17 @@ ERRORS = {
|
|
14
13
|
'No Client Secret Provided, set SUPERGOOD_CLIENT_SECRET or pass it as an argument'
|
15
14
|
};
|
16
15
|
|
16
|
+
LOCAL_CLIENT_ID = 'local-client-id';
|
17
|
+
LOCAL_CLIENT_SECRET = 'local-client-secret';
|
18
|
+
|
17
19
|
DEFAULT_SUPERGOOD_BYTE_LIMIT = 500000
|
18
20
|
|
21
|
+
DEFAULT_CONFIG = {
|
22
|
+
keysToHash: [],
|
23
|
+
flushInterval: 1000,
|
24
|
+
ignoredDomains: []
|
25
|
+
}
|
26
|
+
|
19
27
|
# GZIP_START_BYTES = b'\x1f\x8b'
|
20
28
|
|
21
29
|
class SupergoodException < StandardError
|
data/lib/supergood/utils.rb
CHANGED
@@ -1,33 +1,59 @@
|
|
1
1
|
module Supergood
|
2
2
|
module Vendor
|
3
3
|
module HTTPrb
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
original_response = original_perform(original_request_payload, original_options)
|
19
|
-
status, statusText = original_response.status.to_s.split(' ')
|
20
|
-
{
|
21
|
-
headers: original_response.headers.to_hash,
|
22
|
-
status: status,
|
23
|
-
statusText: statusText,
|
24
|
-
body: Supergood::Utils.safe_parse_json(original_response),
|
25
|
-
original_response: original_response
|
4
|
+
def self.patch
|
5
|
+
if !self.existing_patch?
|
6
|
+
|
7
|
+
block = lambda do |x|
|
8
|
+
alias original_perform perform
|
9
|
+
def perform(original_request_payload, original_options)
|
10
|
+
request = {
|
11
|
+
headers: original_request_payload.headers.to_hash,
|
12
|
+
method: original_request_payload.verb.upcase.to_s,
|
13
|
+
body: Supergood::Utils.safe_parse_json(original_request_payload.body.source),
|
14
|
+
url: original_request_payload.uri.to_s,
|
15
|
+
path: original_request_payload.uri.path,
|
16
|
+
search: original_request_payload.uri.query,
|
17
|
+
domain: original_request_payload.uri.host
|
26
18
|
}
|
19
|
+
Supergood.intercept(request) do
|
20
|
+
original_response = original_perform(original_request_payload, original_options)
|
21
|
+
status, statusText = original_response.status.to_s.split(' ')
|
22
|
+
{
|
23
|
+
headers: original_response.headers.to_hash,
|
24
|
+
status: status,
|
25
|
+
statusText: statusText,
|
26
|
+
body: Supergood::Utils.safe_parse_json(original_response),
|
27
|
+
original_response: original_response
|
28
|
+
}
|
29
|
+
end
|
27
30
|
end
|
28
31
|
end
|
29
|
-
|
32
|
+
|
33
|
+
if defined?(HTTP::Client)
|
34
|
+
HTTP::Client.class_eval(&block)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.unpatch
|
41
|
+
if self.existing_patch?
|
42
|
+
block = lambda do |x|
|
43
|
+
alias perform original_perform
|
44
|
+
end
|
45
|
+
|
46
|
+
if defined?(HTTP::Client)
|
47
|
+
HTTP::Client.class_eval(&block)
|
48
|
+
HTTP::Client.undef_method :original_perform
|
49
|
+
end
|
50
|
+
end
|
30
51
|
end
|
52
|
+
|
53
|
+
def self.existing_patch?
|
54
|
+
defined?(HTTP::Client) && HTTP::Client.method_defined?(:original_perform)
|
55
|
+
end
|
56
|
+
|
31
57
|
end
|
32
58
|
end
|
33
59
|
end
|
@@ -5,41 +5,66 @@ require 'uri'
|
|
5
5
|
module Supergood
|
6
6
|
module Vendor
|
7
7
|
module NetHTTP
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
8
|
+
def self.patch
|
9
|
+
if !self.existing_patch?
|
10
|
+
block = lambda do |x|
|
11
|
+
alias original_request_method request
|
12
|
+
def request(original_request_payload, body = nil, &block)
|
13
|
+
http = self;
|
14
|
+
url = Supergood::Utils.request_url(http, original_request_payload)
|
15
|
+
uri = URI.parse(url)
|
16
|
+
request = {
|
17
|
+
headers: Supergood::Utils.get_header(original_request_payload),
|
18
|
+
method: original_request_payload.method,
|
19
|
+
body: original_request_payload.body,
|
20
|
+
url: url,
|
21
|
+
path: original_request_payload.path,
|
22
|
+
search: uri.query,
|
23
|
+
domain: uri.host,
|
24
|
+
}
|
25
|
+
Supergood.intercept(request) do
|
26
|
+
original_response = original_request_method(original_request_payload, body, &block)
|
27
|
+
{
|
28
|
+
headers: Supergood::Utils.get_header(original_response),
|
29
|
+
status: original_response.code,
|
30
|
+
statusText: original_response.message,
|
31
|
+
body: original_response.body,
|
32
|
+
original_response: original_response
|
33
|
+
}
|
34
|
+
end
|
35
|
+
end
|
32
36
|
end
|
37
|
+
|
38
|
+
if defined?(Net::HTTP)
|
39
|
+
Net::HTTP.class_eval(&block)
|
40
|
+
elsif defined?(::WebMock)
|
41
|
+
WebMock::HttpLibAdapters::NetHttpAdapter.instance_variable_get("@webMockNetHTTP").class_eval(&block)
|
42
|
+
end
|
43
|
+
|
33
44
|
end
|
34
45
|
end
|
35
46
|
|
36
|
-
|
37
|
-
|
47
|
+
def self.unpatch
|
48
|
+
if self.existing_patch?
|
49
|
+
block = lambda do |x|
|
50
|
+
alias request original_request_method
|
51
|
+
end
|
52
|
+
|
53
|
+
if defined?(Net::HTTP)
|
54
|
+
Net::HTTP.class_eval(&block)
|
55
|
+
Net::HTTP.undef_method :original_request_method
|
56
|
+
elsif defined?(::WebMock)
|
57
|
+
WebMock::HttpLibAdapters::NetHttpAdapter.instance_variable_get("@webMockNetHTTP").class_eval(&block)
|
58
|
+
WebMock::HttpLibAdapters::NetHttpAdapter.instance_variable_get("@webMockNetHTTP").undef_method :original_request_method
|
59
|
+
end
|
60
|
+
end
|
38
61
|
end
|
39
62
|
|
40
|
-
|
41
|
-
|
63
|
+
def self.existing_patch?
|
64
|
+
(defined?(Net::HTTP) && Net::HTTP.method_defined?(:original_request_method)) ||
|
65
|
+
(defined?(::Webmock) && WebMock::HttpLibAdapters::NetHttpAdapter.instance_variable_get("@webMockNetHTTP").method_defined?(:original_request_method))
|
42
66
|
end
|
67
|
+
|
43
68
|
end
|
44
69
|
end
|
45
70
|
end
|
data/lib/supergood/version.rb
CHANGED
data/supergood.gemspec
CHANGED
@@ -19,13 +19,13 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
20
20
|
|
21
21
|
s.add_dependency 'rudash', '~> 4.0', '>= 4.0.2'
|
22
|
-
s.add_dependency 'faraday', '~> 2.7', '>= 2.7.4'
|
23
22
|
|
24
23
|
s.add_development_dependency 'rest-client', '~> 2.1'
|
25
24
|
s.add_development_dependency 'httparty', '~> 0.21.0'
|
26
25
|
s.add_development_dependency 'http', '~> 5.1', '>= 5.1.1'
|
27
26
|
s.add_development_dependency 'rspec', '~> 3.12'
|
28
27
|
s.add_development_dependency 'webmock', '~> 3.18', '>= 3.18.1'
|
28
|
+
s.add_development_dependency 'faraday', '~> 2.7', '>= 2.7.4'
|
29
29
|
|
30
30
|
end
|
31
31
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: supergood
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Klarfeld
|
@@ -30,26 +30,6 @@ dependencies:
|
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: 4.0.2
|
33
|
-
- !ruby/object:Gem::Dependency
|
34
|
-
name: faraday
|
35
|
-
requirement: !ruby/object:Gem::Requirement
|
36
|
-
requirements:
|
37
|
-
- - "~>"
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '2.7'
|
40
|
-
- - ">="
|
41
|
-
- !ruby/object:Gem::Version
|
42
|
-
version: 2.7.4
|
43
|
-
type: :runtime
|
44
|
-
prerelease: false
|
45
|
-
version_requirements: !ruby/object:Gem::Requirement
|
46
|
-
requirements:
|
47
|
-
- - "~>"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '2.7'
|
50
|
-
- - ">="
|
51
|
-
- !ruby/object:Gem::Version
|
52
|
-
version: 2.7.4
|
53
33
|
- !ruby/object:Gem::Dependency
|
54
34
|
name: rest-client
|
55
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -132,14 +112,36 @@ dependencies:
|
|
132
112
|
- - ">="
|
133
113
|
- !ruby/object:Gem::Version
|
134
114
|
version: 3.18.1
|
115
|
+
- !ruby/object:Gem::Dependency
|
116
|
+
name: faraday
|
117
|
+
requirement: !ruby/object:Gem::Requirement
|
118
|
+
requirements:
|
119
|
+
- - "~>"
|
120
|
+
- !ruby/object:Gem::Version
|
121
|
+
version: '2.7'
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: 2.7.4
|
125
|
+
type: :development
|
126
|
+
prerelease: false
|
127
|
+
version_requirements: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '2.7'
|
132
|
+
- - ">="
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: 2.7.4
|
135
135
|
description:
|
136
136
|
email: alex@supergood.ai
|
137
137
|
executables: []
|
138
138
|
extensions: []
|
139
139
|
extra_rdoc_files: []
|
140
140
|
files:
|
141
|
+
- ".github/workflows/test.yml"
|
141
142
|
- ".gitignore"
|
142
143
|
- ".rspec"
|
144
|
+
- ".tool-versions"
|
143
145
|
- ".travis.yml"
|
144
146
|
- ".vscode/settings.json"
|
145
147
|
- Gemfile
|