folio_client 0.11.0 → 0.12.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5e7b3edaad66a7bca966c6316eb979f722fe0eb2336def7f45eda9952a2a5ee
4
- data.tar.gz: 7d4d555e56d607acbb4649ef59e94e5ab417ee1f4f78fce2a999864f9e8486ee
3
+ metadata.gz: 7918be772bc1758840166cbb6f0fb66bfbf4765f636118d971efef2192a947df
4
+ data.tar.gz: 86d3c7e5656e849cf3358ddf7e22463bd65527cedf017a9a31dfdd2606bad88a
5
5
  SHA512:
6
- metadata.gz: ad63a3b363409b8561ca3ecf0f94b05f915ffe8ec621915e692f7d805d1f1c140b7626d2c95d613cc35974c08425a313e33ac72cc3249f68a1b3aece8d182688
7
- data.tar.gz: 6e0bfb061e5fafda66cc4690726bb69a17e3ccdd474997bb433d3fa9f02d55f2e6c103edc263ab82e22d69c36960576a7acc5ab73f23b7e6364acee487efb99e
6
+ metadata.gz: 9471247fec95c9df775cd359896c788d124173477b74f1124d41641f76e6d61438fe7b5e7c10fb3ee7d6efb9f5dba11c9b0b7b45fb9040520f6668cba626fc1d
7
+ data.tar.gz: 4f0adf00bb277b709a68552e7f2b5119e7b8597723ffc3c4f500d850e2c8470df0249a19e35a98bcfcf2ef6daa3befb8155e57d5f69c8d825fe3b1806cd240a5
File without changes
data/.rubocop/custom.yml CHANGED
@@ -34,9 +34,9 @@ RSpec/SubjectDeclaration: # new in 2.5
34
34
  Enabled: true
35
35
  RSpec/VerifiedDoubleReference: # new in 2.10.0
36
36
  Enabled: true
37
- RSpec/FactoryBot/ConsistentParenthesesStyle: # new in 2.14
37
+ FactoryBot/ConsistentParenthesesStyle: # new in 2.14
38
38
  Enabled: true
39
- RSpec/FactoryBot/SyntaxMethods: # new in 2.7
39
+ FactoryBot/SyntaxMethods: # new in 2.7
40
40
  Enabled: true
41
41
  RSpec/Rails/AvoidSetupHook: # new in 2.4
42
42
  Enabled: true
@@ -58,7 +58,7 @@ RSpec/DuplicatedMetadata: # new in 2.16
58
58
  Enabled: true
59
59
  RSpec/PendingWithoutReason: # new in 2.16
60
60
  Enabled: true
61
- RSpec/FactoryBot/FactoryNameStyle: # new in 2.16
61
+ FactoryBot/FactoryNameStyle: # new in 2.16
62
62
  Enabled: true
63
63
  RSpec/Rails/MinitestAssertions: # new in 2.17
64
64
  Enabled: true
@@ -68,3 +68,17 @@ RSpec/SkipBlockInsideExample: # new in 2.19
68
68
  Enabled: true
69
69
  RSpec/Rails/TravelAround: # new in 2.19
70
70
  Enabled: true
71
+ FactoryBot/AssociationStyle: # new in 2.23
72
+ Enabled: true
73
+ FactoryBot/FactoryAssociationWithStrategy: # new in 2.23
74
+ Enabled: true
75
+ FactoryBot/RedundantFactoryOption: # new in 2.23
76
+ Enabled: true
77
+ RSpec/BeEmpty: # new in 2.20
78
+ Enabled: true
79
+ RSpec/ContainExactly: # new in 2.19
80
+ Enabled: true
81
+ RSpec/IndexedLet: # new in 2.20
82
+ Enabled: true
83
+ RSpec/MatchArray: # new in 2.19
84
+ Enabled: true
data/.rubocop.yml CHANGED
@@ -3,12 +3,16 @@ inherit_mode:
3
3
  - Exclude
4
4
 
5
5
  require:
6
+ - standard
7
+ - standard-custom
8
+ - standard-performance
6
9
  - rubocop-performance
7
10
  - rubocop-rspec
8
- - standard
9
11
 
10
12
  inherit_gem:
