cocina-models 0.93.0 → 0.94.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: 9cf74f9126fce8106b3bfd5964c11731c460546a4f457da9ba7f35f895243c7a
4
- data.tar.gz: 58467364ec8a96eac4f6d335dce400c0086833830f5704e263bae7365741d473
3
+ metadata.gz: 325cc1afd87f6c47380be3a4858d8858e31661efdfd39c0360c4a62f4541b6f2
4
+ data.tar.gz: 4539fb9f4a715cc488e50a67df0c1e345ff227be9afe1dbd94c6466d4902a41b
5
5
  SHA512:
6
- metadata.gz: e2106344f663362d1609f5e40daf001c43f976abbbe7ae8a43c52295b2a2e280952c7d6d01b6f6b4cbdf124a07c26372bdfc17f9a903cce666edc39ba3b3db35
7
- data.tar.gz: 5675d10901a099d8869baed51c4bdb82608305053d0e830130c28577644daddf73a650410cb20425e4e27ff4dfc60188f0e2cb0b77954c49bd3f00980ee56cf1
6
+ metadata.gz: d37e0ca7edb90caf68d706741e1f04ad8eafa767527af393f72ef3fe44ab55fa056b027848c46d8c43ed4ccdc97369a86a93a7d1d82b60b8d2302307fc1e634b
7
+ data.tar.gz: 2bca5d3dcf6f5d141a0402545a558b17953af6f64311b29e11a57fc0f0d842af983a901b86e1a1cc8265c61f454db88d5f2a84460bb90e5bd0c0d8031073e913
data/.rspec CHANGED
@@ -1,3 +1,2 @@
1
- --format documentation
2
1
  --color
3
2
  --require spec_helper
data/.rubocop.yml CHANGED
@@ -458,4 +458,39 @@ Style/YAMLFileRead: # new in 1.53
458
458
  RSpec/ReceiveMessages: # new in 2.23
459
459
  Enabled: true
460
460
  RSpec/Rails/NegationBeValid: # new in 2.23
461
- Enabled: true
461
+ Enabled: true
462
+
463
+ Lint/ItWithoutArgumentsInBlock: # new in 1.59
464
+ Enabled: true
465
+ Lint/LiteralAssignmentInCondition: # new in 1.58
466
+ Enabled: true
467
+ Style/SingleLineDoEndBlock: # new in 1.57
468
+ Enabled: true
469
+ Style/SuperWithArgsParentheses: # new in 1.58
470
+ Enabled: true
471
+ Capybara/ClickLinkOrButtonStyle: # new in 2.19
472
+ Enabled: true
473
+ Capybara/RedundantWithinFind: # new in 2.20
474
+ Enabled: true
475
+ Capybara/RSpec/HaveSelector: # new in 2.19
476
+ Enabled: true
477
+ Capybara/RSpec/PredicateMatcher: # new in 2.19
478
+ Enabled: true
479
+ FactoryBot/ExcessiveCreateList: # new in 2.25
480
+ Enabled: true
481
+ FactoryBot/IdSequence: # new in 2.24
482
+ Enabled: true
483
+ RSpec/EmptyMetadata: # new in 2.24
484
+ Enabled: true
485
+ RSpec/Eq: # new in 2.24
486
+ Enabled: true
487
+ RSpec/MetadataStyle: # new in 2.24
488
+ Enabled: true
489
+ RSpec/RedundantPredicateMatcher: # new in 2.26
490
+ Enabled: true
491
+ RSpec/RemoveConst: # new in 2.26
492
+ Enabled: true
493
+ RSpec/SpecFilePathFormat: # new in 2.24
494
+ Enabled: true
495
+ RSpec/SpecFilePathSuffix: # new in 2.24
496
+ Enabled: true
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cocina-models (0.93.0)
4
+ cocina-models (0.94.0)
5
5
  activesupport
6
6
  deprecation
7
7
  dry-struct (~> 1.0)
@@ -21,7 +21,7 @@ PATH
21
21
  GEM
22
22
  remote: https://rubygems.org/
23
23
  specs:
24
- activesupport (7.1.1)
24
+ activesupport (7.1.2)
25
25
  base64
26
26
  bigdecimal
27
27
  concurrent-ruby (~> 1.0, >= 1.0.2)
@@ -33,8 +33,8 @@ GEM
33
33
  tzinfo (~> 2.0)
