sdr-client 0.19.0 → 0.23.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ae3d332b62dd4908555f961ffa5f9ebc12e0388836f36f855672731d8b940a1
4
- data.tar.gz: 97c3c18fc7e4ed98b5577ea24390eef9f2ecbf8c24970c92fd3d3097a13b5492
3
+ metadata.gz: ef6a0e67af5c582f3b632f331026fad31f94076dc4801c12757f768f4ea62498
4
+ data.tar.gz: 1bde2dc32b1e498e5262b8eae90fdfb6656230e7be0cd22f3014b6f01eab24b6
5
5
  SHA512:
6
- metadata.gz: f03baa42607cd68d3b814e46df38dda0567ca78082292faaf5ec47dfe518b68e0399f25305a89bed835bf68cde2e680f553646b4c921490ae06c7e426a812c5f
7
- data.tar.gz: d392e1bfda994e6266ca4e6e1834036e76a5cfd37008c6ceda87ed6c20d4cbae9becef1fe8f47e3631f824dae7ae883735e0718dec7161488763d891f9d57121
6
+ metadata.gz: b63ab57e61e0576862ac5f256009489d2eda0c383e92e2ccf0869b205f7f452bb8e1099daeddcfd58809a85b929a51da986c1944146ee69d23a6b065d6510ac1
7
+ data.tar.gz: 9cb2e996ffcef442079961310c3185b5780561f1046dd5f5b5da682edd2a0703729fb39964c69160cc0467683ac65ca54cec43954ee2201573b45cff39b43ef6
@@ -9,6 +9,8 @@ AllCops:
9
9
 
10
10
  Layout/LineLength:
11
11
  Max: 120
12
+ Exclude:
13
+ - 'spec/sdr_client/deposit/process_spec.rb'
12
14
 
13
15
  Metrics/BlockLength:
14
16
  Exclude:
data/README.md CHANGED
@@ -21,8 +21,15 @@ Log in:
21
21
  sdr --service-url http://sdr-api-server:3000 login
22
22
  ```
23
23
 
24
+ Register a new object:
25
+ ```
26
+ sdr --service-url https://sdr-api-server:3000 register --label 'hey there' \
27
+ --admin-policy 'druid:bk123gh4567' \
28
+ --collection 'druid:gh456kw9876' \
29
+ --source-id 'googlebooks:stanford_12345' file1.png file2.png
30
+ ```
24
31
 
25
- Deposit a new object:
32
+ Deposit (register + accession) a new object:
26
33
  ```
27
34
  sdr --service-url https://sdr-api-server:3000 deposit --label 'hey there' \
28
35
  --admin-policy 'druid:bk123gh4567' \
data/exe/sdr CHANGED
@@ -27,7 +27,10 @@ global = OptionParser.new do |opts|
27
27
 
28
28
  COMMANDS
29
29
  deposit
30
- deposit files to the SDR
30
+ accession object into the SDR
31
+
32
+ register
33
+ create a draft object in SDR
31
34
 
32
35
  login
33
36
  Will prompt for email & password and exchange it for an login token, which it saves in ~/.sdr/token
@@ -40,77 +43,80 @@ end
40
43
  global.order!
41
44
  command = ARGV.shift
42
45
 