11
13
  standard: config/base.yml
14
+ standard-performance: config/base.yml
15
+ standard-custom: config/base.yml
12
16
 
13
17
  inherit_from:
14
18
  - .rubocop/custom.yml
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- folio_client (0.11.0)
4
+ folio_client (0.12.0)
5
5
  activesupport (>= 4.2, < 8)
6
6
  dry-monads
7
7
  faraday
@@ -11,82 +11,92 @@ PATH
11
11
  GEM
12
12
  remote: https://rubygems.org/
13
13
  specs:
14
- activesupport (7.0.4.3)
14
+ activesupport (7.0.8)
15
15
  concurrent-ruby (~> 1.0, >= 1.0.2)
16
16
  i18n (>= 1.6, < 2)
17
17
  minitest (>= 5.1)
18
18
  tzinfo (~> 2.0)
19
- addressable (2.8.1)
19
+ addressable (2.8.5)
20
20
  public_suffix (>= 2.0.2, < 6.0)
21
21
  ast (2.4.2)
22
+ base64 (0.1.1)
22
23
  byebug (11.1.3)
23
24
  concurrent-ruby (1.2.2)
24
25
  crack (0.4.5)
25
26
  rexml
26
27
  diff-lcs (1.5.0)
27
28
  docile (1.4.0)
28
- dry-core (1.0.0)
29
+ dry-core (1.0.1)
29
30
  concurrent-ruby (~> 1.0)
30
31
  zeitwerk (~> 2.6)
31
32
  dry-monads (1.6.0)
32
33
  concurrent-ruby (~> 1.0)
33
34
  dry-core (~> 1.0, < 2)
34
35
  zeitwerk (~> 2.6)
35
- faraday (2.7.4)
36
+ faraday (2.7.11)
37
+ base64
36
38
  faraday-net_http (>= 2.0, < 3.1)
37
39
  ruby2_keywords (>= 0.0.4)
38
40
  faraday-net_http (3.0.2)
39
41
  hashdiff (1.0.1)
40
- i18n (1.12.0)
42
+ i18n (1.14.1)
41
43
  concurrent-ruby (~> 1.0)
42
44
  json (2.6.3)
43
45
  language_server-protocol (3.17.0.3)
46
+ lint_roller (1.1.0)
44
47
  marc (1.2.0)
45
48
  rexml
46
49
  scrub_rb (>= 1.0.1, < 2)
47
50
  unf
48
- minitest (5.18.0)
49
- parallel (1.22.1)
50
- parser (3.2.1.1)
51
+ minitest (5.20.0)
52
+ parallel (1.23.0)
53
+ parser (3.2.2.3)
51
54
  ast (~> 2.4.1)
52
- public_suffix (5.0.1)
55
+ racc
56
+ public_suffix (5.0.3)
57
+ racc (1.7.1)
53
58
  rainbow (3.1.1)
54
59
  rake (13.0.6)
55
- regexp_parser (2.7.0)
56
- rexml (3.2.5)
60
+ regexp_parser (2.8.1)
61
+ rexml (3.2.6)
57
62
  rspec (3.12.0)
58
63
  rspec-core (~> 3.12.0)
59
64
  rspec-expectations (~> 3.12.0)
60
65
  rspec-mocks (~> 3.12.0)
61
- rspec-core (3.12.1)
66
+ rspec-core (3.12.2)
62
67
  rspec-support (~> 3.12.0)
63
- rspec-expectations (3.12.2)
68
+ rspec-expectations (3.12.3)
64
69
  diff-lcs (>= 1.2.0, < 2.0)
65
70
  rspec-support (~> 3.12.0)
66
- rspec-mocks (3.12.4)
71
+ rspec-mocks (3.12.6)
67
72
  diff-lcs (>= 1.2.0, < 2.0)
68
73
  rspec-support (~> 3.12.0)
69
- rspec-support (3.12.0)
70
- rubocop (1.48.1)
74
+ rspec-support (3.12.1)
75
+ rubocop (1.56.3)
76
+ base64 (~> 0.1.1)
71
77
  json (~> 2.3)
78
+ language_server-protocol (>= 3.17.0)
72
79
  parallel (~> 1.10)