34
34
  ast (2.4.2)
35
35
  attr_extras (7.1.0)
36
- base64 (0.1.1)
37
- bigdecimal (3.1.4)
36
+ base64 (0.2.0)
37
+ bigdecimal (3.1.5)
38
38
  byebug (11.1.3)
39
39
  committee (5.0.0)
40
40
  json_schema (~> 0.14, >= 0.14.3)
@@ -47,7 +47,7 @@ GEM
47
47
  activesupport
48
48
  diff-lcs (1.5.0)
49
49
  docile (1.4.0)
50
- drb (2.1.1)
50
+ drb (2.2.0)
51
51
  ruby2_keywords
52
52
  dry-core (1.0.1)
53
53
  concurrent-ruby (~> 1.0)
@@ -62,7 +62,8 @@ GEM
62
62
  dry-types (>= 1.7, < 2)
63
63
  ice_nine (~> 0.11)
64
64
  zeitwerk (~> 2.6)
65
- dry-types (1.7.1)
65
+ dry-types (1.7.2)
66
+ bigdecimal (~> 3.0)
66
67
  concurrent-ruby (~> 1.0)
67
68
  dry-core (~> 1.0)
68
69
  dry-inflector (~> 1.0)
@@ -75,24 +76,24 @@ GEM
75
76
  i18n (1.14.1)
76
77
  concurrent-ruby (~> 1.0)
77
78
  ice_nine (0.11.2)
78
- json (2.6.3)
79
+ json (2.7.1)
79
80
  json_schema (0.21.0)
80
81
  jsonpath (1.1.5)
81
82
  multi_json
82
83
  language_server-protocol (3.17.0.3)
83
84
  mini_portile2 (2.8.5)
84
- minitest (5.20.0)
85
+ minitest (5.21.1)
85
86
  multi_json (1.15.0)
86
- mutex_m (0.1.2)
87
- nokogiri (1.15.4)
87
+ mutex_m (0.2.0)
88
+ nokogiri (1.16.0)
88
89
  mini_portile2 (~> 2.8.2)
89
90
  racc (~> 1.4)
90
91
  openapi3_parser (0.9.2)
91
92
  commonmarker (~> 0.17)
92
93
  openapi_parser (1.0.0)
93
94
  optimist (3.1.0)
94
- parallel (1.23.0)
95
- parser (3.2.2.4)
95
+ parallel (1.24.0)
96
+ parser (3.3.0.3)
96
97
  ast (~> 2.4.1)
97
98
  racc
98
99
  patience_diff (1.2.0)
@@ -101,7 +102,7 @@ GEM
101
102
  rack (3.0.8)
102
103
  rainbow (3.1.1)
103
104
  rake (13.1.0)
104
- regexp_parser (2.8.2)
105
+ regexp_parser (2.9.0)
105
106
  rexml (3.2.6)
106
107
  rspec (3.12.0)
107
108
  rspec-core (~> 3.12.0)
@@ -120,26 +121,26 @@ GEM
120
121
  rspec-core (>= 2, < 4, != 2.12.0)
121
122
  rss (0.3.0)
122
123
  rexml
123
- rubocop (1.57.2)
124
+ rubocop (1.60.0)
124
125
  json (~> 2.3)
125
126
  language_server-protocol (>= 3.17.0)
126
127
  parallel (~> 1.10)
127
- parser (>= 3.2.2.4)
128
+ parser (>= 3.3.0.2)
128
129
  rainbow (>= 2.2.2, < 4.0)
129
130
  regexp_parser (>= 1.8, < 3.0)
130
131
  rexml (>= 3.2.5, < 4.0)
131
- rubocop-ast (>= 1.28.1, < 2.0)
132
+ rubocop-ast (>= 1.30.0, < 2.0)
132
133
  ruby-progressbar (~> 1.7)
133
134
  unicode-display_width (>= 2.4.0, < 3.0)
134
135
  rubocop-ast (1.30.0)
135
136
  parser (>= 3.2.1.0)
136
- rubocop-capybara (2.19.0)
137
+ rubocop-capybara (2.20.0)
138
+ rubocop (~> 1.41)
139
+ rubocop-factory_bot (2.25.1)
137
140
  rubocop (~> 1.41)
138
- rubocop-factory_bot (2.24.0)
139
- rubocop (~> 1.33)
140
141
  rubocop-rake (0.6.0)