43
- subcommands = {
44
- 'deposit' => OptionParser.new do |opts|
45
- opts.on('--label LABEL', 'The object label') do |label|
46
- options[:label] = label
47
- end
46
+ deposit_options = OptionParser.new do |opts|
47
+ opts.on('--label LABEL', 'The object label') do |label|
48
+ options[:label] = label
49
+ end
48
50
 
49
- opts.on('--admin-policy ADMIN_POLICY', 'The druid identifier of the admin policy object') do |apo|
50
- options[:apo] = apo
51
- end
51
+ opts.on('--admin-policy ADMIN_POLICY', 'The druid identifier of the admin policy object') do |apo|
52
+ options[:apo] = apo
53
+ end
52
54
 
53
- opts.on('--type TYPE', 'The object type to create. ' \
54
- 'One of: "image", "book", "document", "map", "manuscript", "media", ' \
55
- '"three_dimensional", "collection", or "admin_policy"') do |type|
56
- if %w[image book document map manuscript media three_dimensional collection admin_policy].include?(type)
57
- options[:type] = "http://cocina.sul.stanford.edu/models/#{type}.jsonld"
58
- end
55
+ opts.on('--type TYPE', 'The object type to create. ' \
56
+ 'One of: "image", "book", "document", "map", "manuscript", "media", ' \
57
+ '"three_dimensional", "collection", or "admin_policy"') do |type|
58
+ if %w[image book document map manuscript media three_dimensional collection admin_policy].include?(type)
59
+ options[:type] = "http://cocina.sul.stanford.edu/models/#{type}.jsonld"
59
60
  end
61
+ end
60
62
 
61
- opts.on('--collection COLLECTION', 'The druid identifier of the collection object') do |collection|
62
- options[:collection] = collection
63
- end
63
+ opts.on('--collection COLLECTION', 'The druid identifier of the collection object') do |collection|
64
+ options[:collection] = collection
65
+ end
64
66
 
65
- opts.on('--catkey CATKEY', 'The catkey for this item') do |catkey|
66
- options[:catkey] = catkey
67
- end
67
+ opts.on('--catkey CATKEY', 'The catkey for this item') do |catkey|
68
+ options[:catkey] = catkey
69
+ end
68
70
 
69
- opts.on('--source-id SOURCE_ID', 'The source id for this object') do |source_id|
70
- options[:source_id] = source_id
71
- end
71
+ opts.on('--source-id SOURCE_ID', 'The source id for this object') do |source_id|
72
+ options[:source_id] = source_id
73
+ end
72
74
 
73
- opts.on('--copyright COPYRIGHT', 'The copyright statement') do |copyright|
74
- options[:copyright] = copyright
75
- end
75
+ opts.on('--copyright COPYRIGHT', 'The copyright statement') do |copyright|
76
+ options[:copyright] = copyright
77
+ end
76
78
 
77
- opts.on('--use-statement STATEMENT', 'The use and reproduction statement') do |use_statement|
78
- options[:use_statement] = use_statement
79
- end
79
+ opts.on('--use-statement STATEMENT', 'The use and reproduction statement') do |use_statement|
80
+ options[:use_statement] = use_statement
81
+ end
80
82
 
81
- opts.on('--viewing-direction DIRECTION', 'The viewing direction (if a book). ' \
82
- 'Either "left-to-right" or "right-to-left"') do |viewing_direction|
83
- options[:viewing_direction] = viewing_direction if %w[left-to-right right-to-left].include?(viewing_direction)
84
- end
83
+ opts.on('--viewing-direction DIRECTION', 'The viewing direction (if a book). ' \
84
+ 'Either "left-to-right" or "right-to-left"') do |viewing_direction|
85
+ options[:viewing_direction] = viewing_direction if %w[left-to-right right-to-left].include?(viewing_direction)
86
+ end
85
87
 
86
- opts.on('--access LEVEL', 'The access level for this object. ' \
87
- 'Either "world", "stanford", "location-based", "citation-only" or "dark"') do |level|
88
- options[:access] = level if %w[world stanford location-based citation-only dark].include?(level)
89
- end
88
+ opts.on('--access LEVEL', 'The access level for this object. ' \
89
+ 'Either "world", "stanford", "location-based", "citation-only" or "dark"') do |level|
90
+ options[:access] = level if %w[world stanford location-based citation-only dark].include?(level)
91
+ end
90
92
 
91
- opts.on('--files-metadata FILES_METADATA', 'A JSON object representing per-file metadata') do |files_metadata|
92
- options[:files_metadata] = JSON.parse(files_metadata)
93
- end
93
+ opts.on('--files-metadata FILES_METADATA', 'A JSON object representing per-file metadata') do |files_metadata|
94
+ options[:files_metadata] = JSON.parse(files_metadata)
95
+ end
94
96
 
95
- opts.on('--strategy STRATEGY',
96
- 'The strategy to use for distributing files into filesets. Either "default" or "filename"') do |strategy|
97
- strategy_class = case strategy
98
- when 'filename'
99
- SdrClient::Deposit::MatchingFileGroupingStrategy
100
- when 'default'
101
- SdrClient::Deposit::SingleFileGroupingStrategy
102
- else
103
- warn "Unknown strategy #{strategy}"
104
- exit(1)
105
- end
106
- options[:grouping_strategy] = strategy_class
107
- end
97
+ opts.on('--strategy STRATEGY',
98
+ 'The strategy to use for distributing files into filesets. Either "default" or "filename"') do |strategy|
99
+ strategy_class = case strategy
100
+ when 'filename'
101
+ SdrClient::Deposit::MatchingFileGroupingStrategy
102
+ when 'default'
103
+ SdrClient::Deposit::SingleFileGroupingStrategy
104
+ else
105
+ warn "Unknown strategy #{strategy}"
106
+ exit(1)
107
+ end
108
+ options[:grouping_strategy] = strategy_class
109
+ end
108
110
 
109
- opts.on('-h', '--help', 'Display this screen') do
110
- puts opts
111
- exit
112
- end
113
- end,
111
+ opts.on('-h', '--help', 'Display this screen') do
112
+ puts opts
113
+ exit
114
+ end
115
+ end
116
+
117
+ subcommands = {
118
+ 'deposit' => deposit_options,
119
+ 'register' => deposit_options,
114
120
  'login' => OptionParser.new
115
121
  }
116
122
 
@@ -4,6 +4,8 @@ require 'dry/monads'
4
4
  require 'faraday'
5
5
  require 'active_support'
6
6
  require 'active_support/core_ext/object/json'
7
+ require 'active_support/core_ext/hash/indifferent_access'
8
+ require 'cocina/models'
7
9
 
8
10
  require 'sdr_client/version'
9
11
  require 'sdr_client/deposit'
@@ -6,7 +6,9 @@ module SdrClient
6
6
  def self.start(command, options)
7
7
  case command
8
8
  when 'deposit'
9
- SdrClient::Deposit.run(options)
9
+ SdrClient::Deposit.run(accession: true, **options)
10
+ when 'register'
11
+ SdrClient::Deposit.run(accession: false, **options)
10
12
  when 'login'
11
13
  status = SdrClient::Login.run(options)
12
14
  puts status.value if status.failure?
@@ -3,6 +3,8 @@
3
3
  module SdrClient
4
4
  # The connection to the server
5
5
  class Connection
6
+ include Dry::Monads[:result]
7
+
6
8
  def initialize(url:, token: Credentials.read)
7
9
  @url = url
8
10
  @token = token
@@ -15,6 +17,21 @@ module SdrClient
15
17
  end
16
18
  end
17
19
 
20
+ # This is only available to certain blessed accounts (argo) as it gives the
21
+ # token that allows you to act as any other user. Thus the caller must authenticate
22
+ # the user (e.g. using Shibboleth) before calling this method with their email address.
23
+ # @param [String] the email address of the person to proxy to.
24
+ # @return [Result] the token for the account
25
+ def proxy(to)
26
+ response = connection.post("/v1/auth/proxy?to=#{to}")
27
+ case response.status
28
+ when 200
29
+ Success(response.body)
30
+ else
31
+ Failure("Status: #{response.status}\n#{response.body}")
32
+ end
33
+ end
34
+
18
35
  delegate :put, :post, to: :connection
19
36
 
20
37
  private
@@ -23,6 +23,7 @@ module SdrClient
23
23
  url:,
24
24
  files: [],
25
25
  files_metadata: {},
26
+ accession: false,
26
27
  grouping_strategy: SingleFileGroupingStrategy,
27
28
  logger: Logger.new(STDOUT))
