cocina-models 0.130.0 → 0.132.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: f094501e516f4a68db47da8fa1d78685b3f9d8b43cfabad11deaf1a8929e5601
4
- data.tar.gz: 41a9862bc8297a71d1588705cf1e34296ef65af73225c166688085b87fc032b7
3
+ metadata.gz: 6a61867c1ae0703869cce27ced15c5698d5e4e93b5792e6e1ae559ca55965d39
4
+ data.tar.gz: e091f101f3922c69833aca4117f4d8d011f55d0959e2463e8f151bf1ba6f8d6a
5
5
  SHA512:
6
- metadata.gz: 610982303cca76efa71946ae82436290a2df7611e8933311f96e8532c82093785470ec109c914b241a199781e58b0e0c9462d0c5f11c1f614975ccce8f0830e6
7
- data.tar.gz: ba4ccb6d865668f67e3a163a16c21bf2f4b190bca8cf7b91adf1931a976ef3dd8a17609f95afce59eaa6522d694e3a77eb9d8b006c7bced789406c8dee44bd3c
6
+ metadata.gz: b8b8e322eeed3c9a59831ef76a664c79cd6438224e4ec92de4448c9da17ea10c20874758fd968e270523ceb13acce529cc6b13e596b925b05aac77ba93accfa9
7
+ data.tar.gz: bace81574ac19ed81b453caeec3530c940e1c4bc41d94e316726ea5f42092092363e0c4138fb51fe693732af3f74db5bea5b629f0ab5a60b1db57cf3ca05c802
data/.gitignore CHANGED
@@ -10,7 +10,8 @@
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
12
 
13
+ *.jsonl.zst
13
14
  *.jq.txt
14
15
  *.jsonl.xz
15
16
  *.csv
16
- *-playground.html
17
+ *-playground.html
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.130.0)
4
+ cocina-models (0.132.0)
5
5
  activesupport
6
6
  cocina_display
7
7
  deprecation
@@ -47,7 +47,7 @@ GEM
47
47
  zeitwerk (~> 2.7)
48
48
  concurrent-ruby (1.3.8)
49
49
  connection_pool (3.0.2)
50
- csv (3.3.5)
50
+ csv (3.3.6)
51
51
  debug (1.11.1)
52
52
  irb (~> 1.10)
53
53
  reline (>= 0.3.8)
@@ -101,9 +101,9 @@ GEM
101
101
  iso8601 (0.13.0)
102
102
  janeway-jsonpath (1.0.0)
103
103
  json (2.21.1)
104
- jsonschema_rs (0.48.1-arm64-darwin)
104
+ jsonschema_rs (0.49.1-arm64-darwin)
105
105
  bigdecimal (>= 3.1, < 5)
106
- jsonschema_rs (0.48.1-x86_64-linux)
106
+ jsonschema_rs (0.49.1-x86_64-linux)
107
107
  bigdecimal (>= 3.1, < 5)
108
108
  language_server-protocol (3.17.0.6)
109
109
  lint_roller (1.1.0)
@@ -131,7 +131,7 @@ GEM
131
131
  racc (1.8.1)
132
132
  rainbow (3.1.1)
133
133
  rake (13.4.2)
134
- rbs (4.0.3)
134
+ rbs (4.1.0)
135
135
  logger
136
136
  prism (>= 1.6.0)
137
137
  tsort
@@ -184,7 +184,7 @@ GEM
184
184
  rubocop (~> 1.86, >= 1.86.2)
185
185
  ruby-progressbar (1.13.0)
186
186
  securerandom (0.4.1)
187
- simplecov (1.0.2)
187
+ simplecov (1.0.3)
188
188
  super_diff (0.19.0)
189
189
  attr_extras (>= 6.2.4, < 8)
190
190
  diff-lcs (~> 1.5)
@@ -225,12 +225,12 @@ CHECKSUMS
225
225
  base64 (0.3.0) sha256=27337aeabad6ffae05c265c450490628ef3ebd4b67be58257393227588f5a97b
226
226
  bigdecimal (4.1.2) sha256=53d217666027eab4280346fba98e7d5b66baaae1b9c3c1c0ffe89d48188a3fbd
227
227
  builder (3.3.0) sha256=497918d2f9dca528fdca4b88d84e4ef4387256d984b8154e9d5d3fe5a9c8835f
228
- bundler (4.0.16) sha256=d6ca5dd440c24f9abce9844cf44cc8e18c6a553de65a47efb4544137af92c47d
229
- cocina-models (0.130.0)
228
+ bundler (4.0.17) sha256=214e21431b5665dd2f99df8a5511c6b151d7a72e8015c8b38f8b775b61cbb6c1
229
+ cocina-models (0.132.0)
230
230
  cocina_display (2.9.0) sha256=00e97cf826dafd5c547ca87b58e55f1d3bfa68fa4ddcddbbe25b4d9d9ed05d8f