141
142
  rubocop (~> 1.0)
142
- rubocop-rspec (2.25.0)
143
+ rubocop-rspec (2.26.1)
143
144
  rubocop (~> 1.40)
144
145
  rubocop-capybara (~> 2.17)
145
146
  rubocop-factory_bot (~> 2.22)
data/README.md CHANGED
@@ -12,6 +12,8 @@ The data model is expressed in an OpenAPI specification that lives in this codeb
12
12
 
13
13
  Note that the data model encodes properties as camelCase, which the team believes to be consistent with other HTTP APIs and the original design of the Cocina data model. While using camelCase in Ruby code may look and feel wrong, we did explore automagic conversion between camelCase in the model and snake_case in the Ruby context. We ultimately concluded that we have enough representations of the data model in enough codebases to reasonably worry about data inconsistency problems, none of which we need in our work on SDR.
14
14
 
15
+ For more about the model for description see https://consul.stanford.edu/display/DIGMETADATA/Digital+Object+Metadata+Documentation#DigitalObjectMetadataDocumentation-Cocinamodel
16
+
15
17
  ## Configuration
16
18
 
17
19
  Set the PURL url base:
@@ -356,6 +356,7 @@ identifier:
356
356
  - value: DOI
357
357
  code: doi
358
358
  - value: druid
359
+ - value: EUR-OP
359
360
  - value: FOLIO
360
361
  description: FOLIO HRID for the source record of the metadata.
361
362
  - value: GTIN-14 ID
@@ -391,6 +392,8 @@ identifier:
391
392
  - value: PMCID
392
393
  - value: PMID
393
394
  - value: record id
395
+ - value: ROR
396
+ code: ror
394
397
  - value: Senate Number
395
398
  - value: Series
396
399
  - value: SICI
@@ -424,6 +427,8 @@ note:
424
427
  - value: access note
425
428
  status: deprecated
426
429
  use: access
430
+ - value: access restriction
431
+ description: Information about restrictions on who may or how to access a resource.
427
432
  - value: acquisition
428
433
  description: The transfer of a resource to a repository.
429
434
  - value: action
@@ -432,6 +437,9 @@ note:
432
437
  - value: additions
433
438
  description: Resources added after initial acquisition.
434
439
  - value: admin
440
+ status: deprecated
441
+ use: administrative
442
+ - value: administrative
435
443
  description: Administrative or internal use.
436
444
  - value: affiliation
437
445
  description: Institution with which a person or other entity is associated.
@@ -542,6 +550,9 @@ note:
542
550
  - value: reproduction
543
551
  - value: research
544
552
  - value: restriction
553
+ - value: restriction on access
554
+ status: deprecated
555
+ use: access restriction
545
556
  - value: rubric
546
557
  - value: scope and content
547
558
  - value: secfol
@@ -561,6 +572,7 @@ note:
561
572
  - value: table of contents
562
573
  - value: target audience
563
574
  - value: technical note
575
+ description: Technological requirements for accessing or using the resource.
564
576
  - value: thesis
565
577
  - value: transcript
566
578
  - value: translation
@@ -712,6 +724,8 @@ subject.structuredValue:
712
724
  description: An individual identity.
713
725
  - value: place
714
726
  description: A geographic location associated with the content of a resource.
727
+ - value: point coordinates
728
+ description: The latitude and longitude of a place associated with the content of a resource.
715
729
  - value: region
716
730
  description: An area that incorporates more than one first-order jurisdiction.
717
731
  - value: south
@@ -363,6 +363,7 @@ _Path: identifier.type_
363
363
  * document number
364
364
  * DOI
365
365
  * druid
366
+ * EUR-OP
366
367
  * FOLIO
367
368
  * FOLIO HRID for the source record of the metadata.
368
369
  * GTIN-14 ID
@@ -385,6 +386,7 @@ _Path: identifier.type_
385
386
  * PMCID
386
387
  * PMID
387
388
  * record id
389
+ * ROR
388
390
  * Senate Number
389
391
  * Series
390
392
  * SICI
@@ -409,6 +411,8 @@ _Path: note.type_
409
411
  * Information about gaining access to a resource.
410
412
  * access note
411
413
  * Deprecated. Preferred usage: access
414
+ * access restriction
415
+ * Information about restrictions on who may or how to access a resource.
412
416
  * acquisition
