valkyrie 3.4.0 → 3.5.0

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: a4fcef8213a3e959929dbdb15bffd20c70bf3a5a07ff977a4937271d137d51a7
4
- data.tar.gz: 875ced504589316a4d837fbd4d2d8bfe2e590d0e5f5f3c792edefe1461575a25
3
+ metadata.gz: 7ba113a4df1fa120076006223d629be9d186f96736fbb363781bc78f6c038013
4
+ data.tar.gz: 89e485a082def7836f884354b136c081496b5a9f36e98c2f9f31127dc053ab28
5
5
  SHA512:
6
- metadata.gz: 98945b1fdd7f8cce636eea9abf5fc44c05d8291d1955b22ff91e218e12b81f4b3b617f52d0c846b179e040f623665a62027c60de2b50c50d7b027a7008d78e12
7
- data.tar.gz: 844db5f6507ff3678ffe3c253a29dedd7753d26da6495ffcf51e2a275e6175fc9a904361a5724ec385330366eb84eaf13acf66db014bc783201e2e06e11168fb
6
+ metadata.gz: 3d3537379fb136ec2ca843e2dd13d85a22c46a9c74d94f1ca3cfb1ab32f4a193394ab1ff9deae649939e3260b0ba9e9d8f423f3fb87d40043d107ff646fb74bc
7
+ data.tar.gz: 4a908d4d2574d5017bc81af1683d714b028b5d1ab17e086ff0f8ea6d0a764348f3efd3f308aeedac4623956ccfce915a5c5d611ab84d7e9e2d08c22d5afe623a
data/.circleci/config.yml CHANGED
@@ -28,7 +28,7 @@ jobs:
28
28
  environment:
29
29
  CATALINA_OPTS: "-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"
30
30
  JAVA_OPTIONS: "-Djetty.http.port=8998 -Dfcrepo.dynamic.jms.port=61618 -Dfcrepo.dynamic.stomp.port=61614"
31
- - image: fcrepo/fcrepo:6.4.0
31
+ - image: fcrepo/fcrepo:6.5.1-RC3-tomcat9
32
32
  environment:
33
33
  CATALINA_OPTS: "-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xms512m -Xmx1024m -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true"
34
34
  JAVA_OPTS: "-Djetty.http.port=8978 -Dfcrepo.dynamic.jms.port=61619 -Dfcrepo.dynamic.stomp.port=61615 -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true"
data/.lando.yml CHANGED
@@ -51,7 +51,7 @@ services:
51
51
  volumes:
52
52
  fedora6:
53
53
  services:
54
- image: fcrepo/fcrepo:6.4.0
54
+ image: fcrepo/fcrepo:6.5.1-RC3-tomcat9
55
55
  command:
56
56
  - "catalina.sh"
57
57
  - "run"