28
29
  augmented_metadata = FileMetadataBuilder.build(files: files, files_metadata: files_metadata)
@@ -41,7 +42,9 @@ module SdrClient
41
42
  files_metadata: augmented_metadata)
42
43
  connection = Connection.new(url: url)
43
44
  Process.new(metadata: metadata, connection: connection, files: files,
44
- grouping_strategy: grouping_strategy, logger: logger).run
45
+ grouping_strategy: grouping_strategy,
46
+ accession: accession,
47
+ logger: logger).run
45
48
  end
46
49
  # rubocop:enable Metrics/MethodLength
47
50
  # rubocop:enable Metrics/ParameterLists
@@ -56,6 +59,7 @@ require 'sdr_client/deposit/file'
56
59
  require 'sdr_client/deposit/file_metadata_builder'
57
60
  require 'sdr_client/deposit/file_set'
58
61
  require 'sdr_client/deposit/request'
59
- require 'sdr_client/deposit/upload_files'
60
62
  require 'sdr_client/deposit/metadata_builder'
61
63
  require 'sdr_client/deposit/process'
64
+ require 'sdr_client/deposit/upload_files'
65
+ require 'sdr_client/deposit/upload_resource'
@@ -34,9 +34,10 @@ module SdrClient
34
34
  administrative: {
35
35
  sdrPreserve: @preserve,
36
36
  shelve: @shelve
37
- }
37
+ },
38
+ version: 1,
39
+ hasMessageDigests: message_digests
38
40
  }.tap do |json|