73
- parser (>= 3.2.0.0)
80
+ parser (>= 3.2.2.3)
74
81
  rainbow (>= 2.2.2, < 4.0)
75
82
  regexp_parser (>= 1.8, < 3.0)
76
83
  rexml (>= 3.2.5, < 4.0)
77
- rubocop-ast (>= 1.26.0, < 2.0)
84
+ rubocop-ast (>= 1.28.1, < 2.0)
78
85
  ruby-progressbar (~> 1.7)
79
86
  unicode-display_width (>= 2.4.0, < 3.0)
80
- rubocop-ast (1.28.0)
87
+ rubocop-ast (1.29.0)
81
88
  parser (>= 3.2.1.0)
82
- rubocop-capybara (2.17.1)
89
+ rubocop-capybara (2.18.0)
83
90
  rubocop (~> 1.41)
84
- rubocop-performance (1.16.0)
91
+ rubocop-factory_bot (2.24.0)
92
+ rubocop (~> 1.33)
93
+ rubocop-performance (1.19.1)
85
94
  rubocop (>= 1.7.0, < 2.0)
86
95
  rubocop-ast (>= 0.4.0)
87
- rubocop-rspec (2.19.0)
96
+ rubocop-rspec (2.24.0)
88
97
  rubocop (~> 1.33)
89
98
  rubocop-capybara (~> 2.17)
99
+ rubocop-factory_bot (~> 2.22)
90
100
  ruby-progressbar (1.13.0)
91
101
  ruby2_keywords (0.0.5)
92
102
  scrub_rb (1.0.1)
@@ -96,21 +106,29 @@ GEM
96
106
  simplecov_json_formatter (~> 0.1)
97
107
  simplecov-html (0.12.3)
98
108
  simplecov_json_formatter (0.1.4)
99
- standard (1.25.3)
109
+ standard (1.31.1)
100
110
  language_server-protocol (~> 3.17.0.2)
101
- rubocop (~> 1.48.1)
102
- rubocop-performance (~> 1.16.0)
111
+ lint_roller (~> 1.0)
112
+ rubocop (~> 1.56.2)
113
+ standard-custom (~> 1.0.0)
114
+ standard-performance (~> 1.2)
115
+ standard-custom (1.0.2)
116
+ lint_roller (~> 1.0)
117
+ rubocop (~> 1.50)
118
+ standard-performance (1.2.0)
119
+ lint_roller (~> 1.1)
120
+ rubocop-performance (~> 1.19.0)
103
121
  tzinfo (2.0.6)
104
122
  concurrent-ruby (~> 1.0)
105
123
  unf (0.1.4)
106
124
  unf_ext
107
125
  unf_ext (0.0.8.2)
108
126
  unicode-display_width (2.4.2)
109
- webmock (3.18.1)
127
+ webmock (3.19.1)
110
128
  addressable (>= 2.8.0)
111
129
  crack (>= 0.3.2)
112
130
  hashdiff (>= 0.4.0, < 2.0.0)
113
- zeitwerk (2.6.7)
131
+ zeitwerk (2.6.11)
114
132
 
115
133
  PLATFORMS
116
134
  x86_64-darwin-19
@@ -130,4 +148,4 @@ DEPENDENCIES
130
148
  webmock
131
149
 
132
150
  BUNDLED WITH
133
- 2.4.5
151
+ 2.4.13
data/README.md CHANGED
@@ -71,15 +71,15 @@ client.fetch_marc_hash(instance_hrid: "a7927874")
71
71
  [{"003"=>"FOLIO"}....]
72
72
  }
73
73
 
74
- # Import a MARC record into FOLIO
75
- data_importer = client.data_import(marc: my_marc, job_profile_id: '4ba4f4ab', job_profile_name: 'ETDs')
74
+ # Import MARC records into FOLIO
75
+ data_importer = client.data_import(records: [marc_record1, marc_record2], job_profile_id: '4ba4f4ab', job_profile_name: 'ETDs')
76
76
  # If called too quickly, might get Failure(:not_found)
77
77
  data_importer.status
78
78
  => Failure(:pending)
79
79
  data_importer.wait_until_complete
80
80
  => Success()
