cocina-models 0.92.0 → 0.93.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 +4 -4
- data/Gemfile.lock +2 -2
- data/lib/cocina/models/file.rb +2 -2
- data/lib/cocina/models/file_use.rb +7 -0
- data/lib/cocina/models/language_tag.rb +7 -0
- data/lib/cocina/models/request_file.rb +4 -2
- data/lib/cocina/models/validators/dark_validator.rb +1 -6
- data/lib/cocina/models/validators/description_values_validator.rb +15 -8
- data/lib/cocina/models/validators/language_tag_validator.rb +35 -9
- data/lib/cocina/models/version.rb +1 -1
- data/openapi.yml +12 -6
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9cf74f9126fce8106b3bfd5964c11731c460546a4f457da9ba7f35f895243c7a
|
4
|
+
data.tar.gz: 58467364ec8a96eac4f6d335dce400c0086833830f5704e263bae7365741d473
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2106344f663362d1609f5e40daf001c43f976abbbe7ae8a43c52295b2a2e280952c7d6d01b6f6b4cbdf124a07c26372bdfc17f9a903cce666edc39ba3b3db35
|
7
|
+
data.tar.gz: 5675d10901a099d8869baed51c4bdb82608305053d0e830130c28577644daddf73a650410cb20425e4e27ff4dfc60188f0e2cb0b77954c49bd3f00980ee56cf1
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
cocina-models (0.
|
4
|
+
cocina-models (0.93.0)
|
5
5
|
activesupport
|
6
6
|
deprecation
|
7
7
|
dry-struct (~> 1.0)
|
@@ -97,7 +97,7 @@ GEM
|
|
97
97
|
racc
|
98
98
|
patience_diff (1.2.0)
|
99
99
|
optimist (~> 3.0)
|
100
|
-
racc (1.7.
|
100
|
+
racc (1.7.3)
|
101
101
|
rack (3.0.8)
|
102
102
|
rainbow (3.1.1)
|
103
103
|
rake (13.1.0)
|
data/lib/cocina/models/file.rb
CHANGED
@@ -23,9 +23,9 @@ module Cocina
|
|
23
23
|
# MIME Type of the File.
|
24
24
|
attribute? :hasMimeType, Types::Strict::String
|
25
25
|
# BCP 47 language tag: https://www.rfc-editor.org/rfc/rfc4646.txt -- other applications (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang
|
26
|
-
attribute? :languageTag,
|
26
|
+
attribute? :languageTag, LanguageTag.optional
|
27
27
|
# Use for the File.
|
28
|
-
attribute? :use,
|
28
|
+
attribute? :use, FileUse.optional
|
29
29
|
attribute :hasMessageDigests, Types::Strict::Array.of(MessageDigest).default([].freeze)
|
30
30
|
attribute(:access, FileAccess.default { FileAccess.new })
|
31
31
|
attribute(:administrative, FileAdministrative.default { FileAdministrative.new })
|
@@ -13,9 +13,11 @@ module Cocina
|
|
13
13
|
attribute? :size, Types::Strict::Integer
|
14
14
|
attribute :version, Types::Strict::Integer
|
15
15
|
attribute? :hasMimeType, Types::Strict::String
|
16
|
-
|
16
|
+
# BCP 47 language tag: https://www.rfc-editor.org/rfc/rfc4646.txt -- other applications (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang
|
17
|
+
attribute? :languageTag, LanguageTag.optional
|
17
18
|
attribute? :externalIdentifier, Types::Strict::String
|
18
|
-
|
19
|
+
# Use for the File.
|
20
|
+
attribute? :use, FileUse.optional
|
19
21
|
attribute :hasMessageDigests, Types::Strict::Array.of(MessageDigest).default([].freeze)
|
20
22
|
attribute(:access, FileAccess.default { FileAccess.new })
|
21
23
|
attribute(:administrative, FileAdministrative.default { FileAdministrative.new })
|
@@ -39,12 +39,7 @@ module Cocina
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def invalid_files
|
42
|
-
@invalid_files ||=
|
43
|
-
[].tap do |invalid_files|
|
44
|
-
files.each do |file|
|
45
|
-
invalid_files << file if invalid?(file)
|
46
|
-
end
|
47
|
-
end
|
42
|
+
@invalid_files ||= files.select { |file| invalid?(file) }
|
48
43
|
end
|
49
44
|
|
50
45
|
def invalid_filenames
|
@@ -12,7 +12,8 @@ module Cocina
|
|
12
12
|
def initialize(clazz, attributes)
|
13
13
|
@clazz = clazz
|
14
14
|
@attributes = attributes
|
15
|
-
@
|
15
|
+
@error_paths_multiple = []
|
16
|
+
@error_paths_blank = []
|
16
17
|
end
|
17
18
|
|
18
19
|
def validate
|
@@ -20,21 +21,21 @@ module Cocina
|
|
20
21
|
|
21
22
|
validate_obj(attributes, [])
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
raise ValidationError, "Multiple value, groupedValue, structuredValue, and parallelValue in description: #{error_paths.join(', ')}"
|
24
|
+
raise ValidationError, "Multiple value, groupedValue, structuredValue, and parallelValue in description: #{error_paths_multiple.join(', ')}" unless error_paths_multiple.empty?
|
25
|
+
raise ValidationError, "Blank value in description: #{error_paths_blank.join(', ')}" unless error_paths_blank.empty?
|
26
26
|
end
|
27
27
|
|
28
28
|
private
|
29
29
|
|
30
|
-
attr_reader :clazz, :attributes, :
|
30
|
+
attr_reader :clazz, :attributes, :error_paths_blank, :error_paths_multiple
|
31
31
|
|
32
32
|
def meets_preconditions?
|
33
33
|
[Cocina::Models::Description, Cocina::Models::RequestDescription].include?(clazz)
|
34
34
|
end
|
35
35
|
|
36
36
|
def validate_hash(hash, path)
|
37
|
-
|
37
|
+
validate_values_for_blanks(hash, path)
|
38
|
+
validate_values_for_multiples(hash, path)
|
38
39
|
hash.each do |key, obj|
|
39
40
|
validate_obj(obj, path + [key])
|
40
41
|
end
|
@@ -51,10 +52,16 @@ module Cocina
|
|
51
52
|
validate_array(obj, path) if obj.is_a?(Array)
|
52
53
|
end
|
53
54
|
|
54
|
-
def
|
55
|
+
def validate_values_for_blanks(hash, path)
|
56
|
+
return unless hash[:value] && hash[:value].is_a?(String) && /\A\s+\z/.match?(hash[:value]) # rubocop:disable Style/SafeNavigation
|
57
|
+
|
58
|
+
error_paths_blank << path_to_s(path)
|
59
|
+
end
|
60
|
+
|
61
|
+
def validate_values_for_multiples(hash, path)
|
55
62
|
return unless hash.count { |key, value| %i[value groupedValue structuredValue parallelValue].include?(key) && value.present? } > 1
|
56
63
|
|
57
|
-
|
64
|
+
error_paths_multiple << path_to_s(path)
|
58
65
|
end
|
59
66
|
|
60
67
|
def path_to_s(path)
|
@@ -17,10 +17,10 @@ module Cocina
|
|
17
17
|
def validate
|
18
18
|
return unless meets_preconditions?
|
19
19
|
|
20
|
-
return if
|
20
|
+
return if invalid_files.empty?
|
21
21
|
|
22
|
-
raise ValidationError, '
|
23
|
-
"#{
|
22
|
+
raise ValidationError, 'Some files have invalid language tags according to RFC 4646: ' \
|
23
|
+
"#{invalid_filenames_with_language_tags.join(', ')}"
|
24
24
|
end
|
25
25
|
|
26
26
|
private
|
@@ -28,19 +28,45 @@ module Cocina
|
|
28
28
|
attr_reader :clazz, :attributes
|
29
29
|
|
30
30
|
def meets_preconditions?
|
31
|
-
|
31
|
+
dro?
|
32
32
|
end
|
33
33
|
|
34
|
-
def
|
35
|
-
(clazz::TYPES &
|
34
|
+
def dro?
|
35
|
+
(clazz::TYPES & DRO::TYPES).any?
|
36
36
|
rescue NameError
|
37
37
|
false
|
38
38
|
end
|
39
39
|
|
40
|
-
def valid_language_tag?
|
41
|
-
|
40
|
+
def valid_language_tag?(file)
|
41
|
+
# I18n::Locale::Tag::Rfc4646.tag will return an instance of I18n::Locale::Tag::Rfc4646 (with fields like language, script,
|
42
|
+
# region) for strings that can be parsed according to RFC 4646, and nil for strings that do not conform to the spec.
|
43
|
+
I18n::Locale::Tag::Rfc4646.tag(file[:languageTag]).present?
|
44
|
+
end
|
45
|
+
|
46
|
+
def invalid_files
|
47
|
+
@invalid_files ||= language_tag_files.reject { |file| valid_language_tag?(file) }
|
48
|
+
end
|
49
|
+
|
50
|
+
def invalid_filenames_with_language_tags
|
51
|
+
invalid_files.map { |invalid_file| "#{invalid_file[:filename] || invalid_file[:label]} (#{invalid_file[:languageTag]})" }
|
52
|
+
end
|
53
|
+
|
54
|
+
def language_tag_files
|
55
|
+
files.select { |file| file[:languageTag].present? }
|
56
|
+
end
|
57
|
+
|
58
|
+
def files
|
59
|
+
[].tap do |files|
|
60
|
+
next if attributes.dig(:structural, :contains).nil?
|
61
|
+
|
62
|
+
attributes[:structural][:contains].each do |fileset|
|
63
|
+
next if fileset.dig(:structural, :contains).nil?
|
42
64
|
|
43
|
-
|
65
|
+
fileset[:structural][:contains].each do |file|
|
66
|
+
files << file
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
44
70
|
end
|
45
71
|
end
|
46
72
|
end
|
data/openapi.yml
CHANGED
@@ -1045,11 +1045,9 @@ components:
|
|
1045
1045
|
description: MIME Type of the File.
|
1046
1046
|
type: string
|
1047
1047
|
languageTag:
|
1048
|
-
|
1049
|
-
type: string
|
1048
|
+
$ref: '#/components/schemas/LanguageTag'
|
1050
1049
|
use:
|
1051
|
-
|
1052
|
-
type: string
|
1050
|
+
$ref: '#/components/schemas/FileUse'
|
1053
1051
|
hasMessageDigests:
|
1054
1052
|
type: array
|
1055
1053
|
items:
|
@@ -1144,6 +1142,10 @@ components:
|
|
1144
1142
|
type: array
|
1145
1143
|
items:
|
1146
1144
|
$ref: '#/components/schemas/File'
|
1145
|
+
FileUse:
|
1146
|
+
description: Use for the File.
|
1147
|
+
type: string
|
1148
|
+
nullable: true
|
1147
1149
|
FolioCatalogLink:
|
1148
1150
|
description: A linkage between an object and a Folio catalog record
|
1149
1151
|
type: object
|
@@ -1272,6 +1274,10 @@ components:
|
|
1272
1274
|
valueLanguage:
|
1273
1275
|
# description: present for mapping to additional schemas in the future and for consistency but not otherwise used
|
1274
1276
|
$ref: "#/components/schemas/DescriptiveValueLanguage"
|
1277
|
+
LanguageTag:
|
1278
|
+
description: "BCP 47 language tag: https://www.rfc-editor.org/rfc/rfc4646.txt -- other applications (like media players) expect language codes of this format, see e.g. https://videojs.com/guides/text-tracks/#srclang"
|
1279
|
+
type: string
|
1280
|
+
nullable: true
|
1275
1281
|
License:
|
1276
1282
|
description: The license governing reuse of the DRO. Should be an IRI for known licenses (i.e. CC, RightsStatement.org URI, etc.).
|
1277
1283
|
type: string
|
@@ -1779,11 +1785,11 @@ components:
|
|
1779
1785
|
hasMimeType:
|
1780
1786
|
type: string
|
1781
1787
|
languageTag:
|
1782
|
-
|
1788
|
+
$ref: '#/components/schemas/LanguageTag'
|
1783
1789
|
externalIdentifier:
|
1784
1790
|
type: string
|
1785
1791
|
use:
|
1786
|
-
|
1792
|
+
$ref: '#/components/schemas/FileUse'
|
1787
1793
|
hasMessageDigests:
|
1788
1794
|
type: array
|
1789
1795
|
items:
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocina-models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.93.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-11-
|
11
|
+
date: 2023-11-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -429,11 +429,13 @@ files:
|
|
429
429
|
- lib/cocina/models/file_set.rb
|
430
430
|
- lib/cocina/models/file_set_structural.rb
|
431
431
|
- lib/cocina/models/file_set_type.rb
|
432
|
+
- lib/cocina/models/file_use.rb
|
432
433
|
- lib/cocina/models/folio_catalog_link.rb
|
433
434
|
- lib/cocina/models/geographic.rb
|
434
435
|
- lib/cocina/models/identification.rb
|
435
436
|
- lib/cocina/models/lane_medical_barcode.rb
|
436
437
|
- lib/cocina/models/language.rb
|
438
|
+
- lib/cocina/models/language_tag.rb
|
437
439
|
- lib/cocina/models/license.rb
|
438
440
|
- lib/cocina/models/location_based_access.rb
|
439
441
|
- lib/cocina/models/location_based_download_access.rb
|