39
- json['hasMessageDigests'] = message_digests unless message_digests.empty?
40
41
  json['hasMimeType'] = @mime_type if @mime_type
41
42
  json['use'] = @use if @use
42
43
  end
@@ -25,7 +25,8 @@ module SdrClient
25
25
  "label": label,
26
26
  structural: {
27
27
  contains: files.map(&:as_json)
28
- }
28
+ },
29
+ version: 1
29
30
  }
30
31
  end
31
32
 
@@ -6,19 +6,18 @@ module SdrClient
6
6
  module Deposit
7
7
  # The process for doing a deposit from a Cocina Model
8
8
  class ModelProcess
9
- DRO_PATH = '/v1/resources'
10
9
  # @param [Cocina::Model::RequestDRO] request_dro for depositing
11
- # @param [String] url the server to send to
12
- # @param [String] token the bearer auth token for the server
10
+ # @param [Connection] connection the connection to use
13
11
  # @param [Array<String>] files a list of file names to upload
12
+ # @param [Boolean] accession should the accessionWF be started
14
13
  # @param [Logger] logger the logger to use
15
- def initialize(request_dro:, url:,
16
- token:, files: [], logger: Logger.new(STDOUT))
14
+ def initialize(request_dro:, connection:,
15
+ files: [], accession:, logger: Logger.new(STDOUT))
17
16
  @files = files
18
- @url = url
19
- @token = token
17
+ @connection = connection
20
18
  @request_dro = request_dro
21
19
  @logger = logger
20
+ @accession = accession
22
21
  end
23
22
 
24
23
  def run
@@ -30,12 +29,15 @@ module SdrClient
30
29
  connection: connection,
31
30
  mime_types: mime_types).run
32
31
  new_request_dro = with_external_identifiers(upload_responses)
33
- upload_request_dro(new_request_dro.to_json)
32
+ UploadResource.run(accession: @accession,
33
+ metadata: new_request_dro.to_json,
34
+ logger: logger,
35
+ connection: connection)
34
36
  end
35
37
 
36
38
  private
37
39
 
38
- attr_reader :request_dro, :files, :url, :token, :logger
40
+ attr_reader :request_dro, :files, :logger, :connection
39
41
 
40
42
  def check_files_exist
41
43
  logger.info('checking to see if files exist')
@@ -59,31 +61,6 @@ module SdrClient
59
61
  end
60
62
  end
61
63
 
62
- # @return [Hash<Symbol,String>] the result of the metadata call
63
- def upload_request_dro(request_json)
64
- logger.info("Starting upload metadata: #{request_json}")
65
- response = connection.post(DRO_PATH, request_json, 'Content-Type' => 'application/json')
66
- unexpected_response(response) unless response.status == 201
67
-
68
- logger.info("Response from server: #{response.body}")
69
-
70
- { druid: JSON.parse(response.body)['druid'], background_job: response.headers['Location'] }
71
- end
72
-
73
- def unexpected_response(response)
74
- raise "There was an error with your request: #{response.body}" if response.status == 400
75
- raise 'There was an error with your credentials. Perhaps they have expired?' if response.status == 401
76
-
77
- raise "unexpected response: #{response.status} #{response.body}"
78
- end
79
-
80
- def connection
81
- @connection ||= Faraday.new(url: url) do |conn|
82
- conn.authorization :Bearer, token
83
- conn.adapter :net_http
84
- end
85
- end
86
-
87
64
  # Map of filenames to mimetypes