81
- data_importer.instance_hrid
82
- => Success("in00000000010")
81
+ data_importer.instance_hrids
82
+ => Success(["in00000000010", "in00000000011"])
83
83
 
84
84
  # Get list of organizations (filtered with an optional query)
85
85
  # see https://s3.amazonaws.com/foliodocs/api/mod-organizations/p/organizations.html#organizations_organizations_get
@@ -14,17 +14,21 @@ class FolioClient
14
14
  @client = client
15
15
  end
16
16
 
17
- # @param record [MARC::Record] record to be imported
17
+ # @param records [Array<MARC::Record>] records to be imported
18
18
  # @param job_profile_id [String] job profile id to use for import
19
19
  # @param job_profile_name [String] job profile name to use for import
20
20
  # @return [JobStatus] a job status instance to get information about the data import job
21
- def import(marc:, job_profile_id:, job_profile_name:)
21
+ def import(records:, job_profile_id:, job_profile_name:)
22
22
  response_hash = client.post("/data-import/uploadDefinitions", {fileDefinitions: [{name: marc_filename}]})
23
23
  upload_definition_id = response_hash.dig("fileDefinitions", 0, "uploadDefinitionId")
24
24
  job_execution_id = response_hash.dig("fileDefinitions", 0, "jobExecutionId")
25
25
  file_definition_id = response_hash.dig("fileDefinitions", 0, "id")
26
26
 
27
- upload_file_response_hash = client.post("/data-import/uploadDefinitions/#{upload_definition_id}/files/#{file_definition_id}", marc_binary(marc), content_type: "application/octet-stream")
27
+ upload_file_response_hash = client.post(
28
+ "/data-import/uploadDefinitions/#{upload_definition_id}/files/#{file_definition_id}",
29
+ marc_binary(records),
30
+ content_type: "application/octet-stream"
31
+ )
28
32
 