413
417
  * The transfer of a resource to a repository.
414
418
  * action
@@ -417,6 +421,8 @@ _Path: note.type_
417
421
  * additions
418
422
  * Resources added after initial acquisition.
419
423
  * admin
424
+ * Deprecated. Preferred usage: administrative
425
+ * administrative
420
426
  * Administrative or internal use.
421
427
  * affiliation
422
428
  * Institution with which a person or other entity is associated.
@@ -522,6 +528,8 @@ _Path: note.type_
522
528
  * reproduction
523
529
  * research
524
530
  * restriction
531
+ * restriction on access
532
+ * Deprecated. Preferred usage: access restriction
525
533
  * rubric
526
534
  * scope and content
527
535
  * secfol
@@ -539,6 +547,7 @@ _Path: note.type_
539
547
  * table of contents
540
548
  * target audience
541
549
  * technical note
550
+ * Technological requirements for accessing or using the resource.
542
551
  * thesis
543
552
  * transcript
544
553
  * translation
@@ -695,6 +704,8 @@ _Path: subject.structuredValue.type_
695
704
  * An individual identity.
696
705
  * place
697
706
  * A geographic location associated with the content of a resource.
707
+ * point coordinates
708
+ * The latitude and longitude of a place associated with the content of a resource.
698
709
  * region
699
710
  * An area that incorporates more than one first-order jurisdiction.
700
711
  * south
@@ -6,8 +6,7 @@ module Cocina
6
6
  module Models
7
7
  module Builders
8
8
  # TitleBuilder selects the prefered title from the cocina object for solr indexing
9
- # rubocop:disable Metrics/ClassLength
10
- class TitleBuilder
9
+ class TitleBuilder # rubocop:disable Metrics/ClassLength
11
10
  extend Deprecation
12
11
  # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
13
12
  # @param [Symbol] strategy ":first" is the strategy for selection when primary or display
@@ -24,24 +23,57 @@ module Cocina
24
23
  new(strategy: strategy, add_punctuation: add_punctuation).build(titles)
25
24
  end
26
25
 
26
+ # the "main title" is the title withOUT subtitle, part name, etc. We want to index it separately so
27
+ # we can boost matches on it in search results (boost matching this string higher than matching full title string)
28
+ # e.g. "The Hobbit" (main_title) vs "The Hobbit, or, There and Back Again (full_title)
29
+ # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
30
+ # @return [String] the main title value for Solr
31
+ def self.main_title(titles)
32
+ new(strategy: :first, add_punctuation: false).main_title(titles)
33
+ end
34
+
35
+ # the "full title" is the title WITH subtitle, part name, etc. We want to able able to index it separately so
36
+ # we can boost matches on it in search results (boost matching this string higher than other titles present)
37
+ # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
38
+ # @return [String] the title value for Solr
39
+ def self.full_title(titles)
40
+ new(strategy: :first, add_punctuation: false).build(titles)
41
+ end
42
+
43
+ # "additional titles" are all title data except for full_title. We want to able able to index it separately so
44
+ # we can boost matches on it in search results (boost matching these strings lower than other titles present)
45
+ # @param [[Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
46
+ # @return [Array<String>] the values for Solr
47
+ def self.additional_titles(titles)
48
+ new(strategy: :all, add_punctuation: false).build(titles) - [full_title(titles)]
49
+ end
50
+
27
51
  def initialize(strategy:, add_punctuation:)
28
52
  @strategy = strategy
29
53
  @add_punctuation = add_punctuation
30
54
  end
31
55
 
32
- # @param [[Array<Cocina::Models::Title>] titles the titles to consider
56
+ # @param [[Array<Cocina::Models::Title>] cocina_titles the titles to consider
33
57
  # @return [String] the title value for Solr
34
- def build(titles)
35
- cocina_title = primary_title(titles) || untyped_title(titles)
36
- cocina_title = other_title(titles) if cocina_title.blank?
58
+ def build(cocina_titles)
59
+ cocina_title = primary_title(cocina_titles) || untyped_title(cocina_titles)
60
+ cocina_title = other_title(cocina_titles) if cocina_title.blank?
37
61
 
38
62
  if strategy == :first
39
63
  extract_title(cocina_title)
40
64
  else