231
231
  concurrent-ruby (1.3.8) sha256=b2f1be836e968ccc78ccfce277ea79c72a88633f22306782c16ff23fb415d1e1
232
232
  connection_pool (3.0.2) sha256=33fff5ba71a12d2aa26cb72b1db8bba2a1a01823559fb01d29eb74c286e62e0a
233
- csv (3.3.5) sha256=6e5134ac3383ef728b7f02725d9872934f523cb40b961479f69cf3afa6c8e73f
233
+ csv (3.3.6) sha256=aba61e7e507a66f03d45cb1f3c4b6359861c3504038b422962875dce099e4456
234
234
  debug (1.11.1) sha256=2e0b0ac6119f2207a6f8ac7d4a73ca8eb4e440f64da0a3136c30343146e952b6
235
235
  deprecation (1.1.0) sha256=01707cea9a6ed2d7270377457941f43394a345e6dd8048e1be6d18ff2f2a01e1
236
236
  diff-lcs (1.6.2) sha256=9ae0d2cba7d4df3075fe8cd8602a8604993efc0dfa934cff568969efb1909962
@@ -253,8 +253,8 @@ CHECKSUMS
253
253
  iso8601 (0.13.0) sha256=298c2b15b7be5fa95a1372813d36a2257656cd8e906dfbc1f5cb409851425aa2
254
254
  janeway-jsonpath (1.0.0) sha256=c8293f009f2aea9487ddee3067ca735a1f758eb1c8834ff4fab3ffd06c56d0a3
255
255
  json (2.21.1) sha256=13a43df75d95641443f5702dff350f237164a9d811ff0f2c2800d4d980220583
256
- jsonschema_rs (0.48.1-arm64-darwin) sha256=9159986e47c5fe4a169060c46adb0addfc5229bfcb44052d9f0b90071d1ab28b
257
- jsonschema_rs (0.48.1-x86_64-linux) sha256=efbc173c13f982ba1a2396ee9c781016837c5797338ac1e0f8e765a23bf8ab58
256
+ jsonschema_rs (0.49.1-arm64-darwin) sha256=1c3a72c95f60e6c1dad6873b206eebaaa57ac947049675d0504bddc79be6db67
257
+ jsonschema_rs (0.49.1-x86_64-linux) sha256=de9c96bc0d68f818b1dd59fba09d954a13e02deaf2121aef803ad9c47dc3204b
258
258
  language_server-protocol (3.17.0.6) sha256=5ef2c0c138f8267e1bc631d3328347d354f96724b0af22f2c79516120443b7f0
259
259
  lint_roller (1.1.0) sha256=2c0c845b632a7d172cb849cc90c1bce937a28c5c8ccccb50dfd46a485003cc87
260
260
  logger (1.7.0) sha256=196edec7cc44b66cfb40f9755ce11b392f21f7967696af15d274dde7edff0203
@@ -272,7 +272,7 @@ CHECKSUMS
272
272
  racc (1.8.1) sha256=4a7f6929691dbec8b5209a0b373bc2614882b55fc5d2e447a21aaa691303d62f
273
273
  rainbow (3.1.1) sha256=039491aa3a89f42efa1d6dec2fc4e62ede96eb6acd95e52f1ad581182b79bc6a
274
274
  rake (13.4.2) sha256=cb825b2bd5f1f8e91ca37bddb4b9aaf345551b4731da62949be002fa89283701
275
- rbs (4.0.3) sha256=5a7bf70e2628549d9a1f44eae447b2cfe55968a9c60cfff52693a4bdcc020e14
275
+ rbs (4.1.0) sha256=8baba59008b0643b4ba2090e9b1d0149655b0bbd42eb2ffe42b1d0eb6923fd72
276
276
  rdoc (8.0.0) sha256=03bf8c08a9639658855a0cfd77c0abca8325c227693f7f33f82957811348c469
277
277
  regexp_parser (2.12.0) sha256=35a916a1d63190ab5c9009457136ae5f3c0c7512d60291d0d1378ba18ce08ebb
278
278
  reline (0.6.3) sha256=1198b04973565b36ec0f11542ab3f5cfeeec34823f4e54cebde90968092b1835
@@ -289,7 +289,7 @@ CHECKSUMS
289
289
  rubocop-rspec (3.10.2) sha256=0b3e2ecc592cd10ecbf0095bb58d1e357905276e069643523cc19eb7495f65e2
290
290
  ruby-progressbar (1.13.0) sha256=80fc9c47a9b640d6834e0dc7b3c94c9df37f08cb072b7761e4a71e22cff29b33
291
291
  securerandom (0.4.1) sha256=cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1
