bridgeapi_client 1.0.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/.env.example +2 -0
- data/.github/workflows/ci-analysis.yml +24 -0
- data/.github/workflows/rubocop-analysis.yml +24 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/.rubocop.yml +50 -0
- data/CHANGELOG.md +24 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +186 -0
- data/LICENSE.txt +21 -0
- data/README.md +229 -0
- data/Rakefile +12 -0
- data/bin/bundle +114 -0
- data/bin/coderay +27 -0
- data/bin/console +21 -0
- data/bin/htmldiff +27 -0
- data/bin/ldiff +27 -0
- data/bin/pry +27 -0
- data/bin/racc +27 -0
- data/bin/rake +27 -0
- data/bin/rspec +27 -0
- data/bin/rubocop +27 -0
- data/bin/ruby-parse +27 -0
- data/bin/ruby-rewrite +27 -0
- data/bin/setup +8 -0
- data/bridge_api.gemspec +40 -0
- data/lib/bridge_api/account.rb +46 -0
- data/lib/bridge_api/api/client.rb +206 -0
- data/lib/bridge_api/api/error.rb +48 -0
- data/lib/bridge_api/api/resource.rb +25 -0
- data/lib/bridge_api/authorization.rb +44 -0
- data/lib/bridge_api/bank.rb +18 -0
- data/lib/bridge_api/bridge_object.rb +120 -0
- data/lib/bridge_api/category.rb +39 -0
- data/lib/bridge_api/configuration.rb +38 -0
- data/lib/bridge_api/connect.rb +59 -0
- data/lib/bridge_api/insight.rb +27 -0
- data/lib/bridge_api/item.rb +91 -0
- data/lib/bridge_api/object_types.rb +28 -0
- data/lib/bridge_api/payment.rb +260 -0
- data/lib/bridge_api/provider.rb +40 -0
- data/lib/bridge_api/resources.rb +15 -0
- data/lib/bridge_api/stock.rb +45 -0
- data/lib/bridge_api/transaction.rb +79 -0
- data/lib/bridge_api/transfer.rb +42 -0
- data/lib/bridge_api/user.rb +98 -0
- data/lib/bridge_api/version.rb +5 -0
- data/lib/bridge_api.rb +22 -0
- data/lib/bridgeapi_client.rb +3 -0
- metadata +97 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "net/http"
|
|
4
|
+
require "uri"
|
|
5
|
+
require "json"
|
|
6
|
+
|
|
7
|
+
require "bridge_api/api/error"
|
|
8
|
+
|
|
9
|
+
module BridgeApi
|
|
10
|
+
module API
|
|
11
|
+
#
|
|
12
|
+
# Allows to request the Bridge API using Ruby native net/http library
|
|
13
|
+
#
|
|
14
|
+
class Client
|
|
15
|
+
HTTP_VERBS_MAP = {
|
|
16
|
+
get: Net::HTTP::Get,
|
|
17
|
+
post: Net::HTTP::Post,
|
|
18
|
+
put: Net::HTTP::Put,
|
|
19
|
+
delete: Net::HTTP::Delete
|
|
20
|
+
}.freeze
|
|
21
|
+
|
|
22
|
+
attr_accessor :access_token
|
|
23
|
+
|
|
24
|
+
#
|
|
25
|
+
# Handles a GET request
|
|
26
|
+
#
|
|
27
|
+
# @param [String] path the API endpoint PATH to query
|
|
28
|
+
# @param [Hash] params any params that might be required (or optional) to communicate with the API
|
|
29
|
+
#
|
|
30
|
+
# @return [Hash] the parsed API response
|
|
31
|
+
#
|
|
32
|
+
# @raise [API::Error] expectation if API responding with any error
|
|
33
|
+
#
|
|
34
|
+
def get(path, **params)
|
|
35
|
+
request :get, path, params
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
#
|
|
39
|
+
# Handles a POST request
|
|
40
|
+
#
|
|
41
|
+
# @param (see #get)
|
|
42
|
+
#
|
|
43
|
+
# @return (see #get)
|
|
44
|
+
#
|
|
45
|
+
# @raise (see #get)
|
|
46
|
+
#
|
|
47
|
+
|
|
48
|
+
def post(path, **params)
|
|
49
|
+
request :post, path, params
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
#
|
|
53
|
+
# Handles a PUT request
|
|
54
|
+
#
|
|
55
|
+
# @param (see #get)
|
|
56
|
+
#
|
|
57
|
+
# @return (see #get)
|
|
58
|
+
#
|
|
59
|
+
# @raise (see #get)
|
|
60
|
+
#
|
|
61
|
+
def put(path, **params)
|
|
62
|
+
request :put, path, params
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
#
|
|
66
|
+
# Handles a DELETE request
|
|
67
|
+
#
|
|
68
|
+
# @param (see #get)
|
|
69
|
+
#
|
|
70
|
+
# @return (see #get)
|
|
71
|
+
#
|
|
72
|
+
# @raise (see #get)
|
|
73
|
+
#
|
|
74
|
+
def delete(path, **params)
|
|
75
|
+
request :delete, path, params
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
private
|
|
79
|
+
|
|
80
|
+
def request(method, path, params = {})
|
|
81
|
+
make_http_request do
|
|
82
|
+
if !method.in?(%i(get delete))
|
|
83
|
+
HTTP_VERBS_MAP[method].new(path, headers).tap do |request|
|
|
84
|
+
request.body = params.to_json
|
|
85
|
+
end
|
|
86
|
+
else
|
|
87
|
+
HTTP_VERBS_MAP[method].new(encode_path(path, params), headers)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def make_http_request
|
|
93
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
|
|
94
|
+
http.set_debug_output($stdout) if debug?
|
|
95
|
+
|
|
96
|
+
request = yield
|
|
97
|
+
|
|
98
|
+
if debug?
|
|
99
|
+
puts "\n--- BRIDGE API REQUEST ---"
|
|
100
|
+
puts "#{request.method} #{uri}#{request.path}"
|
|
101
|
+
request.each_header { |k, v| puts " #{k}: #{v}" }
|
|
102
|
+
puts " Body: #{request.body.inspect}" if request.body
|
|
103
|
+
puts "--------------------------\n"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
api_response = http.request(request)
|
|
107
|
+
|
|
108
|
+
if debug?
|
|
109
|
+
puts "--- BRIDGE API RESPONSE #{api_response.code} ---"
|
|
110
|
+
puts api_response.body
|
|
111
|
+
puts "-------------------------------\n"
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
case api_response.code
|
|
115
|
+
when "200", "201"
|
|
116
|
+
data = parse_response_body(api_response.body)
|
|
117
|
+
|
|
118
|
+
if data.dig(:pagination, :next_uri) && follow_pages
|
|
119
|
+
handle_paging(data)
|
|
120
|
+
else
|
|
121
|
+
data
|
|
122
|
+
end
|
|
123
|
+
when "204", "202"
|
|
124
|
+
{}
|
|
125
|
+
else
|
|
126
|
+
handle_error(api_response)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def parse_response_body(json_response_body)
|
|
132
|
+
JSON.parse(json_response_body, symbolize_names: true)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def uri
|
|
136
|
+
@uri ||= URI.parse(BridgeApi.configuration.api_base_url)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def follow_pages
|
|
140
|
+
BridgeApi.configuration.follow_pages
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def debug?
|
|
144
|
+
BridgeApi.configuration.debug
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def handle_paging(data)
|
|
148
|
+
page_uri = URI.parse(data[:pagination][:next_uri])
|
|
149
|
+
params = URI.decode_www_form(page_uri.query).to_h
|
|
150
|
+
|
|
151
|
+
next_page_data = get(page_uri.path, **params)
|
|
152
|
+
|
|
153
|
+
next_page_data[:resources] = data[:resources] + next_page_data[:resources]
|
|
154
|
+
next_page_data
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def headers
|
|
158
|
+
headers =
|
|
159
|
+
{
|
|
160
|
+
"Bridge-Version" => BridgeApi.configuration.api_version,
|
|
161
|
+
"Client-Id" => BridgeApi.configuration.api_client_id,
|
|
162
|
+
"Client-Secret" => BridgeApi.configuration.api_client_secret,
|
|
163
|
+
"Content-Type" => "application/json",
|
|
164
|
+
"Accept" => "application/json"
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return headers unless access_token
|
|
168
|
+
|
|
169
|
+
headers.merge!("Authorization" => "Bearer #{access_token}")
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def encode_path(path, params = nil)
|
|
173
|
+
URI::HTTP
|
|
174
|
+
.build(path: path, query: URI.encode_www_form(params))
|
|
175
|
+
.request_uri
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def handle_error(api_response)
|
|
179
|
+
response_body = parse_response_body(api_response.body)
|
|
180
|
+
|
|
181
|
+
case api_response.code
|
|
182
|
+
when "400"
|
|
183
|
+
raise API::BadRequestError.new(api_response.code, response_body)
|
|
184
|
+
when "401"
|
|
185
|
+
raise API::UnauthorizedError.new(api_response.code, response_body)
|
|
186
|
+
when "403"
|
|
187
|
+
raise API::ForbiddenError.new(api_response.code, response_body)
|
|
188
|
+
when "404"
|
|
189
|
+
raise API::NotFoundError.new(api_response.code, response_body)
|
|
190
|
+
when "409"
|
|
191
|
+
raise API::ConflictError.new(api_response.code, response_body)
|
|
192
|
+
when "415"
|
|
193
|
+
raise API::UnsupportedMediaTypeError.new(api_response.code, response_body)
|
|
194
|
+
when "422"
|
|
195
|
+
raise API::UnprocessableEntityError.new(api_response.code, response_body)
|
|
196
|
+
when "429"
|
|
197
|
+
raise API::TooManyRequestsError.new(api_response.code, response_body)
|
|
198
|
+
when "500"
|
|
199
|
+
raise API::InternalServerError.new(api_response.code, response_body)
|
|
200
|
+
else
|
|
201
|
+
raise API::Error.new(api_response.code, response_body)
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgeApi
|
|
4
|
+
module API
|
|
5
|
+
#
|
|
6
|
+
# Error is the base error from which all other more specific BridgeApi errors derive.
|
|
7
|
+
#
|
|
8
|
+
class Error < StandardError
|
|
9
|
+
#
|
|
10
|
+
# Initializes Error
|
|
11
|
+
#
|
|
12
|
+
# @param [String] code the HTTP code returned by the API
|
|
13
|
+
# @param [Hash] response_body the parsed API response
|
|
14
|
+
# @option response_body [String] :type the machine readable error message
|
|
15
|
+
# @option response_body [String] :message the human readable error message
|
|
16
|
+
# @option response_body [String] :documentation_url the optional link to documentation
|
|
17
|
+
#
|
|
18
|
+
def initialize(code, response_body = {})
|
|
19
|
+
@payload = response_body
|
|
20
|
+
@code = code
|
|
21
|
+
@type = payload[:type]
|
|
22
|
+
@documentation_url = payload[:documentation_url]
|
|
23
|
+
|
|
24
|
+
super(payload[:message])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
attr_reader :payload, :code, :type, :documentation_url
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
class BadRequestError < Error; end
|
|
31
|
+
|
|
32
|
+
class UnauthorizedError < Error; end
|
|
33
|
+
|
|
34
|
+
class ForbiddenError < Error; end
|
|
35
|
+
|
|
36
|
+
class NotFoundError < Error; end
|
|
37
|
+
|
|
38
|
+
class ConflictError < Error; end
|
|
39
|
+
|
|
40
|
+
class UnsupportedMediaTypeError < Error; end
|
|
41
|
+
|
|
42
|
+
class UnprocessableEntityError < Error; end
|
|
43
|
+
|
|
44
|
+
class TooManyRequestsError < Error; end
|
|
45
|
+
|
|
46
|
+
class InternalServerError < Error; end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgeApi
|
|
4
|
+
module API
|
|
5
|
+
#
|
|
6
|
+
# Extend any resource class with API specific methods
|
|
7
|
+
#
|
|
8
|
+
module Resource
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def protected_resource(access_token)
|
|
12
|
+
client = API::Client.new
|
|
13
|
+
client.access_token = access_token
|
|
14
|
+
Thread.current[:bridge_api_api_client] = client
|
|
15
|
+
yield
|
|
16
|
+
ensure
|
|
17
|
+
Thread.current[:bridge_api_api_client] = nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def api_client
|
|
21
|
+
Thread.current[:bridge_api_api_client] || API::Client.new
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "time"
|
|
4
|
+
|
|
5
|
+
module BridgeApi
|
|
6
|
+
#
|
|
7
|
+
# User authentication & authorization
|
|
8
|
+
#
|
|
9
|
+
class Authorization
|
|
10
|
+
attr_reader :access_token, :expires_at
|
|
11
|
+
|
|
12
|
+
#
|
|
13
|
+
# Initializes Authorization
|
|
14
|
+
#
|
|
15
|
+
# @param [String] access_token access token the access token provided by the API
|
|
16
|
+
# @param [Time] expires_at the expiration time for the provided access token
|
|
17
|
+
#
|
|
18
|
+
def initialize(access_token, expires_at)
|
|
19
|
+
@access_token = access_token
|
|
20
|
+
@expires_at = Time.parse(expires_at)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
class << self
|
|
24
|
+
include API::Resource
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Generate an access token for a Bridge user
|
|
28
|
+
#
|
|
29
|
+
# @param [String] user_uuid the Bridge user UUID
|
|
30
|
+
# @param [String] external_user_id the external user identifier (alternative to user_uuid)
|
|
31
|
+
#
|
|
32
|
+
# @return [Authorization] the authorization informations provided by the API
|
|
33
|
+
#
|
|
34
|
+
def generate_token(user_uuid: nil, external_user_id: nil)
|
|
35
|
+
params = {}
|
|
36
|
+
params[:user_uuid] = user_uuid if user_uuid
|
|
37
|
+
params[:external_user_id] = external_user_id if external_user_id
|
|
38
|
+
|
|
39
|
+
response = api_client.post("/v3/aggregation/authorization/token", **params)
|
|
40
|
+
new(response[:access_token], response[:expires_at])
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgeApi
|
|
4
|
+
#
|
|
5
|
+
# Bank resource is deprecated, using Provider instead
|
|
6
|
+
#
|
|
7
|
+
class Bank < Provider
|
|
8
|
+
def self.list(**params)
|
|
9
|
+
warn "BridgeApi::Bank is deprecated. Use BridgeApi::Provider instead."
|
|
10
|
+
super
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def self.find(id:, **params)
|
|
14
|
+
warn "BridgeApi::Bank is deprecated. Use BridgeApi::Provider instead."
|
|
15
|
+
super
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgeApi
|
|
4
|
+
#
|
|
5
|
+
# BridgeObject is the base class from which all other more specific BridgeApi resources derive.
|
|
6
|
+
#
|
|
7
|
+
class BridgeObject
|
|
8
|
+
HIDDEN_ATTRIBUTES = %i[resource_type resource_uri].freeze
|
|
9
|
+
|
|
10
|
+
#
|
|
11
|
+
# Initializes BridgeObject
|
|
12
|
+
#
|
|
13
|
+
# @param [Hash] attrs any informations returned by the API as a valid response
|
|
14
|
+
#
|
|
15
|
+
def initialize(**attrs)
|
|
16
|
+
define_instance_variables(attrs)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
class << self
|
|
20
|
+
#
|
|
21
|
+
# Convert any API response body with its corresponding resource object if exists
|
|
22
|
+
#
|
|
23
|
+
# @param [Hash] data parsed API response body
|
|
24
|
+
#
|
|
25
|
+
# @return [Account, Bank, Category, Item, Stock, Transaction, Transfer, User, BridgeObject] a resource object
|
|
26
|
+
#
|
|
27
|
+
def convert_to_bridge_object(data)
|
|
28
|
+
if data[:resources]
|
|
29
|
+
data[:resources].map { |resource| convert_to_bridge_object(resource) }
|
|
30
|
+
elsif data.is_a?(Array)
|
|
31
|
+
data.map { |val| convert_to_bridge_object(val) }
|
|
32
|
+
else
|
|
33
|
+
object_from_resource_type(data)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def object_classes
|
|
40
|
+
@object_classes ||= ObjectTypes.resource_types_to_classes
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def object_from_resource_type(data)
|
|
44
|
+
object_classes.fetch(data[:resource_type], BridgeObject).new(**data)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def to_hash
|
|
49
|
+
instance_variables.each_with_object({}) do |var, hash|
|
|
50
|
+
hash[var.to_s.delete("@")] =
|
|
51
|
+
case instance_variable_get(var)
|
|
52
|
+
when BridgeObject
|
|
53
|
+
instance_variable_get(var).to_hash
|
|
54
|
+
when Array
|
|
55
|
+
instance_variable_get(var).map { |val| val.is_a?(BridgeObject) ? val.to_hash : val }
|
|
56
|
+
else
|
|
57
|
+
instance_variable_get(var)
|
|
58
|
+
end
|
|
59
|
+
end.transform_keys!(&:to_sym)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def to_json(*_args)
|
|
63
|
+
to_hash.to_json
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def ==(other)
|
|
67
|
+
other.is_a?(BridgeObject) && to_hash == other.to_hash
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def define_instance_variables(attrs)
|
|
73
|
+
attrs.each do |key, value|
|
|
74
|
+
next if HIDDEN_ATTRIBUTES.include?(key)
|
|
75
|
+
|
|
76
|
+
handle_values_types(key, value) do |parsed_value|
|
|
77
|
+
instance_variable_set(:"@#{key}", parsed_value)
|
|
78
|
+
self.class.class_eval { attr_reader key }
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def handle_values_types(key, value)
|
|
84
|
+
yield(
|
|
85
|
+
case value
|
|
86
|
+
when Array
|
|
87
|
+
handle_array_values(value)
|
|
88
|
+
when Hash
|
|
89
|
+
handle_hash_values(value)
|
|
90
|
+
when String
|
|
91
|
+
handle_time_values(key, value)
|
|
92
|
+
else
|
|
93
|
+
value
|
|
94
|
+
end
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def handle_array_values(array)
|
|
99
|
+
array.map do |value|
|
|
100
|
+
next value unless value.is_a?(Hash)
|
|
101
|
+
|
|
102
|
+
handle_hash_values(value)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def handle_hash_values(hash)
|
|
107
|
+
self.class.convert_to_bridge_object(hash)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def handle_time_values(key, value)
|
|
111
|
+
if key == :date
|
|
112
|
+
Date.parse(value)
|
|
113
|
+
elsif key.to_s.match?(/_at$/)
|
|
114
|
+
Time.parse(value)
|
|
115
|
+
else
|
|
116
|
+
value
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgeApi
|
|
4
|
+
#
|
|
5
|
+
# Category resource
|
|
6
|
+
#
|
|
7
|
+
class Category < BridgeObject
|
|
8
|
+
RESOURCE_TYPE = "category"
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
include API::Resource
|
|
12
|
+
|
|
13
|
+
#
|
|
14
|
+
# List all categories supported by the Bridge API
|
|
15
|
+
#
|
|
16
|
+
# @param [Hash] params any params that might be required (or optional) to communicate with the API
|
|
17
|
+
#
|
|
18
|
+
# @return [Array<Category>] the supported categories list
|
|
19
|
+
#
|
|
20
|
+
def list(**params)
|
|
21
|
+
data = api_client.get("/v3/aggregation/categories", **params)
|
|
22
|
+
convert_to_bridge_object(**data)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
#
|
|
26
|
+
# Retrieve a single category
|
|
27
|
+
#
|
|
28
|
+
# @param [Integer] id the id of the requested resource
|
|
29
|
+
# @param [Hash] params any params that might be required (or optional) to communicate with the API
|
|
30
|
+
#
|
|
31
|
+
# @return [Category] the requested category
|
|
32
|
+
#
|
|
33
|
+
def find(id:, **params)
|
|
34
|
+
data = api_client.get("/v3/aggregation/categories/#{id}", **params)
|
|
35
|
+
convert_to_bridge_object(**data)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# BridgeApi module
|
|
5
|
+
#
|
|
6
|
+
module BridgeApi
|
|
7
|
+
def self.configuration
|
|
8
|
+
@configuration ||= Configuration.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.configuration=(config)
|
|
12
|
+
@configuration = config
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.configure
|
|
16
|
+
yield configuration
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
#
|
|
20
|
+
# Configurations setup
|
|
21
|
+
#
|
|
22
|
+
class Configuration
|
|
23
|
+
attr_reader :api_base_url, :api_version
|
|
24
|
+
attr_accessor :api_client_id, :api_client_secret, :follow_pages, :debug
|
|
25
|
+
|
|
26
|
+
#
|
|
27
|
+
# Initializes Configuration
|
|
28
|
+
#
|
|
29
|
+
def initialize
|
|
30
|
+
@api_base_url = "https://api.bridgeapi.io"
|
|
31
|
+
@api_version = "2025-01-15"
|
|
32
|
+
@api_client_id = ""
|
|
33
|
+
@api_client_secret = ""
|
|
34
|
+
@follow_pages = false
|
|
35
|
+
@debug = false
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgeApi
|
|
4
|
+
#
|
|
5
|
+
# Connect resource
|
|
6
|
+
#
|
|
7
|
+
class Connect < BridgeObject
|
|
8
|
+
class << self
|
|
9
|
+
include API::Resource
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Create a Connect session (replaces all old connect methods)
|
|
13
|
+
#
|
|
14
|
+
# @param [String] access_token the access token provided during the user authentication
|
|
15
|
+
# @param [Hash] params any params that might be required (or optional) to communicate with the API
|
|
16
|
+
#
|
|
17
|
+
# @return [BridgeObject] Connect session with redirect_url
|
|
18
|
+
#
|
|
19
|
+
def create_session(access_token:, **params)
|
|
20
|
+
protected_resource(access_token) do
|
|
21
|
+
data = api_client.post("/v3/aggregation/connect-sessions", **params)
|
|
22
|
+
convert_to_bridge_object(**data)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Deprecated methods - kept for backward compatibility
|
|
27
|
+
|
|
28
|
+
def connect_item(access_token:, **params)
|
|
29
|
+
warn "BridgeApi::Connect.connect_item is deprecated. Use BridgeApi::Connect.create_session instead."
|
|
30
|
+
create_session(access_token: access_token, **params)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def connect_item_with_iban(access_token:, **params)
|
|
34
|
+
warn "BridgeApi::Connect.connect_item_with_iban is deprecated. Use BridgeApi::Connect.create_session instead."
|
|
35
|
+
create_session(access_token: access_token, **params)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def edit_item(access_token:, **params)
|
|
39
|
+
warn "BridgeApi::Connect.edit_item is deprecated. Use BridgeApi::Connect.create_session instead."
|
|
40
|
+
create_session(access_token: access_token, **params)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def item_sync(access_token:, **params)
|
|
44
|
+
warn "BridgeApi::Connect.item_sync is deprecated. Use BridgeApi::Connect.create_session instead."
|
|
45
|
+
create_session(access_token: access_token, **params)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def validate_email(access_token:, **params)
|
|
49
|
+
warn "BridgeApi::Connect.validate_email is deprecated. Use BridgeApi::Connect.create_session instead."
|
|
50
|
+
create_session(access_token: access_token, **params)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def validate_pro_items(access_token:, **params)
|
|
54
|
+
warn "BridgeApi::Connect.validate_pro_items is deprecated. Use BridgeApi::Connect.create_session instead."
|
|
55
|
+
create_session(access_token: access_token, **params)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module BridgeApi
|
|
4
|
+
#
|
|
5
|
+
# Insight resource
|
|
6
|
+
#
|
|
7
|
+
class Insight < BridgeObject
|
|
8
|
+
class << self
|
|
9
|
+
include API::Resource
|
|
10
|
+
|
|
11
|
+
#
|
|
12
|
+
# Categories statistics provided by Bridge
|
|
13
|
+
#
|
|
14
|
+
# @param [String] access_token the access token provided during the user authentication
|
|
15
|
+
# @param [Hash] params any params that might be required (or optional) to communicate with the API
|
|
16
|
+
#
|
|
17
|
+
# @return [Insight] the statistics generated by Bridge API
|
|
18
|
+
#
|
|
19
|
+
def categories_insights(access_token:, **params)
|
|
20
|
+
protected_resource(access_token) do
|
|
21
|
+
data = api_client.get("/v3/aggregation/insights/category", **params)
|
|
22
|
+
convert_to_bridge_object(**data)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|