41
- cocina_title.map { |one| extract_title(one) }
65
+ cocina_titles.map { |ctitle| extract_title(ctitle) }.flatten
42
66
  end
43
67
  end
44
68
 
69
+ def main_title(titles)
70
+ cocina_title = primary_title(titles) || untyped_title(titles)
71
+ cocina_title = other_title(titles) if cocina_title.blank?
72
+
73
+ cocina_title = cocina_title.first if cocina_title.is_a?(Array)
74
+ extract_main_title(cocina_title)
75
+ end
76
+
45
77
  private
46
78
 
47
79
  attr_reader :strategy
@@ -57,6 +89,16 @@ module Cocina
57
89
  remove_trailing_punctuation(result.strip) if result.present?
58
90
  end
59
91
 
92
+ def extract_main_title(cocina_title)
93
+ if cocina_title.value
94
+ cocina_title.value # covers both title and main title types
95
+ elsif cocina_title.structuredValue.present?
96
+ main_title_from_structured_values(cocina_title)
97
+ elsif cocina_title.parallelValue.present?
98
+ main_title(cocina_title.parallelValue)
99
+ end
100
+ end
101
+
60
102
  def add_punctuation?
61
103
  @add_punctuation
62
104
  end
@@ -93,7 +135,8 @@ module Cocina
93
135
  end
94
136
  end
95
137
 
96
- # This handles 'main title', 'uniform' or 'translated'
138
+ # This is called when there is no primary title and no untyped title
139
+ # @return [Cocina::Models::Title, Array<Cocina::Models::Title>] first title or all titles
97
140
  def other_title(titles)
98
141
  if strategy == :first
99
142
  titles.first
@@ -102,17 +145,19 @@ module Cocina
102
145
  end
103
146
  end
104
147
 
105
- # rubocop:disable Metrics/BlockLength
106
- # rubocop:disable Metrics/CyclomaticComplexity
107
- # rubocop:disable Metrics/PerceivedComplexity
108
- # rubocop:disable Metrics/MethodLength
109
148
  # @param [Cocina::Models::Title] title with structured values
110
149
  # @return [String] the title value from combining the pieces of the structured_values by type and order
111
150
  # with desired punctuation per specs
151
+ #
152
+ # rubocop:disable Metrics/CyclomaticComplexity
153
+ # rubocop:disable Metrics/MethodLength
154
+ # rubocop:disable Metrics/PerceivedComplexity
112
155
  def title_from_structured_values(title)
113
- structured_title = ''
156
+ # parse out the parts
157
+ main_title = ''
158
+ subtitle = ''
159
+ non_sort_value = ''
114
160
  part_name_number = ''
115
- # combine pieces of the cocina structuredValue into a single title
116
161
  title.structuredValue.each do |structured_value|
117
162
  # There can be a structuredValue inside a structuredValue. For example,
118
163
  # a uniform title where both the name and the title have internal StructuredValue
@@ -125,42 +170,88 @@ module Cocina
125
170
  case structured_value.type&.downcase
126
171
  when 'nonsorting characters'
127
172
  non_sort_value = "#{value}#{non_sorting_padding(title, value)}"
128
- structured_title = if structured_title.present?
129
- "#{structured_title}#{non_sort_value}"
130
- else
131
- non_sort_value
132
- end
133
173
  when 'part name', 'part number'
134
- if part_name_number.blank?
135
- part_name_number = part_name_number(title.structuredValue)
136
- structured_title = if !add_punctuation?
137
- [structured_title, part_name_number].join(' ')
138
- elsif structured_title.present?
139
- "#{structured_title.sub(/[ .,]*$/, '')}. #{part_name_number}. "
140
- else
141
- "#{part_name_number}. "
142
- end
143
- end
174
+ part_name_number = part_name_number(title.structuredValue) if part_name_number.blank?
144
175
  when 'main title', 'title'
145
- structured_title = "#{structured_title}#{value}"
176
+ main_title = value
146
177
  when 'subtitle'