88
65
  def mime_types
89
66
  @mime_types ||=
@@ -6,21 +6,26 @@ module SdrClient
6
6
  module Deposit
7
7
  # The process for doing a deposit
8
8
  class Process
9
- DRO_PATH = '/v1/resources'
10
9
  # @param [Request] metadata information about the object
11
10
  # @param [Class] grouping_strategy class whose run method groups an array of uploads
12
11
  # @param [String] connection the server connection to use
13
12
  # @param [Array<String>] files a list of file names to upload
13
+ # @param [Boolean] accession should the accessionWF be started
14
14
  # @param [Logger] logger the logger to use
15
+ #
16
+ # rubocop:disable Metrics/ParameterLists
15
17
  def initialize(metadata:, grouping_strategy: SingleFileGroupingStrategy,
16
- connection:, files: [], logger: Logger.new(STDOUT))
18
+ connection:, files: [], accession:, logger: Logger.new(STDOUT))
17
19
  @files = files
18
20
  @connection = connection
19
21
  @metadata = metadata
20
22
  @logger = logger
21
23
  @grouping_strategy = grouping_strategy
24
+ @accession = accession
22
25
  end
26
+ # rubocop:enable Metrics/ParameterLists
23
27
 
28
+ # rubocop:disable Metrics/AbcSize
24
29
  def run
25
30
  check_files_exist
26
31
  upload_responses = UploadFiles.new(files: files,
@@ -31,8 +36,13 @@ module SdrClient
31
36
  grouping_strategy: grouping_strategy,
32
37
  logger: logger)
33
38
  request = metadata_builder.with_uploads(upload_responses)
34
- upload_metadata(request.as_json)
39
+ model = Cocina::Models.build_request(request.as_json.with_indifferent_access)
40
+ UploadResource.run(accession: @accession,
41
+ metadata: JSON.generate(model.to_h),
42
+ logger: logger,
43
+ connection: connection)
35
44
  end
45
+ # rubocop:enable Metrics/AbcSize
36
46
 
37
47
  private
38
48
 
@@ -45,25 +55,6 @@ module SdrClient
45
55
  end
46
56
  end
47
57
 
48
- # @return [Hash<Symbol,String>] the result of the metadata call
49
- def upload_metadata(metadata)
50
- logger.info("Starting upload metadata: #{metadata}")
51
- request_json = JSON.generate(metadata)
52
- response = connection.post(DRO_PATH, request_json, 'Content-Type' => 'application/json')
53
- unexpected_response(response) unless response.status == 201
54
-
55
- logger.info("Response from server: #{response.body}")
56
-
57
- { druid: JSON.parse(response.body)['druid'], background_job: response.headers['Location'] }
58
- end
59
-
60
- def unexpected_response(response)
61
- raise "There was an error with your request: #{response.body}" if response.status == 400
62
- raise 'There was an error with your credentials. Perhaps they have expired?' if response.status == 401
63
-
64
- raise "unexpected response: #{response.status} #{response.body}"
65
- end
66
-
67
58
  def mime_types
68
59
  @mime_types ||=
69
60
  Hash[
@@ -49,10 +49,10 @@ module SdrClient
49
49
  type: type,
50
50
  administrative: administrative,
51
51
  identification: identification,
52
- structural: structural
53
- }.tap do |json|
54
- json[:label] = label if label
55
- end
52
+ structural: structural,
53
+ version: 1,
54
+ label: label.nil? ? ':auto' : label
55
+ }
56
56
  end
57
57
 