data/CHANGELOG.md CHANGED
@@ -1,3 +1,11 @@
1
+ # v3.5.0 2024-12-10
2
+
3
+ * Provides new boolean configuration setting `auto_cast_iso8601_as_datetime` ([dchandekstark](https://github.com/dchandekstark))
4
+ * Align behavior of server managed properties with Fedora. ([dlpierce](https://github.com/dlpierce))
5
+ * Check for nil id to avoid InvalidURIError ([dlpierce](https://github.com/dlpierce))
6
+ * Support Fedora 6.5 ([dlpierce](https://github.com/dlpierce))
7
+ * Make storage adapters report their protocol string ([dlpierce](https://github.com/dlpierce))
8
+
1
9
  # v3.4.0 2024-10-11
2
10
 
3
11
  ## Changes since last release
@@ -105,7 +105,8 @@ module Valkyrie::Persistence::Fedora
105
105
  # @param [Property] value
106
106
  # @return [Boolean]
107
107
  def self.handles?(value)
108
- value.statement.object.to_s.start_with?("http://www.w3.org/ns/ldp", "http://fedora.info")
108
+ value.statement.predicate == RDF.type &&
109
+ value.statement.object.to_s.start_with?('http://www.w3.org/ns/ldp#', 'http://fedora.info/definitions/v4/repository#')
109
110
  end
110
111
 
111
112
  # Provide the NullApplicator Class for any Property in a deny listed namespace
@@ -562,7 +563,7 @@ module Valkyrie::Persistence::Fedora
562
563
  # @return [Array<String>]
563
564
  def denylist
564
565
  [
565
- "http://fedora.info/definitions",
566
+ "http://fedora.info/definitions/v4/repository#",
566
567
  "http://www.iana.org/assignments/relation/last"
567
568
  ]
568
569
  end
@@ -162,6 +162,7 @@ module Valkyrie::Persistence::Fedora
162
162
  # @return [Valkyrie::Resource]
163
163
  # @raise [Valkyrie::Persistence::ObjectNotFoundError]
164
164
  def resource_from_uri(uri)
165
+ raise ::Valkyrie::Persistence::ObjectNotFoundError if uri.nil?
165
166
  resource = Ldp::Resource.for(connection, uri, connection.get(uri))
166
167
  resource_factory.to_resource(object: resource)
167
168
  rescue ::Ldp::Gone, ::Ldp::NotFound
@@ -139,6 +139,7 @@ module Valkyrie::Persistence::Shared
139
139
  # @return [Boolean]
140
140
  # rubocop:disable Metrics/CyclomaticComplexity
141
141
  def self.handles?(value)
142
+ return false unless ::Valkyrie.config.auto_cast_iso8601_as_datetime
142
143
  return false unless value.is_a?(String)
143
144
  return false unless value[4] == "-" && value[10] == "T"
144
145
  year = value.to_s[0..3]
@@ -86,8 +86,13 @@ RSpec.shared_examples 'a Valkyrie query provider' do
86
86
  expect { query_service.find_by(id: Valkyrie::ID.new("123123123")) }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
87
87
  end
88
88
 
89
+ it 'returns a Valkyrie::Persistence::ObjectNotFoundError for an empty string' do
90
+ expect { query_service.find_by(id: '') }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
91
+ end
92
+
89
93
  it 'raises an error if the id is not a Valkyrie::ID or a string' do
90
94
  expect { query_service.find_by(id: 123) }.to raise_error ArgumentError
95
+ expect { query_service.find_by(id: nil) }.to raise_error ArgumentError
91
96
  end
92
97
  end
93
98
 
@@ -117,8 +122,13 @@ RSpec.shared_examples 'a Valkyrie query provider' do
117
122
  expect { query_service.find_by_alternate_identifier(alternate_identifier: Valkyrie::ID.new("123123123")) }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
118
123
  end
119
124
 
125
+ it "raises a Valkyrie::Persistence::ObjectNotFoundError for a non-found alternate identifier" do
126
+ expect { query_service.find_by_alternate_identifier(alternate_identifier: '') }.to raise_error ::Valkyrie::Persistence::ObjectNotFoundError
127
+ end
128
+
120
129
  it 'raises an error if the alternate identifier is not a Valkyrie::ID or a string' do
121
130
  expect { query_service.find_by_alternate_identifier(alternate_identifier: 123) }.to raise_error ArgumentError
131
+ expect { query_service.find_by_alternate_identifier(alternate_identifier: nil) }.to raise_error ArgumentError
122
132
  end
123
133
 
124
134
  it 'can have multiple alternate identifiers' do
@@ -12,6 +12,7 @@ RSpec.shared_examples 'a Valkyrie::StorageAdapter' do
12
12
  Valkyrie::Specs.send(:remove_const, :CustomResource)
13
13
  end
14
14
  subject { storage_adapter }
15
+ it { is_expected.to respond_to(:protocol) }
15
16
  it { is_expected.to respond_to(:handles?).with_keywords(:id) }
16
17
  it { is_expected.to respond_to(:find_by).with_keywords(:id) }
17
18
  it { is_expected.to respond_to(:delete).with_keywords(:id) }
@@ -74,8 +75,9 @@ RSpec.shared_examples 'a Valkyrie::StorageAdapter' do
74
75
  resource = Valkyrie::Specs::CustomResource.new(id: "test#{SecureRandom.uuid}")
75
76
  sha1 = Digest::SHA1.file(file).to_s
76
77
  size = file.size
77
- expect(uploaded_file = storage_adapter.upload(file: file, original_filename: 'foo.jpg', resource: resource, fake_upload_argument: true)).to be_kind_of Valkyrie::StorageAdapter::File
78
+ uploaded_file = storage_adapter.upload(file: file, original_filename: 'foo.jpg', resource: resource, fake_upload_argument: true)
78
79
 
80
+ expect(uploaded_file).to be_kind_of Valkyrie::StorageAdapter::File
79
81
  expect(uploaded_file).to respond_to(:checksum).with_keywords(:digests)
80
82
  expect(uploaded_file).to respond_to(:valid?).with_keywords(:size, :digests)
81
83
  expect(uploaded_file.checksum(digests: [Digest::SHA1.new])).to eq([sha1])
@@ -133,28 +135,42 @@ RSpec.shared_examples 'a Valkyrie::StorageAdapter' do
133
135
  # Deleting a version should leave the current versions
134
136
  if storage_adapter.supports?(:version_deletion)
135
137
  storage_adapter.delete(id: uploaded_file.version_id)
136
- expect(storage_adapter.find_versions(id: uploaded_file.id).length).to eq 1
138
+ remnants = storage_adapter.find_versions(id: uploaded_file.id)
139
+ expect(remnants.length).to eq 1
140
+ expect(remnants.first.version_id).to eq new_version.version_id
137
141
  expect { storage_adapter.find_by(id: uploaded_file.version_id) }.to raise_error Valkyrie::StorageAdapter::FileNotFound
138
142
  end
139
143
  current_length = storage_adapter.find_versions(id: new_version.id).length
140
144
 
141
145
  # Restoring a previous version is just pumping its file into upload_version
142
146
  newest_version = storage_adapter.upload_version(file: new_version, id: new_version.id)
147
+ current_length += 1
143
148
  expect(newest_version.version_id).not_to eq new_version.id
144
149
  expect(storage_adapter.find_by(id: newest_version.id).version_id).to eq newest_version.version_id
145
150
 
146
151
  # I can restore a version twice
147
152
  newest_version = storage_adapter.upload_version(file: new_version, id: new_version.id)
153
+ current_length += 1
148
154
  expect(newest_version.version_id).not_to eq new_version.id
149
155
  expect(storage_adapter.find_by(id: newest_version.id).version_id).to eq newest_version.version_id
150
- expect(storage_adapter.find_versions(id: newest_version.id).length).to eq current_length + 2
156
+ expect(storage_adapter.find_versions(id: newest_version.id).length).to eq current_length
157
+
158
+ # Fedora 6.5 may not create versions when the timestamp is the same?
159
+ # See: https://fedora-repository.atlassian.net/browse/FCREPO-3958
160
+ sleep 1 if storage_adapter.supports?(:list_deleted_versions)
151
161
 
152
162
  # NOTE: We originally wanted deleting the current record to push it into the
153
163
  # versions history, but FCRepo 4/5/6 doesn't work that way, so we changed to
154
164
  # instead make deleting delete everything.
155
165
  storage_adapter.delete(id: new_version.id)
156
166
  expect { storage_adapter.find_by(id: new_version.id) }.to raise_error Valkyrie::StorageAdapter::FileNotFound
157
- expect(storage_adapter.find_versions(id: new_version.id).length).to eq 0
167
+
168
+ if storage_adapter.supports?(:list_deleted_versions)
169
+ expect(storage_adapter.find_versions(id: new_version.id).length).to eq current_length
170
+ else
171
+ expect(storage_adapter.find_versions(id: new_version.id).length).to eq 0
172
+ end
173
+
158
174
  ensure
159
175
  f&.close
160
176
  end
@@ -3,6 +3,8 @@ module Valkyrie::Storage
3
3
  # Implements the DataMapper Pattern to store binary data on disk
4
4
  class Disk
5
5
  attr_reader :base_path, :path_generator, :file_mover
6
+ PROTOCOL = 'disk://'
7
+
6
8
  def initialize(base_path:, path_generator: BucketedStorage, file_mover: FileUtils.method(:mv))
7
9
  @base_path = Pathname.new(base_path.to_s)
8
10
  @path_generator = path_generator.new(base_path: base_path)
@@ -18,13 +20,13 @@ module Valkyrie::Storage
18
20
  new_path = path_generator.generate(resource: resource, file: file, original_filename: original_filename)
19
21
  FileUtils.mkdir_p(new_path.parent)
20
22
  file_mover.call(file.path, new_path)
21
- find_by(id: Valkyrie::ID.new("disk://#{new_path}"))
23
+ find_by(id: Valkyrie::ID.new("#{protocol}#{new_path}"))
22
24
  end
23
25
 
24
26
  # @param id [Valkyrie::ID]
25
27
  # @return [Boolean] true if this adapter can handle this type of identifer
26
28
  def handles?(id:)
27
- id.to_s.start_with?("disk://#{base_path}")
29
+ id.to_s.start_with?("#{protocol}#{base_path}")
28
30
  end
29
31
 
30
32
  # @param feature [Symbol] Feature to test for.
@@ -33,8 +35,13 @@ module Valkyrie::Storage
33
35
  false
34
36
  end
35
37
 
38
+ # @return [String] identifier prefix
39
+ def protocol
40
+ PROTOCOL
41
+ end
42
+
36
43
  def file_path(id)
37
- id.to_s.gsub(/^disk:\/\//, '')
44
+ id.to_s.gsub(/^#{Regexp.escape(protocol)}/, '')
38
45
  end
39
46
 
40
47
  # Return the file associated with the given identifier
@@ -27,7 +27,7 @@ module Valkyrie::Storage
27
27
  # @param id [Valkyrie::ID]
28
28
  # @return [Boolean] true if this adapter can handle this type of identifer
29
29
  def handles?(id:)
30
- id.to_s.start_with?(PROTOCOL)
30
+ id.to_s.start_with?(protocol)
31
31
  end
32
32
 
33
33
  # @param feature [Symbol] Feature to test for.
@@ -36,9 +36,16 @@ module Valkyrie::Storage
36
36
  return true if feature == :versions
37
37
  # Fedora 6 auto versions and you can't delete versions.
38
38
  return true if feature == :version_deletion && fedora_version < 6
39
+ # Fedora 6.5+ lists versions for deleted objects
40
+ return true if feature == :list_deleted_versions && fedora_version >= 6.5
39
41
  false
40
42
  end
41
43
 
44
+ # @return [String] identifier prefix
45
+ def protocol
46
+ PROTOCOL
47
+ end
48
+
42
49
  # Return the file associated with the given identifier
43
50
  # @param id [Valkyrie::ID]
44
51
  # @return [Valkyrie::StorageAdapter::StreamFile]
@@ -61,7 +68,7 @@ module Valkyrie::Storage
61
68
  # Fedora 6 auto versions, so check to see if there's a version for this
62
69
  # initial upload. If not, then mint one (fedora 4/5)
63
70
  version_id = current_version_id(id: valkyrie_identifier(uri: identifier)) || mint_version(identifier, latest_version(identifier))
64
- perform_find(id: Valkyrie::ID.new(identifier.to_s.sub(/^.+\/\//, PROTOCOL)), version_id: version_id)
71
+ perform_find(id: Valkyrie::ID.new(identifier.to_s.sub(/^.+\/\//, protocol)), version_id: version_id)
65
72
  end
66
73
 
67
74
  # @param id [Valkyrie::ID] ID of the Valkyrie::StorageAdapter::StreamFile to
@@ -77,7 +84,7 @@ module Valkyrie::Storage
77
84
  end
78
85
  upload_file(fedora_uri: uri, io: file)
79
86
  version_id = mint_version(uri, latest_version(uri))
80
- perform_find(id: Valkyrie::ID.new(uri.to_s.sub(/^.+\/\//, PROTOCOL)), version_id: version_id)
87
+ perform_find(id: Valkyrie::ID.new(uri.to_s.sub(/^.+\/\//, protocol)), version_id: version_id)
81
88
  end
82
89
 
83
90
  # @param id [Valkyrie::ID]
@@ -88,7 +95,9 @@ module Valkyrie::Storage
88
95
  version_list.map do |version|
89
96
  id = valkyrie_identifier(uri: version["@id"])
90
97
  perform_find(id: id, version_id: id)
91
- end
98
+ rescue Valkyrie::StorageAdapter::FileNotFound
99
+ nil
100
+ end.compact
92
101
  end
93
102
 
94
103
  # Delete the file in Fedora associated with the given identifier.
@@ -197,12 +206,12 @@ module Valkyrie::Storage
197
206
  # Translate the Valkrie ID into a URL for the fedora file
198
207
  # @return [RDF::URI]
199
208
  def fedora_identifier(id:)
200
- identifier = id.to_s.sub(PROTOCOL, "#{connection.http.scheme}://")
209
+ identifier = id.to_s.sub(protocol, "#{connection.http.scheme}://")
201
210
  RDF::URI(identifier)
202
211
  end
203
212
 
204
213
  def valkyrie_identifier(uri:)
205
- id = uri.to_s.sub("http://", PROTOCOL)
214
+ id = uri.to_s.sub("http://", protocol)
206
215
  Valkyrie::ID.new(id)
207
216
  end
208
217
 
@@ -211,7 +220,7 @@ module Valkyrie::Storage
211
220
  # @return [IOProxy]
212
221
  def response(id:)
213
222
  response = connection.http.get(fedora_identifier(id: id))
214
- raise Valkyrie::StorageAdapter::FileNotFound unless response.success?
223
+ raise Valkyrie::StorageAdapter::FileNotFound, "HTTP #{response.status} #{response.body}" unless response.success?
215
224
  IOProxy.new(response.body)
216
225
  end
217
226
 
@@ -6,6 +6,8 @@ module Valkyrie::Storage
6
6
  # in cases where you want to preserve real data
7
7
  class Memory
8
8
  attr_reader :cache
9
+ PROTOCOL = 'memory://'
10
+
9
11
  def initialize
10
12
  @cache = {}
11
13
  end
@@ -16,7 +18,7 @@ module Valkyrie::Storage
16
18
  # @param _extra_arguments [Hash] additional arguments which may be passed to other adapters
17
19
  # @return [Valkyrie::StorageAdapter::StreamFile]
18
20
  def upload(file:, original_filename:, resource: nil, **_extra_arguments)
19
- identifier = Valkyrie::ID.new("memory://#{resource.id}")
21
+ identifier = Valkyrie::ID.new("#{protocol}#{resource.id}")
20
22
  version_id = Valkyrie::ID.new("#{identifier}##{SecureRandom.uuid}")
21
23
  cache[identifier] ||= {}
22
24
  cache[identifier][:current] = Valkyrie::StorageAdapter::StreamFile.new(id: identifier, io: file, version_id: version_id)
@@ -67,7 +69,7 @@ module Valkyrie::Storage
67
69
  # @param id [Valkyrie::ID]
68
70
  # @return [Boolean] true if this adapter can handle this type of identifer
69
71
  def handles?(id:)
70
- id.to_s.start_with?("memory://")
72
+ id.to_s.start_with?(protocol)
71
73
  end
72
74
 
73
75
  # @param feature [Symbol] Feature to test for.
@@ -83,6 +85,11 @@ module Valkyrie::Storage
83
85
  end
84
86
  end
85
87
 
88
+ # @return [String] identifier prefix
89
+ def protocol
90
+ PROTOCOL
91
+ end
92
+
86
93
  def id_and_version(id)
87
94
  id, version = id.to_s.split("#")
88
95
  [Valkyrie::ID.new(id), version]
@@ -7,6 +7,8 @@ module Valkyrie::Storage
7
7
  # with "deletionmarker" in the name of the file.
8
8
  class VersionedDisk
9
9
  attr_reader :base_path, :path_generator, :file_mover
10
+ PROTOCOL = 'versiondisk://'
11
+
10
12
  def initialize(base_path:, path_generator: ::Valkyrie::Storage::Disk::BucketedStorage, file_mover: FileUtils.method(:cp))
11
13
  @base_path = Pathname.new(base_path.to_s)
12
14
  @path_generator = path_generator.new(base_path: base_path)
@@ -26,7 +28,7 @@ module Valkyrie::Storage
26
28
  return sleep(0.001) && upload(file: file, original_filename: original_filename, resource: resource, paused: true, **extra_arguments) if !paused && File.exist?(new_path)
27
29
  FileUtils.mkdir_p(new_path.parent)
28
30
  file_mover.call(file.try(:path) || file.try(:disk_path), new_path)
29
- find_by(id: Valkyrie::ID.new("versiondisk://#{new_path}"))
31
+ find_by(id: Valkyrie::ID.new("#{protocol}#{new_path}"))
30
32
  end
31
33
 
32
34
  def current_timestamp
@@ -50,13 +52,13 @@ module Valkyrie::Storage
50
52
  return sleep(0.001) && upload_version(id: id, file: file, paused: true) if !paused && File.exist?(new_path)
51
53
  FileUtils.mkdir_p(new_path.parent)
52
54
  file_mover.call(file.try(:path) || file.try(:disk_path), new_path)
53
- find_by(id: Valkyrie::ID.new("versiondisk://#{new_path}"))
55
+ find_by(id: Valkyrie::ID.new("#{protocol}#{new_path}"))
54
56
  end
55
57
 
56
58
  # @param id [Valkyrie::ID]
57
59
  # @return [Boolean] true if this adapter can handle this type of identifer
58
60
  def handles?(id:)
59
- id.to_s.start_with?("versiondisk://#{base_path}")
61
+ id.to_s.start_with?("#{protocol}#{base_path}")
60
62
  end
61
63
 
62
64
  # @param feature [Symbol] Feature to test for.
@@ -66,6 +68,11 @@ module Valkyrie::Storage
66
68
  false
67
69
  end
68
70
 
71
+ # @return [String] identifier prefix
72
+ def protocol
73
+ PROTOCOL
74
+ end
75
+
69
76
  # Return the file associated with the given identifier
70
77
  # @param id [Valkyrie::ID]
71
78
  # @return [Valkyrie::StorageAdapter::File]
@@ -95,7 +102,7 @@ module Valkyrie::Storage
95
102
  # @return [Array<Valkyrie::StorageAdapter::File>]
96
103
  def find_versions(id:)
97
104
  version_files(id: id).select { |x| !x.to_s.include?("deletionmarker") }.map do |file|
98
- find_by(id: Valkyrie::ID.new("versiondisk://#{file}"))
105
+ find_by(id: Valkyrie::ID.new("#{protocol}#{file}"))
99
106
  end
100
107
  end
101
108
 
@@ -106,7 +113,7 @@ module Valkyrie::Storage
106
113
  end
107
114
 
108
115
  def file_path(version_id)
109
- version_id.to_s.gsub(/^versiondisk:\/\//, '')
116
+ version_id.to_s.gsub(/^#{Regexp.escape(protocol)}/, '')
110
117
  end
111
118
 
112
119
  # @return VersionId A VersionId value that's resolved a current reference,
@@ -128,6 +135,10 @@ module Valkyrie::Storage
128
135
  @id = id
129
136
  end
130
137
 
138
+ def protocol
139
+ PROTOCOL
140
+ end
141
+
131
142
  def current_reference_id
132
143
  self.class.new(Valkyrie::ID.new(string_id.gsub(version, "current")))
133
144
  end
@@ -139,13 +150,13 @@ module Valkyrie::Storage
139
150
  end
140
151
 
141
152
  def file_path
142
- @file_path ||= string_id.gsub(/^versiondisk:\/\//, '')
153
+ @file_path ||= string_id.gsub(/^#{Regexp.escape(protocol)}/, '')
143
154
  end
144
155
 
145
156
  def version_files
146
157
  root = Pathname.new(file_path)
147
158
  root.parent.children.select { |file| file.basename.to_s.end_with?(filename) }.sort.reverse.map do |file|
148
- VersionId.new(Valkyrie::ID.new("versiondisk://#{file}"))
159
+ VersionId.new(Valkyrie::ID.new("#{protocol}#{file}"))
149
160
  end
150
161
  end
151
162
 
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module Valkyrie
3
- VERSION = "3.4.0"
3
+ VERSION = "3.5.0"
4
4
  end
data/lib/valkyrie.rb CHANGED
@@ -101,6 +101,10 @@ module Valkyrie
101
101
  self[:index_tsim_only_threshold].to_i
102
102
  end
103
103
 
104
+ def auto_cast_iso8601_as_datetime
105
+ self[:auto_cast_iso8601_as_datetime]
106
+ end
107
+
104
108
  # @api public
105
109
  #
106
110
  # The returned anonymous method (e.g. responds to #call) has a signature of
@@ -123,7 +127,8 @@ module Valkyrie
123
127
  def defaults
124
128
  {
125
129
  resource_class_resolver: method(:default_resource_class_resolver),
126
- index_tsim_only_threshold: 1000
130
+ index_tsim_only_threshold: 1000,
131
+ auto_cast_iso8601_as_datetime: true
127
132
  }
128
133
  end
129
134
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: valkyrie
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Trey Pendragon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-10-11 00:00:00.000000000 Z
11
+ date: 2024-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-struct