147
- # subtitle is preceded by space colon space, unless it is at the beginning of the title string
148
- structured_title = if !add_punctuation?
149
- [structured_title, value].join(' ')
150
- elsif structured_title.present?
151
- "#{structured_title.sub(/[. :]+$/, '')} : #{value.sub(/^:/, '').strip}"
152
- else
153
- structured_title = value.sub(/^:/, '').strip
154
- end
178
+ # combine multiple subtitles into a single string
179
+ subtitle = if !add_punctuation?
180
+ if subtitle.present?
181
+ [subtitle, value].join(' ')
182
+ else
183
+ value
184
+ end
185
+ elsif subtitle.present?
186
+ # subtitle is preceded by space colon space, unless it is at the beginning of the title string
187
+ "#{subtitle.sub(/[. :]+$/, '')} : #{value.sub(/^:/, '').strip}"
188
+ else
189
+ value.sub(/^:/, '').strip
190
+ end
155
191
  end
156
192
  end
157
- structured_title
193
+
194
+ # combine the parts into a single title string
195
+ if add_punctuation?
196
+ combine_with_punctuation(non_sort_value: non_sort_value, main_title: main_title, subtitle: subtitle,
197
+ part_name_number: part_name_number)
198
+ else
199
+ ["#{non_sort_value}#{main_title}", subtitle, part_name_number].select(&:presence).join(' ')
200
+ end
158
201
  end
159
- # rubocop:enable Metrics/MethodLength
160
- # rubocop:enable Metrics/BlockLength
161
202
  # rubocop:enable Metrics/CyclomaticComplexity
203
+ # rubocop:enable Metrics/MethodLength
162
204
  # rubocop:enable Metrics/PerceivedComplexity
163
205
 
206
+ # main_title is title.structuredValue.value with type 'main title' (or just title.value)
207
+ # @param [Cocina::Models::Title] title with structured values
208
+ # @return [String] the main title value
209
+ def main_title_from_structured_values(cocina_title) # rubocop:disable Metrics/MethodLength
210
+ result = ''
211
+ # combine pieces of the cocina structuredValue into a single title
212
+ cocina_title.structuredValue.each do |structured_value|
213
+ # There can be a structuredValue inside a structuredValue. For example,
214
+ # a uniform title where both the name and the title have internal StructuredValue
215
+ return main_title_from_structured_values(structured_value) if structured_value.structuredValue.present?
216
+
217
+ value = structured_value.value&.strip
218
+ next unless value
219
+
220
+ case structured_value.type&.downcase
221
+ when 'nonsorting characters'
222
+ non_sort_value = "#{value}#{non_sorting_padding(cocina_title, value)}"
223
+ result = "#{non_sort_value}#{result}" # non-sorting characters are at the beginning of the title
224
+ when 'main title'
225
+ result = "#{result}#{value}"
226
+ when 'title'
227
+ result = value
228
+ end
229
+ end
230
+ result
231
+ end
232
+
233
+ # Thank MARC and catalog cards for this mess. We need to add punctuation.
234
+ # rubocop:disable Metrics/MethodLength
235
+ def combine_with_punctuation(non_sort_value:, main_title:, subtitle:, part_name_number:)
236
+ result = "#{non_sort_value}#{main_title}"
237
+ if subtitle.present?
238
+ result = if result.present?
239
+ "#{result.sub(/[. :]+$/, '')} : #{subtitle.sub(/^:/, '').strip}"
240
+ else
241
+ result = subtitle
242
+ end
243
+ end
244
+ if part_name_number.present?
245
+ result = if result.present?
246
+ "#{result.sub(/[ .,]*$/, '')}. #{part_name_number}."
247
+ else
248
+ "#{part_name_number}."
249
+ end
250
+ end
251
+ result
252
+ end
253
+ # rubocop:enable Metrics/MethodLength
254
+
164
255
  def remove_trailing_punctuation(title)
165
256
  title.sub(%r{[ .,;:/\\]+$}, '')
166
257
  end
@@ -205,7 +296,6 @@ module Cocina
205
296
  end
206
297
  end
207
298
  end
208
- # rubocop:enable Metrics/ClassLength
209
299
  end
210
300
  end
211
301
  end
@@ -37,7 +37,7 @@ module Cocina
37
37
  def build
38
38
  grouped_altrepgroup_name_nodes, other_name_nodes = AltRepGroup.split(nodes: deduped_name_nodes)
39
39
  check_altrepgroup_type_inconsistency(grouped_altrepgroup_name_nodes)
40
- contributors = grouped_altrepgroup_name_nodes.map { |name_nodes| build_name_nodes(name_nodes) } + \
40
+ contributors = grouped_altrepgroup_name_nodes.map { |name_nodes| build_name_nodes(name_nodes) } +
41
41
  other_name_nodes.map { |name_node| build_name_nodes([name_node]) }