58
58
  # @return [Request] a clone of this request with the file_sets added
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SdrClient
4
+ module Deposit
5
+ # Uploads a resource (metadata) to the server
6
+ class UploadResource
7
+ DRO_PATH = '/v1/resources'
8
+
9
+ def self.run(accession:, metadata:, logger:, connection:)
10
+ new(accession: accession, metadata: metadata, logger: logger, connection: connection).run
11
+ end
12
+
13
+ # @param [Boolean] accession should the accessionWF be started
14
+ # @param [String] metadata
15
+ # @param [Hash<Symbol,String>] the result of the metadata call
16
+ def initialize(accession:, metadata:, logger:, connection:)
17
+ @accession = accession
18
+ @metadata = metadata
19
+ @logger = logger
20
+ @connection = connection
21
+ end
22
+
23
+ # @param [Hash<Symbol,String>] the result of the metadata call
24
+ # @return [Hash<Symbol,String>] the result of the metadata call
25
+ def run
26
+ response = metadata_request
27
+ unexpected_response(response) unless response.status == 201
28
+
29
+ logger.info("Response from server: #{response.body}")
30
+
31
+ { druid: JSON.parse(response.body)['druid'], background_job: response.headers['Location'] }
32
+ end
33
+
34
+ private
35
+
36
+ attr_reader :metadata, :logger, :connection
37
+
38
+ def metadata_request
39
+ logger.debug("Starting upload metadata: #{metadata}")
40
+
41
+ connection.post(path, metadata, 'Content-Type' => 'application/json')
42
+ end
43
+
44
+ def unexpected_response(response)
45
+ raise "There was an error with your request: #{response.body}" if response.status == 400
46
+ raise 'There was an error with your credentials. Perhaps they have expired?' if response.status == 401
47
+
48
+ raise "unexpected response: #{response.status} #{response.body}"
49
+ end
50
+
51
+ def accession?
52
+ @accession
53
+ end
54
+
55
+ def path
56
+ path = DRO_PATH
57
+ path += '?accession=true' if accession?
58
+ path
59
+ end
60
+ end
61
+ end
62
+ end
@@ -7,12 +7,12 @@ module SdrClient
7
7
  extend Dry::Monads[:result]
8
8
 
9
9
  # @return [Result] the status of the call
10
- def self.run(url:, login_service: LoginPrompt)
10
+ def self.run(url:, login_service: LoginPrompt, credential_store: Credentials)
11
11
  request_json = JSON.generate(login_service.run)
12
12
  response = Faraday.post(url + LOGIN_PATH, request_json, 'Content-Type' => 'application/json')
13
13
  case response.status
14
14
  when 200
15
- Credentials.write(response.body)
15
+ credential_store.write(response.body)
16
16
  Success()
17
17
  when 400
18
18
  Failure('Email address is not a valid email')
@@ -8,10 +8,14 @@ module SdrClient
8
8
  def self.model_run(request_dro:,
9
9
  files: [],
10
10
  url:,
11
+ accession:,
11
12
  logger: Logger.new(STDOUT))
12
- token = Credentials.read
13
-
14
- ModelProcess.new(request_dro: request_dro, url: url, token: token, files: files, logger: logger).run
13
+ connection = Connection.new(url: url)
14
+ ModelProcess.new(request_dro: request_dro,
15
+ connection: connection,
16
+ files: files,
17
+ logger: logger,
18
+ accession: accession).run
15
19
  end
16
20
  end
17
21
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SdrClient
4
- VERSION = '0.19.0'
4
+ VERSION = '0.23.1'
5
5
  end
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  spec.require_paths = ['lib']
29
29
 
30
30
  spec.add_dependency 'activesupport'
31
- spec.add_dependency 'cocina-models', '~> 0.29.0'
31
+ spec.add_dependency 'cocina-models', '~> 0.31.0'
32
32
  spec.add_dependency 'dry-monads'
33
33
  spec.add_dependency 'faraday', '>= 0.16'
34
34
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sdr-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.0
4
+ version: 0.23.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-17 00:00:00.000000000 Z
11
+ date: 2020-04-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.29.0
33
+ version: 0.31.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.29.0
40
+ version: 0.31.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: dry-monads
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -207,6 +207,7 @@ files:
207
207
  - lib/sdr_client/deposit/request.rb
208
208
  - lib/sdr_client/deposit/single_file_grouping_strategy.rb
209
209
  - lib/sdr_client/deposit/upload_files.rb
210
+ - lib/sdr_client/deposit/upload_resource.rb
210
211
  - lib/sdr_client/login.rb
211
212
  - lib/sdr_client/login_prompt.rb
212
213
  - lib/sdr_client/model_deposit.rb