29
33
  client.post(
30
34
  "/data-import/uploadDefinitions/#{upload_definition_id}/processFiles",
@@ -51,16 +55,16 @@ class FolioClient
51
55
 
52
56
  private
53
57
 
54
- attr_reader :client, :marc, :job_profile_id, :job_profile_name
58
+ attr_reader :client, :job_profile_id, :job_profile_name
55
59
 
56
60
  def marc_filename
57
61
  @marc_filename ||= "#{DateTime.now.iso8601}.marc"
58
62
  end
59
63
 
60
- def marc_binary(marc)
64
+ def marc_binary(records)
61
65
  StringIO.open do |io|
62
66
  MARC::Writer.new(io) do |writer|
63
- writer.write(marc)
67
+ records.each { |record| writer.write(record) }
64
68
  end
65
69
  io.string
66
70
  end
@@ -17,15 +17,17 @@ class FolioClient
17
17
  @job_execution_id = job_execution_id
18
18
  end
19
19
 
20
- # @return [Dry::Monads::Result] Success if job is complete,
21
- # Failure(:pending) if job is still running,
22
- # Failure(:error) if job has errors
23
- # Failure(:not_found) if job is not found
20
+ # @todo An "ERROR" approach means one or more records failed, but it does
21
+ # not mean they all fail. We will likely need a more nuanced way to
22
+ # handle this eventually.
23
+ #
24
+ # @return [Dry::Monads::Result] Success() if job is complete,
25
+ # Failure(:pending) if job is still running,
26
+ # Failure(:not_found) if job is not found
24
27
  def status
25
- response_hash = client.get("/metadata-provider/jobSummary/#{job_execution_id}")
28
+ response_hash = client.get("/change-manager/jobExecutions/#{job_execution_id}")
26
29
 
27
- return Failure(:error) if response_hash["totalErrors"].positive?
28
- return Failure(:pending) if response_hash.dig("sourceRecordSummary", "totalCreatedEntities").zero? && response_hash.dig("sourceRecordSummary", "totalUpdatedEntities").zero?
30
+ return Failure(:pending) if !["COMMITTED", "ERROR"].include?(response_hash["status"])
29
31
 
30
32
  Success()
31
33
  rescue ResourceNotFound
@@ -37,18 +39,18 @@ class FolioClient
37
39
  wait_with_timeout(wait_secs: wait_secs, timeout_secs: timeout_secs) { status }
38
40
  end
39
41
 
40
- def instance_hrid
42
+ def instance_hrids
41
43
  current_status = status
42
44
  return current_status unless current_status.success?
43
45
 
44
- @instance_hrid ||= wait_with_timeout do
46
+ @instance_hrids ||= wait_with_timeout do
45
47
  response = client
46
48
  .get("/metadata-provider/journalRecords/#{job_execution_id}")
47
49
  .fetch("journalRecords", [])
48
- .find { |journal_record| journal_record["entityType"] == "INSTANCE" }
49
- &.fetch("entityHrId", nil)
50
+ .select { |journal_record| journal_record["entityType"] == "INSTANCE" && journal_record["actionStatus"] == "COMPLETED" }
51
+ .filter_map { |instance_record| instance_record["entityHrId"] }
50
52
 
51
- response.nil? ? Failure() : Success(response)
53
+ response.empty? ? Failure() : Success(response)
52
54
  end
53
55
  end
54
56
 
@@ -61,7 +63,7 @@ class FolioClient
61
63
  end
62
64
 
63
65
  def default_timeout_secs
64
- 5 * 60
66
+ 10 * 60
65
67
  end
66
68
 
67
69
  def wait_with_timeout(wait_secs: default_wait_secs, timeout_secs: default_timeout_secs)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class FolioClient
4
- VERSION = "0.11.0"
4
+ VERSION = "0.12.0"
5
5
  end
data/lib/folio_client.rb CHANGED
@@ -47,25 +47,34 @@ class FolioClient
47
47
  # @param url [String] the folio API URL
48
48
  # @param login_params [Hash] the folio client login params (username:, password:)
49
49
  # @param okapi_headers [Hash] the okapi specific headers to add (X-Okapi-Tenant:, User-Agent:)
50
+ # @return [FolioClient] the configured Singleton class
50
51
  def configure(url:, login_params:, okapi_headers:, timeout: default_timeout)
51
52
  instance.config = OpenStruct.new(
53
+ # For the initial token, use a dummy value to avoid hitting any APIs
54
+ # during configuration, allowing `with_token_refresh_when_unauthorized` to handle
55
+ # auto-magic token refreshing. Why not immediately get a valid token? Our apps
56
+ # commonly invoke client `.configure` methods in the initializer in all
57
+ # application environments, even those that are never expected to
58
+ # connect to production APIs, such as local development machines.
59
+ #
60
+ # NOTE: `nil` and blank string cannot be used as dummy values here as
61
+ # they lead to a malformed request to be sent, which triggers an
62
+ # exception not rescued by `with_token_refresh_when_unauthorized`
63
+ token: "a temporary dummy token to avoid hitting the API before it is needed",
52
64
  url: url,
53
65
  login_params: login_params,
54
66
  okapi_headers: okapi_headers,
55
67
  timeout: timeout
56
68
  )
57
69
 
58
- # NOTE: The token cannot be set above, since `#connection` relies on
59
- # `instance.config` parameters having already been set.
60
- instance.config.token = Authenticator.token(login_params, connection)
61
-
62
70
  self
63
71
  end
64
72
 
65
- delegate :config, :connection, :data_import, :default_timeout, :edit_marc_json,
66
- :fetch_external_id, :fetch_hrid, :fetch_instance_info, :fetch_marc_hash, :get,
67
- :has_instance_status?, :interface_details, :job_profiles, :organization_interfaces,
68
- :organizations, :post, :put, to: :instance
73
+ delegate :config, :connection, :data_import, :default_timeout,
74
+ :edit_marc_json, :fetch_external_id, :fetch_hrid, :fetch_instance_info,
75
+ :fetch_marc_hash, :get, :has_instance_status?, :http_get_headers,
76
+ :http_post_and_put_headers, :interface_details, :job_profiles,
77
+ :organization_interfaces, :organizations, :post, :put, to: :instance
69
78
  end
70
79
 
71
80
  attr_accessor :config
@@ -74,7 +83,7 @@ class FolioClient
74
83
  # @param path [String] the path to the Folio API request
75
84
  # @param params [Hash] params to get to the API
76
85
  def get(path, params = {})
77
- response = TokenWrapper.refresh(config, connection) do
86
+ response = with_token_refresh_when_unauthorized do
78
87
  connection.get(path, params, {"x-okapi-token": config.token})
79
88
  end
80
89
 
@@ -91,7 +100,7 @@ class FolioClient
91
100
  # @param body [Object] body to post to the API as JSON
92
101
  def post(path, body = nil, content_type: "application/json")
93
102
  req_body = (content_type == "application/json") ? body&.to_json : body
94
- response = TokenWrapper.refresh(config, connection) do
103
+ response = with_token_refresh_when_unauthorized do
95
104
  req_headers = {
96
105
  "x-okapi-token": config.token,
97
106
  "content-type": content_type
@@ -112,7 +121,7 @@ class FolioClient
112
121
  # @param body [Object] body to put to the API as JSON
113
122
  def put(path, body = nil, content_type: "application/json")
114
123
  req_body = (content_type == "application/json") ? body&.to_json : body
115
- response = TokenWrapper.refresh(config, connection) do
124
+ response = with_token_refresh_when_unauthorized do
116
125
  req_headers = {
117
126
  "x-okapi-token": config.token,
118
127
  "content-type": content_type
@@ -218,4 +227,30 @@ class FolioClient
218
227
  def default_timeout
219
228
  120
220
229
  end
230
+
231
+ private
232
+
233
+ # Wraps API operations to request new access token if expired.
234
+ # @yieldreturn response [Faraday::Response] the response to inspect
235
+ #
236
+ # @note You likely want to make sure you're wrapping a _single_ HTTP request in this
237
+ # method, because 1) all calls in the block will be retried from the top if there's
238
+ # an authN failure detected, and 2) only the response returned by the block will be
239
+ # inspected for authN failure.
240
+ # Related: consider that the client instance and its token will live across many
241
+ # invocations of the FolioClient methods once the client is configured by a consuming application,
242
+ # since this class is a Singleton. Thus, a token may expire between any two calls (i.e. it
243
+ # isn't necessary for a set of operations to collectively take longer than the token lifetime for
244
+ # expiry to fall in the middle of that related set of HTTP calls).
245
+ def with_token_refresh_when_unauthorized
246
+ response = yield
247
+
248
+ # if unauthorized, token has likely expired. try to get a new token and then retry the same request(s).
249
+ if response.status == 401
250
+ config.token = Authenticator.token(config.login_params, connection)
251
+ response = yield
252
+ end
253
+
254
+ response
255
+ end
221
256
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: folio_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.0
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Mangiafico
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-04-04 00:00:00.000000000 Z
11
+ date: 2023-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -196,7 +196,6 @@ files:
196
196
  - lib/folio_client/organizations.rb
197
197
  - lib/folio_client/records_editor.rb
198
198
  - lib/folio_client/source_storage.rb
199
- - lib/folio_client/token_wrapper.rb
200
199
  - lib/folio_client/unexpected_response.rb
201
200
  - lib/folio_client/version.rb
202
201
  homepage: https://github.com/sul-dlss/folio_client
@@ -206,7 +205,7 @@ metadata:
206
205
  source_code_uri: https://github.com/sul-dlss/folio_client
207
206
  changelog_uri: https://github.com/sul-dlss/folio_client/releases
208
207
  rubygems_mfa_required: 'true'
209
- post_install_message:
208
+ post_install_message:
210
209
  rdoc_options: []
211
210
  require_paths:
212
211
  - lib
@@ -222,7 +221,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
222
221
  version: '0'
223
222
  requirements: []
224
223
  rubygems_version: 3.3.7
225
- signing_key:
224
+ signing_key:
226
225
  specification_version: 4
227
226
  summary: Interface for interacting with the Folio ILS API.
228
227
  test_files: []
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class FolioClient
4
- # Wraps API operations to request new access token if expired
5
- class TokenWrapper
6
- def self.refresh(config, connection)
7
- yield.tap { |response| UnexpectedResponse.call(response) unless response.success? }
8
- rescue UnauthorizedError
9
- config.token = Authenticator.token(config.login_params, connection)
10
- yield
11
- end
12
- end
13
- end