42
42
  contrib_level_type_and_status(contributors)
43
43
  adjust_primary(contributors.compact).presence
@@ -110,7 +110,7 @@ module Cocina
110
110
  end
111
111
  end
112
112
 
113
- result.each { |_k, role_nodes| role_nodes.uniq! { |role_node| name_node_comparitor(role_node) } }
113
+ result.each_value { |role_nodes| role_nodes.uniq! { |role_node| name_node_comparitor(role_node) } }
114
114
  end
115
115
 
116
116
  def check_altrepgroup_type_inconsistency(grouped_altrepgroup_name_nodes)
@@ -95,7 +95,7 @@ module Cocina
95
95
  node.text.size + add
96
96
  end
97
97
  [{
98
- value: count.to_s, # cast to String until cocina-models 0.40.0 is used. See https://github.com/sul-dlss/cocina-models/pull/146
98
+ value: count.to_s, # cast to String until cocina-models 0.40.0 is used. See https://github.com/sul-dlss/cocina-models/pull/146
99
99
  type: 'nonsorting character count'
100
100
  }]
101
101
  end
@@ -174,7 +174,7 @@ module Cocina
174
174
  [role_node]
175
175
  end
176
176
  end
177
- result.each { |_k, role_nodes| role_nodes.uniq! { |role_node| name_node_comparitor(role_node) } }
177
+ result.each_value { |role_nodes| role_nodes.uniq! { |role_node| name_node_comparitor(role_node) } }
178
178
  end
179
179
 
180
180
  def normalize_type
@@ -11,9 +11,7 @@ module Cocina
11
11
  PurlValidator,
12
12
  CatalogLinksValidator,
13
13
  AssociatedNameValidator,
14
- # Removing until production data can be remediated and/or additional types can be added to configuration.
15
- # See also spec/cocina/models/validatable_spec.rb:59
16
- # DescriptionTypesValidator,
14
+ DescriptionTypesValidator,
17
15
  DescriptionValuesValidator,
18
16
  DateTimeValidator,
19
17
  LanguageTagValidator
@@ -27,12 +25,12 @@ module Cocina
27
25
  VALIDATORS.each { |validator| validator.validate(clazz, attributes_hash) }
28
26
  end
29
27
 
30
- def self.deep_transform_values(object, &block)
28
+ def self.deep_transform_values(object, ...)
31
29
  case object
32
30
  when Hash
33
- object.transform_values { |value| deep_transform_values(value, &block) }
31
+ object.transform_values { |value| deep_transform_values(value, ...) }
34
32
  when Array
35
- object.map { |e| deep_transform_values(e, &block) }
33
+ object.map { |e| deep_transform_values(e, ...) }
36
34
  else
37
35
  yield(object)
38
36
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.93.0'
5
+ VERSION = '0.94.0'
6
6
  end
7
7
  end
@@ -38,7 +38,7 @@ module Cocina
38
38
 
39
39
  build_type = type.to_s.delete_suffix(WITH_METADATA_SUFFIX)
40
40
 
41
- fixture = public_send("build_#{build_type}".to_sym, attributes)
41
+ fixture = public_send("build_#{build_type}".to_sym, attributes) # rubocop:disable Lint/SymbolConversion
42
42
  return fixture unless type.end_with?(WITH_METADATA_SUFFIX)
43
43
 
44
44
  Cocina::Models.with_metadata(fixture, 'abc123')
data/openapi.yml CHANGED
@@ -330,6 +330,7 @@ components:
330
330
  pattern: '^[0-9]+-[0-9]+$'
331
331
  example: '6772719-1001'
332
332
  CitationOnlyAccess:
333
+ description: A type of access for an object wherein users can see the metadata and a list of files, but the files will not have view or download access
333
334
  type: object
334
335
  properties:
335
336
  view:
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.93.0
4
+ version: 0.94.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-09 00:00:00.000000000 Z
11
+ date: 2024-01-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -562,7 +562,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
562
562
  - !ruby/object:Gem::Version
563
563
  version: '0'
564
564
  requirements: []
565
- rubygems_version: 3.4.19
565
+ rubygems_version: 3.3.7
566
566
  signing_key:
567
567
  specification_version: 4
568
568
  summary: Data models for the SDR