292
- simplecov (1.0.2) sha256=c6459434efe4b948b46477cc2df2faa73ab365f83a33c7c17f81262f4f7f1244
292
+ simplecov (1.0.3) sha256=38ef0514f16ae7562f0d0f4df02610071115103d301b6de7dacbcc000082e39b
293
293
  super_diff (0.19.0) sha256=c35fc1c0daa223d67b203fe3fb49a6cfd67850a53920319565c3c654e03ec902
294
294
  thor (1.5.0) sha256=e3a9e55fe857e44859ce104a84675ab6e8cd59c650a49106a05f55f136425e73
295
295
  tsort (0.2.0) sha256=9650a793f6859a43b6641671278f79cfead60ac714148aabe4e3f0060480089f
@@ -300,4 +300,4 @@ CHECKSUMS
300
300
  zeitwerk (2.8.2) sha256=7212a61311083c604184b1ea2574b9aa05cd14f855a0841c06985cabe9181d12
301
301
 
302
302
  BUNDLED WITH
303
- 4.0.16
303
+ 4.0.17
data/README.md CHANGED
@@ -62,7 +62,7 @@ Beyond what is necessary to test the generator, the Cocina model classes are not
62
62
 
63
63
  ## Testing validation changes
64
64
 
65
- If there is a possibility that a model, mapping, or validation change will conflict with some existing objects then `bin/validate-data` should be used for testing. This operates on an export of objects from the repository and reports any validation errors. You may get the file by running the script [bin/export-cocina-head-versions](https://github.com/sul-dlss/dor-services-app#export-cocina-json-data) and downloading the data file to your computer. See the [DSA README](https://github.com/sul-dlss/dor-services-app#scheduled-cocina-json-data-exports) for more info about the files and locations. Running a full validation takes about 2 hours.
65
+ If there is a possibility that a model, mapping, or validation change will conflict with some existing objects then `bin/validate-data` should be used for testing. This operates on an export of objects from the repository and reports any validation errors. You may get the file by running the script [bin/export-cocina-head-versions](https://github.com/sul-dlss/dor-services-app#export-cocina-json-data) and downloading the data file to your computer. See the [DSA README](https://github.com/sul-dlss/dor-services-app#scheduled-cocina-json-data-exports) for more info about the files and locations. Running a full validation takes about 2 hours.
66
66
 
67
67
 
68
68
  Alternatively, you can use [validate-cocina](https://github.com/sul-dlss/dor-services-app/blob/main/bin/validate-cocina) for testing. This must be run on the `sdr-infra` VM since it requires deploying a branch of cocina-models. It is slower than using `bin/validate-data`, but all of the data is completely up to date.
@@ -70,7 +70,8 @@ Alternatively, you can use [validate-cocina](https://github.com/sul-dlss/dor-ser
70
70
  For background on object validation, as it relates to migrating versions, see: https://github.com/sul-dlss/dor-services-app/wiki/Migrating-Cocina
71
71
 
72
72
  1. Create a cocina-models branch containing the proposed change and push to GitHub.
73
- 2. On the `sdr-infra` VM, while logged in as the `deploy` user, check out `main`, update the `Gemfile` so that cocina-models references the branch, and `bundle install`.
73
+ 2. On the `sdr-infra` VM, while logged in as the `deploy` user, check out `main`, update the `Gemfile` so that cocina-models references the branch, and `bundle install`, e.g.
74
+ gem 'cocina-models', git: 'https://github.com/sul-dlss/cocina-models', branch: 'my-branch'
74
75
  3. Select the appropriate environment vars below - they are set to values in puppet. (first 2 lines are the same; last two lines use different variables)
75
76
 
76
77
  For QA:
@@ -109,6 +110,11 @@ export RUBYOPT='-W:no-deprecated -W:no-experimental'
109
110
  RAILS_ENV=production bin/validate-cocina -p 8 -l
110
111
  ```
111
112
 
113
+ To run against only a specific list of druids, pass in a CSV file with druids in the first column and no header (druids should have the "druid:" prefix). This matches the format that comes from the `bin/validate-data` script in cocina-models repo, so you can the use the CSV file and re-run against just those objects once they have been remediated.
114
+ ```
115
+ RAILS_ENV=production bin/validate-cocina -f validate-data-errors.csv
116
+ ```
117
+
112
118
  5. Check `validate-cocina.csv` for validation errors.
113
119
 
114
120
  ## Running Reports in DSA
@@ -0,0 +1,15 @@
1
+ # Language Code and Term Source Codes
2
+ # Source: https://www.loc.gov/standards/sourcelist/language.html
3
+ - austlang
4
+ - din2335
5
+ - glotto
6
+ - iso639-1
7
+ - iso639-2b
8
+ - iso639-3
9
+ - iso639-5
10
+ - knia
11
+ - lrwl
12
+ - rfc3066
13
+ - rfc4646
14
+ - rfc5646
15
+ - walso
@@ -15,11 +15,10 @@ module Cocina
15
15
  attribute :type, Types::Strict::String.enum(*AdminPolicy::TYPES)
16
16
  # example: druid:bc123df4567
17
17
  attribute :externalIdentifier, Druid
18
- attribute? :label, Types::Strict::String.default('')
19
18
  attribute :version, Types::Strict::Integer
20
19
  # Administrative properties for an AdminPolicy
21
20
  attribute(:administrative, AdminPolicyAdministrative.default { AdminPolicyAdministrative.new })
22
- attribute? :description, Description.optional
21
+ attribute(:description, Description.default { Description.new })
23
22
  end
24
23
  end
25
24
  end
@@ -13,7 +13,6 @@ module Cocina
13
13
  attribute :type, Types::Strict::String.enum(*AdminPolicyLite::TYPES)
14
14
  # example: druid:bc123df4567
15
15
  attribute :externalIdentifier, Druid
16
- attribute? :label, Types::Strict::String.default('')
17
16
  attribute :version, Types::Strict::Integer
18
17
  # Administrative properties for an AdminPolicy
19
18
  # Validation of this property is relaxed. See the schema.json for full validation.
@@ -16,11 +16,10 @@ module Cocina
16
16
  attribute :type, Types::Strict::String.enum(*AdminPolicyWithMetadata::TYPES)
17
17
  # example: druid:bc123df4567
18
18
  attribute :externalIdentifier, Druid
19
- attribute? :label, Types::Strict::String.default('')
20
19
  attribute :version, Types::Strict::Integer
21
20
  # Administrative properties for an AdminPolicy
22
21
  attribute(:administrative, AdminPolicyAdministrative.default { AdminPolicyAdministrative.new })
23
- attribute? :description, Description.optional
22
+ attribute(:description, Description.default { Description.new })
24
23
  # When the object was created.
25
24
  attribute? :created, Types::Params::DateTime
26
25
  # When the object was modified.
@@ -22,8 +22,6 @@ module Cocina
22
22
  attribute :type, Types::Strict::String.enum(*Collection::TYPES)
23
23
  # example: druid:bc123df4567
24
24
  attribute :externalIdentifier, Druid
25
- # Primary processing label (can be same as title) for a Collection.
26
- attribute? :label, Types::Strict::String.default('')
27
25
  # Version for the Collection within SDR.
28
26
  attribute :version, Types::Strict::Integer
29
27
  # Access metadata for collections
@@ -20,8 +20,6 @@ module Cocina
20
20
  attribute :type, Types::Strict::String.enum(*CollectionLite::TYPES)
21
21
  # example: druid:bc123df4567
22
22
  attribute :externalIdentifier, Druid
23
- # Primary processing label (can be same as title) for a Collection.
24
- attribute? :label, Types::Strict::String.default('')
25
23
  # Version for the Collection within SDR.
26
24
  attribute :version, Types::Strict::Integer
27
25
  # Access metadata for collections
@@ -21,8 +21,6 @@ module Cocina
21
21
  attribute :type, Types::Strict::String.enum(*CollectionWithMetadata::TYPES)
22
22
  # example: druid:bc123df4567
23
23
  attribute :externalIdentifier, Druid
24
- # Primary processing label (can be same as title) for a Collection.
25
- attribute? :label, Types::Strict::String.default('')
26
24
  # Version for the Collection within SDR.
27
25
  attribute :version, Types::Strict::Integer
28
26
  # Access metadata for collections
@@ -32,8 +32,6 @@ module Cocina
32
32
  attribute :type, Types::Strict::String.enum(*DRO::TYPES)
33
33
  # example: druid:bc123df4567
34
34
  attribute :externalIdentifier, Druid
35
- # Primary processing label (can be same as title) for a DRO.
36
- attribute? :label, Types::Strict::String.default('')
37
35
  # Version for the DRO within SDR.
38
36
  attribute :version, Types::Strict::Integer
39
37
  attribute(:access, DROAccess.default { DROAccess.new })
@@ -30,8 +30,6 @@ module Cocina
30
30
  attribute :type, Types::Strict::String.enum(*DROLite::TYPES)
31
31
  # example: druid:bc123df4567
32
32
  attribute :externalIdentifier, Druid
33
- # Primary processing label (can be same as title) for a DRO.
34
- attribute? :label, Types::Strict::String.default('')
35
33
  # Version for the DRO within SDR.
36
34
  attribute :version, Types::Strict::Integer
37
35
  # Validation of this property is relaxed. See the schema.json for full validation.
@@ -31,8 +31,6 @@ module Cocina
31
31
  attribute :type, Types::Strict::String.enum(*DROWithMetadata::TYPES)
32
32
  # example: druid:bc123df4567
33
33
  attribute :externalIdentifier, Druid
34
- # Primary processing label (can be same as title) for a DRO.
35
- attribute? :label, Types::Strict::String.default('')
36
34
  # Version for the DRO within SDR.
37
35
  attribute :version, Types::Strict::Integer
38
36
  attribute(:access, DROAccess.default { DROAccess.new })
@@ -11,20 +11,18 @@ module Cocina
11
11
 
12
12
  # @param [Nokogiri::XML] mods
13
13
  # @param [String] druid
14
- # @oaram [String] label
15
14
  # @param [TitleBuilder] title_builder - defaults to Title class
16
15
  # @param [Cocina::Models::Mapping::ErrorNotifier] notifier
17
16
  # @return [Hash] a hash that can be mapped to a cocina descriptive model
18
- def self.props(mods:, druid:, label:, title_builder: Title, notifier: nil)
19
- new(title_builder: title_builder, mods: mods, druid: druid, label: label, notifier: notifier).props
17
+ def self.props(mods:, druid:, title_builder: Title, notifier: nil)
18
+ new(title_builder: title_builder, mods: mods, druid: druid, notifier: notifier).props
20
19
  end
21
20
 
22
- def initialize(title_builder:, mods:, label:, druid:, notifier:)
21
+ def initialize(title_builder:, mods:, druid:, notifier:)
23
22
  @title_builder = title_builder
24
23
  @ng_xml = mods
25
24
  @notifier = notifier || ErrorNotifier.new(druid: druid)
26
25
  @druid = druid
27
- @label = label
28
26
  end
29
27
 
30
28
  # @return [Hash] a hash that can be mapped to a cocina descriptive model
@@ -34,17 +32,15 @@ module Cocina
34
32
 
35
33
  check_altrepgroups
36
34
  check_version
37
- props = DescriptionBuilder.build(title_builder: title_builder,
38
- resource_element: ng_xml.root,
39
- notifier: notifier,
40
- purl: druid ? Cocina::Models::Mapping::Purl.for(druid: druid) : nil)
41
- props[:title] = [{ value: label }] unless props.key?(:title)
42
- props
35
+ DescriptionBuilder.build(title_builder: title_builder,
36
+ resource_element: ng_xml.root,
37
+ notifier: notifier,
38
+ purl: druid ? Cocina::Models::Mapping::Purl.for(druid: druid) : nil)
43
39
  end
44
40
 
45
41
  private
46
42
 
47
- attr_reader :title_builder, :ng_xml, :notifier, :druid, :label
43
+ attr_reader :title_builder, :ng_xml, :notifier, :druid
48
44
 
49
45
  def check_altrepgroups
50
46
  ng_xml.xpath('//mods:*[@altRepGroup]', mods: DESC_METADATA_NS)
@@ -14,7 +14,6 @@ module Cocina
14
14
  # example: 1.2.3
15
15
  attribute :cocinaVersion, CocinaVersion.default(VERSION)
16
16
  attribute :type, Types::Strict::String.enum(*RequestAdminPolicy::TYPES)
17
- attribute? :label, Types::Strict::String.default('')
18
17
  attribute :version, Types::Strict::Integer.default(1).enum(1)
19
18
  # Administrative properties for an AdminPolicy
20
19
  attribute(:administrative, AdminPolicyAdministrative.default { AdminPolicyAdministrative.new })
@@ -18,7 +18,6 @@ module Cocina
18
18
  # example: 1.2.3
19
19
  attribute :cocinaVersion, CocinaVersion.default(VERSION)
20
20
  attribute :type, Types::Strict::String.enum(*RequestCollection::TYPES)
21
- attribute? :label, Types::Strict::String.default('')
22
21
  attribute :version, Types::Strict::Integer.default(1).enum(1)
23
22
  # Access metadata for collections
24
23
  attribute(:access, CollectionAccess.default { CollectionAccess.new })
@@ -30,7 +30,6 @@ module Cocina
30
30
  # example: 1.2.3
31
31
  attribute :cocinaVersion, CocinaVersion.default(VERSION)
32
32
  attribute :type, Types::Strict::String.enum(*RequestDRO::TYPES)
33
- attribute? :label, Types::Strict::String.default('')
34
33
  attribute :version, Types::Strict::Integer.default(1).enum(1)
35
34
  attribute? :access, DROAccess.optional
36
35
  attribute(:administrative, RequestAdministrative.default { RequestAdministrative.new })
@@ -20,6 +20,7 @@ module Cocina
20
20
  DescriptionSubjectTemporalEncodingVisitorValidator,
21
21
  DescriptionTitleSourceCodeVisitorValidator,
22
22
  DescriptionLanguageUriVisitorValidator,
23
+ DescriptionLanguageSourceCodeVisitorValidator,
23
24
  DescriptionScriptVisitorValidator,
24
25
  DescriptionLocationVisitorValidator
25
26
  ].freeze
@@ -7,7 +7,7 @@ module Cocina
7
7
  module Validators
8
8
  # Validates that dates of known types are type-valid using the visitor pattern.
9
9
  class DescriptionDateTimeVisitorValidator < BaseDescriptionVisitorValidator
10
- VALIDATABLE_TYPES = %w[edtf iso8601 w3cdtf].freeze
10
+ VALIDATABLE_TYPES = %w[edtf iso8601 marc w3cdtf].freeze
11
11
  VALID_ENCODING_CODES = %w[edtf iso8601 marc temper w3cdtf].freeze
12
12
 
13
13
  def visit_hash(hash:, path:) # rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
@@ -135,6 +135,10 @@ module Cocina
135
135
  def valid_w3cdtf?(value)
136
136
  W3cdtfValidator.validate(value)
137
137
  end
138
+
139
+ def valid_marc?(value)
140
+ MarcDateValidator.validate(value)
141
+ end
138
142
  end
139
143
  end
140
144
  end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ module Validators
6
+ # Validates language.source.code and valueLanguage.source.code values against language_source_codes.yml.
7
+ class DescriptionLanguageSourceCodeVisitorValidator < BaseDescriptionVisitorValidator
8
+ def validate!
9
+ return if error_paths.empty?
10
+
11
+ raise ValidationError, "Unrecognized language source codes in description: #{error_paths.join(', ')}"
12
+ end
13
+
14
+ def visit_hash(hash:, path:)
15
+ return unless language_or_value_language_path?(path)
16
+
17
+ source_code = hash.dig(:source, :code)
18
+ return unless source_code
19
+ return if valid_codes.include?(source_code.downcase)
20
+
21
+ error_paths << "#{path_to_s(path)}.source.code (#{source_code})"
22
+ end
23
+
24
+ private
25
+
26
+ def error_paths
27
+ @error_paths ||= []
28
+ end
29
+
30
+ def language_or_value_language_path?(path)
31
+ language_path?(path) || value_language_path?(path)
32
+ end
33
+
34
+ def language_path?(path)
35
+ # language is a typed array (Array.of(Language)), so the visitor descends through
36
+ # an integer index. Path ends with [:language, <Integer>].
37
+ path.length >= 2 && path[-1].is_a?(Integer) && path[-2].to_s == 'language'
38
+ end
39
+
40
+ def value_language_path?(path)
41
+ # valueLanguage is a single optional hash (not an array), so the visitor descends
42
+ # directly by key. Path ends with [:valueLanguage].
43
+ path.length >= 1 && path[-1].to_s == 'valueLanguage'
44
+ end
45
+
46
+ # rubocop:disable Style/ClassVars
47
+ def valid_codes
48
+ @@valid_codes ||= YAML.load_file(::File.expand_path('../../../../language_source_codes.yml', __dir__)).to_set(&:downcase)
49
+ end
50
+ # rubocop:enable Style/ClassVars
51
+ end
52
+ end
53
+ end
54
+ end
@@ -3,8 +3,10 @@
3
3
  module Cocina
4
4
  module Models
5
5
  module Validators
6
- # Validates contributor.role.source.code values against role_source_codes.yml.
6
+ # Validates contributor.role.source.code values.
7
7
  class DescriptionRoleSourceCodeVisitorValidator < BaseDescriptionVisitorValidator
8
+ VALID_CODES = %w[aat lcmpt marcrelator rbmsrel].freeze
9
+
8
10
  def validate!
9
11
  return if error_paths.empty?
10
12
 
@@ -16,7 +18,7 @@ module Cocina
16
18
 
17
19
  source_code = hash.dig(:source, :code)
18
20
  return unless source_code
19
- return if valid_codes.include?(source_code.downcase)
21
+ return if VALID_CODES.include?(source_code.downcase)
20
22
 
21
23
  error_paths << "#{path_to_s(path)}.source.code (#{source_code})"
22
24
  end
@@ -33,11 +35,6 @@ module Cocina
33
35
  path[-2].to_s == 'role' && # we have a nested role in the path
34
36
  path.any? { |part| part.to_s == 'contributor' } # there is a contributor in the path (any? allows for nested roles)
35
37
  end
36
-
37
- # Source codes allowed for contributor.role.source.code
38
- def valid_codes
39
- %w[aat lcmpt marcrelator rbmsrel]
40
- end
41
38
  end
42
39
  end
43
40
  end
@@ -36,7 +36,8 @@ module Cocina
36
36
  # @return [JSONSchema validator] a cached per-definition validator
37
37
  def self.validator_for(def_name)
38
38
  @validators ||= {}
39
- @validators[def_name] ||= JSONSchema.validator_for({ '$ref' => "#/$defs/#{def_name}", '$defs' => document['$defs'] })
39
+ schema = { '$ref' => "#/$defs/#{def_name}", '$defs' => document['$defs'] }
40
+ @validators[def_name] ||= JSONSchema.validator_for(schema, validate_formats: true)
40
41
  end
41
42
 
42
43
  # @return [Hash] a hash representation of the schema.json document
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ module Validators
6
+ # Validates that not all titles have type 'alternative'
7
+ class NonAlternativeTitleValidator
8
+ def self.validate(...)
9
+ new(...).validate
10
+ end
11
+
12
+ def initialize(clazz, attributes)
13
+ @clazz = clazz
14
+ @attributes = attributes
15
+ end
16
+
17
+ def validate
18
+ return unless meets_preconditions?
19
+
20
+ return unless titles.all? { |title| title[:type] == 'alternative' }
21
+
22
+ raise ValidationError, "At least one title must have no type or a type other than 'alternative'."
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :clazz, :attributes
28
+
29
+ def meets_preconditions?
30
+ [Cocina::Models::Description, Cocina::Models::RequestDescription].include?(clazz) &&
31
+ titles.present?
32
+ end
33
+
34
+ def titles
35
+ @titles ||= Array(attributes[:title])
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -12,7 +12,8 @@ module Cocina
12
12
  PurlValidator,
13
13
  CatalogLinksValidator,
14
14
  AssociatedNameValidator,
15
- MarcRelatorRoleValidator
15
+ MarcRelatorRoleValidator,
16
+ NonAlternativeTitleValidator
16
17
  ].freeze
17
18
 
18
19
  def self.validate(clazz, attributes, validators: VALIDATORS)
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.130.0'
5
+ VERSION = '0.132.0'
6
6
  end
7
7
  end
data/schema.json CHANGED
@@ -106,10 +106,6 @@
106
106
  "externalIdentifier": {
107
107
  "$ref": "#/$defs/Druid"
108
108
  },
109
- "label": {
110
- "type": "string",
111
- "default": ""
112
- },
113
109
  "version": {
114
110
  "type": "integer"
115
111
  },
@@ -125,7 +121,8 @@
125
121
  "administrative",
126
122
  "externalIdentifier",
127
123
  "type",
128
- "version"
124
+ "version",
125
+ "description"
129
126
  ]
130
127
  },
131
128
  "AdminPolicy": {
@@ -372,11 +369,6 @@
372
369
  "externalIdentifier": {
373
370
  "$ref": "#/$defs/Druid"
374
371
  },
375
- "label": {
376
- "description": "Primary processing label (can be same as title) for a Collection.",
377
- "type": "string",
378
- "default": ""
379
- },
380
372
  "version": {
381
373
  "description": "Version for the Collection within SDR.",
382
374
  "type": "integer"
@@ -645,11 +637,6 @@
645
637
  ]
646
638
  },
647
639
  "externalIdentifier": { "$ref": "#/$defs/Druid" },
648
- "label": {
649
- "description": "Primary processing label (can be same as title) for a DRO.",
650
- "type": "string",
651
- "default": ""
652
- },
653
640
  "version": {
654
641
  "description": "Version for the DRO within SDR.",
655
642
  "type": "integer"
@@ -1126,7 +1113,8 @@
1126
1113
  },
1127
1114
  "uri": {
1128
1115
  "description": "URI value of the descriptive element.",
1129
- "type": "string"
1116
+ "type": "string",
1117
+ "format": "uri"
1130
1118
  },
1131
1119
  "standard": {
1132
1120
  "$ref": "#/$defs/Standard"
@@ -1352,7 +1340,8 @@
1352
1340
  },
1353
1341
  "uri": {
1354
1342
  "description": "URI for the standard or encoding.",
1355
- "type": "string"
1343
+ "type": "string",
1344
+ "format": "uri"
1356
1345
  },
1357
1346
  "value": {
1358
1347
  "description": "String describing the standard or encoding.",
@@ -1877,7 +1866,8 @@
1877
1866
  },
1878
1867
  "uri": {
1879
1868
  "description": "URI value of the descriptive element.",
1880
- "type": "string"
1869
+ "type": "string",
1870
+ "format": "uri"
1881
1871
  },
1882
1872
  "value": {
1883
1873
  "description": "Value of the descriptive element.",
@@ -2446,10 +2436,6 @@
2446
2436
  "https://cocina.sul.stanford.edu/models/admin_policy"
2447
2437
  ]
2448
2438
  },
2449
- "label": {
2450
- "type": "string",
2451
- "default": ""
2452
- },
2453
2439
  "version": {
2454
2440
  "type": "integer",
2455
2441
  "default": 1,
@@ -2518,10 +2504,6 @@
2518
2504
  "https://cocina.sul.stanford.edu/models/series"
2519
2505
  ]
2520
2506
  },
2521
- "label": {
2522
- "type": "string",
2523
- "default": ""
2524
- },
2525
2507
  "version": {
2526
2508
  "type": "integer",
2527
2509
  "default": 1,
@@ -2619,10 +2601,6 @@
2619
2601
  "https://cocina.sul.stanford.edu/models/webarchive-seed"
2620
2602
  ]
2621
2603
  },
2622
- "label": {
2623
- "type": "string",
2624
- "default": ""
2625
- },
2626
2604
  "version": {
2627
2605
  "type": "integer",
2628
2606
  "default": 1,
@@ -2996,7 +2974,8 @@
2996
2974
  },
2997
2975
  "uri": {
2998
2976
  "description": "URI for the value source.",
2999
- "type": "string"
2977
+ "type": "string",
2978
+ "format": "uri"
3000
2979
  },
3001
2980
  "value": {
3002
2981
  "description": "String describing the value source.",
@@ -3043,7 +3022,8 @@
3043
3022
  },
3044
3023
  "uri": {
3045
3024
  "description": "URI for the standard or encoding.",
3046
- "type": "string"
3025
+ "type": "string",
3026
+ "format": "uri"
3047
3027
  },
3048
3028
  "value": {
3049
3029
  "description": "String describing the standard or encoding.",
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cocina-models
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.130.0
4
+ version: 0.132.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Coyne
@@ -329,6 +329,7 @@ files:
329
329
  - form_source_codes.yml
330
330
  - identifier_source_codes.yml
331
331
  - iso15924_codes.yml
332
+ - language_source_codes.yml
332
333
  - language_uri_iso639_2_codes.yml
333
334
  - language_uri_languages_codes.yml
334
335
  - lib/cocina/generator.rb
@@ -441,7 +442,6 @@ files:
441
442
  - lib/cocina/models/mapping/from_mods/subject_authority_codes.rb
442
443
  - lib/cocina/models/mapping/from_mods/title.rb
443
444
  - lib/cocina/models/mapping/from_mods/title_builder.rb
444
- - lib/cocina/models/mapping/from_mods/title_builder_strategy.rb
445
445
  - lib/cocina/models/mapping/from_mods/value_uri.rb
446
446
  - lib/cocina/models/mapping/purl.rb
447
447
  - lib/cocina/models/message_digest.rb
@@ -488,6 +488,7 @@ files:
488
488
  - lib/cocina/models/validators/description_form_source_code_visitor_validator.rb
489
489
  - lib/cocina/models/validators/description_identifier_source_code_visitor_validator.rb
490
490
  - lib/cocina/models/validators/description_language_code_visitor_validator.rb
491
+ - lib/cocina/models/validators/description_language_source_code_visitor_validator.rb
491
492
  - lib/cocina/models/validators/description_language_uri_visitor_validator.rb
492
493
  - lib/cocina/models/validators/description_location_visitor_validator.rb
493
494
  - lib/cocina/models/validators/description_name_source_code_visitor_validator.rb
@@ -502,6 +503,7 @@ files:
502
503
  - lib/cocina/models/validators/language_tag_visitor_validator.rb
503
504
  - lib/cocina/models/validators/marc_date_validator.rb
504
505
  - lib/cocina/models/validators/marc_relator_role_validator.rb
506
+ - lib/cocina/models/validators/non_alternative_title_validator.rb
505
507
  - lib/cocina/models/validators/purl_validator.rb
506
508
  - lib/cocina/models/validators/reserved_filename_visitor_validator.rb
507
509
  - lib/cocina/models/validators/validator.rb
@@ -537,7 +539,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
537
539
  - !ruby/object:Gem::Version
538
540
  version: '0'
539
541
  requirements: []
540
- rubygems_version: 4.0.6
542
+ rubygems_version: 3.6.9
541
543
  specification_version: 4
542
544
  summary: Data models for the SDR
543
545
  test_files: []
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Cocina
4
- module Models
5
- module Mapping
6
- module FromMods
7
- # Decides how to build a title based on whether this is a registered Hydrus object or not.
8
- class TitleBuilderStrategy
9
- # @param [String] label
10
- # @return [#build] a class that can build a title
11
- def self.find(label:)
12
- # Some hydrus items don't have titles, so using label. See https://github.com/sul-dlss/hydrus/issues/421
13
- label == 'Hydrus' ? HydrusDefaultTitleBuilder : Title
14
- end
15
- end
16
- end
17
- end
18
- end
19
- end