cocina-models 0.100.0 → 0.101.1
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/.circleci/config.yml +1 -2
- data/.rubocop.yml +34 -54
- data/Gemfile.lock +32 -35
- data/cocina-models.gemspec +1 -1
- data/lib/cocina/generator/generator.rb +1 -0
- data/lib/cocina/generator/vocab.rb +1 -0
- data/lib/cocina/models/builders/title_builder.rb +22 -11
- data/lib/cocina/models/folio_catalog_link.rb +4 -0
- data/lib/cocina/models/mapping/from_mods/event.rb +1 -0
- data/lib/cocina/models/mapping/normalizers/mods/origin_info_normalizer.rb +1 -0
- data/lib/cocina/models/validators/catalog_links_validator.rb +12 -0
- data/lib/cocina/models/version.rb +1 -1
- data/openapi.yml +6 -0
- metadata +7 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 020bb1af47ff01f6e95a8d126cabaae16a19a1cd92ae8bdade1e18f97f519af6
|
4
|
+
data.tar.gz: e05e3b0a0a6122a1297fe3d12e3b9737b618ed03ae246d8b4b24e0740254ad9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd8a640dfe907eaebfc3f0b6b72f044b8b149718601d8845b315d529f861634fc0ce194f684236802e2799378a5a01920d8facf7f3669a95ac9e6d1ede066ce5
|
7
|
+
data.tar.gz: eb7d1fc6c14ebadb308e7c7b53f00640d20de07ca337523e33cc77e7b039b00d737fa94079282e29254c8f46b6dffb654ae5c3c5dbfb7fe5cc7cabc592e1fa93
|
data/.circleci/config.yml
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
# This is the configuration used to check the rubocop source code.
|
2
2
|
|
3
3
|
inherit_from: .rubocop_todo.yml
|
4
|
-
|
5
|
-
- rubocop-rspec
|
4
|
+
plugins:
|
6
5
|
- rubocop-rake
|
6
|
+
- rubocop-rspec
|
7
7
|
|
8
8
|
AllCops:
|
9
9
|
TargetRubyVersion: 3.0
|
@@ -301,10 +301,6 @@ RSpec/IdenticalEqualityAssertion: # new in 2.4
|
|
301
301
|
Enabled: true
|
302
302
|
RSpec/SubjectDeclaration: # new in 2.5
|
303
303
|
Enabled: true
|
304
|
-
FactoryBot/SyntaxMethods: # new in 2.7
|
305
|
-
Enabled: true
|
306
|
-
RSpecRails/AvoidSetupHook: # new in 2.4
|
307
|
-
Enabled: true
|
308
304
|
Style/NestedFileDirname: # new in 1.26
|
309
305
|
Enabled: true
|
310
306
|
|
@@ -341,17 +337,10 @@ Style/MapCompactWithConditionalBlock: # new in 1.30
|
|
341
337
|
Enabled: true
|
342
338
|
RSpec/ChangeByZero: # new in 2.11.0
|
343
339
|
Enabled: true
|
344
|
-
Capybara/SpecificMatcher: # new in 2.12
|
345
|
-
Enabled: false
|
346
|
-
RSpecRails/HaveHttpStatus: # new in 2.12
|
347
|
-
Enabled: false
|
348
|
-
|
349
340
|
RSpec/ClassCheck: # new in 2.13
|
350
341
|
Enabled: true
|
351
342
|
RSpec/NoExpectationExample: # new in 2.13
|
352
343
|
Enabled: true
|
353
|
-
Capybara/SpecificFinders: # new in 2.13
|
354
|
-
Enabled: true
|
355
344
|
Gemspec/DevelopmentDependencies: # new in 1.44
|
356
345
|
Enabled: true
|
357
346
|
Lint/DuplicateMagicComment: # new in 1.37
|
@@ -378,29 +367,14 @@ Style/RedundantEach: # new in 1.38
|
|
378
367
|
Enabled: true
|
379
368
|
Style/RedundantStringEscape: # new in 1.37
|
380
369
|
Enabled: true
|
381
|
-
Capybara/MatchStyle: # new in <<next>>
|
382
|
-
Enabled: true
|
383
|
-
Capybara/NegationMatcher: # new in 2.14
|
384
|
-
Enabled: true
|
385
|
-
Capybara/SpecificActions: # new in 2.14
|
386
|
-
Enabled: true
|
387
370
|
RSpec/DuplicatedMetadata: # new in 2.16
|
388
371
|
Enabled: true
|
389
372
|
RSpec/PendingWithoutReason: # new in 2.16
|
390
373
|
Enabled: true
|
391
374
|
RSpec/SortMetadata: # new in 2.14
|
392
375
|
Enabled: true
|
393
|
-
FactoryBot/ConsistentParenthesesStyle: # new in 2.14
|
394
|
-
Enabled: true
|
395
|
-
FactoryBot/FactoryNameStyle: # new in 2.16
|
396
|
-
Enabled: true
|
397
|
-
RSpecRails/InferredSpecType: # new in 2.14
|
398
|
-
Enabled: true
|
399
|
-
RSpecRails/MinitestAssertions: # new in 2.17
|
400
|
-
Enabled: true
|
401
376
|
Style/RedundantHeredocDelimiterQuotes: # new in 1.45
|
402
377
|
Enabled: true
|
403
|
-
|
404
378
|
Metrics/CollectionLiteralLength: # new in 1.47
|
405
379
|
Enabled: true
|
406
380
|
Style/DirEmpty: # new in 1.48
|
@@ -411,9 +385,6 @@ RSpec/RedundantAround: # new in 2.19
|
|
411
385
|
Enabled: true
|
412
386
|
RSpec/SkipBlockInsideExample: # new in 2.19
|
413
387
|
Enabled: true
|
414
|
-
RSpecRails/TravelAround: # new in 2.19
|
415
|
-
Enabled: true
|
416
|
-
|
417
388
|
Lint/DuplicateMatchPattern: # new in 1.50
|
418
389
|
Enabled: true
|
419
390
|
Style/DataInheritance: # new in 1.49
|
@@ -428,12 +399,6 @@ Style/RedundantLineContinuation: # new in 1.49
|
|
428
399
|
Enabled: true
|
429
400
|
Style/RedundantRegexpConstructor: # new in 1.52
|
430
401
|
Enabled: true
|
431
|
-
FactoryBot/AssociationStyle: # new in 2.23
|
432
|
-
Enabled: true
|
433
|
-
FactoryBot/FactoryAssociationWithStrategy: # new in 2.23
|
434
|
-
Enabled: true
|
435
|
-
FactoryBot/RedundantFactoryOption: # new in 2.23
|
436
|
-
Enabled: true
|
437
402
|
RSpec/BeEmpty: # new in 2.20
|
438
403
|
Enabled: true
|
439
404
|
RSpec/ContainExactly: # new in 2.19
|
@@ -457,9 +422,6 @@ Style/YAMLFileRead: # new in 1.53
|
|
457
422
|
Enabled: true
|
458
423
|
RSpec/ReceiveMessages: # new in 2.23
|
459
424
|
Enabled: true
|
460
|
-
RSpecRails/NegationBeValid: # new in 2.23
|
461
|
-
Enabled: true
|
462
|
-
|
463
425
|
Lint/ItWithoutArgumentsInBlock: # new in 1.59
|
464
426
|
Enabled: true
|
465
427
|
Lint/LiteralAssignmentInCondition: # new in 1.58
|
@@ -468,18 +430,6 @@ Style/SingleLineDoEndBlock: # new in 1.57
|
|
468
430
|
Enabled: true
|
469
431
|
Style/SuperWithArgsParentheses: # new in 1.58
|
470
432
|
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
433
|
RSpec/EmptyMetadata: # new in 2.24
|
484
434
|
Enabled: true
|
485
435
|
RSpec/Eq: # new in 2.24
|
@@ -498,7 +448,6 @@ RSpec/IsExpectedSpecify: # new in 2.27
|
|
498
448
|
Enabled: true
|
499
449
|
RSpec/RepeatedSubjectCall: # new in 2.27
|
500
450
|
Enabled: true
|
501
|
-
|
502
451
|
Style/MapIntoArray: # new in 1.63
|
503
452
|
Enabled: true
|
504
453
|
Style/SendWithLiteralMethodName: # new in 1.64
|
@@ -511,7 +460,6 @@ RSpec/ExpectInLet: # new in 2.30
|
|
511
460
|
Enabled: true
|
512
461
|
RSpec/UndescriptiveLiteralsDescription: # new in 2.29
|
513
462
|
Enabled: true
|
514
|
-
|
515
463
|
Gemspec/AddRuntimeDependency: # new in 1.65
|
516
464
|
Enabled: true
|
517
465
|
Lint/DuplicateSetElement: # new in 1.67
|
@@ -532,3 +480,35 @@ Style/RedundantInterpolationUnfreeze: # new in 1.66
|
|
532
480
|
Enabled: true
|
533
481
|
Style/SafeNavigationChainLength: # new in 1.68
|
534
482
|
Enabled: false
|
483
|
+
Lint/ArrayLiteralInRegexp: # new in 1.71
|
484
|
+
Enabled: true
|
485
|
+
Lint/ConstantReassignment: # new in 1.70
|
486
|
+
Enabled: true
|
487
|
+
Lint/CopDirectiveSyntax: # new in 1.72
|
488
|
+
Enabled: true
|
489
|
+
Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69
|
490
|
+
Enabled: true
|
491
|
+
Lint/NumericOperationWithConstantResult: # new in 1.69
|
492
|
+
Enabled: true
|
493
|
+
Lint/RedundantTypeConversion: # new in 1.72
|
494
|
+
Enabled: true
|
495
|
+
Lint/SharedMutableDefault: # new in 1.70
|
496
|
+
Enabled: true
|
497
|
+
Lint/SuppressedExceptionInNumberConversion: # new in 1.72
|
498
|
+
Enabled: true
|
499
|
+
Lint/UselessConstantScoping: # new in 1.72
|
500
|
+
Enabled: true
|
501
|
+
Lint/UselessDefined: # new in 1.69
|
502
|
+
Enabled: true
|
503
|
+
Style/DigChain: # new in 1.69
|
504
|
+
Enabled: true
|
505
|
+
Style/FileNull: # new in 1.69
|
506
|
+
Enabled: true
|
507
|
+
Style/FileTouch: # new in 1.69
|
508
|
+
Enabled: true
|
509
|
+
Style/HashSlice: # new in 1.71
|
510
|
+
Enabled: true
|
511
|
+
Style/ItAssignment: # new in 1.70
|
512
|
+
Enabled: true
|
513
|
+
Style/RedundantFormat: # new in 1.72
|
514
|
+
Enabled: true
|
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.101.1)
|
5
5
|
activesupport
|
6
6
|
deprecation
|
7
7
|
dry-struct (~> 1.0)
|
@@ -19,7 +19,7 @@ PATH
|
|
19
19
|
GEM
|
20
20
|
remote: https://rubygems.org/
|
21
21
|
specs:
|
22
|
-
activesupport (8.0.
|
22
|
+
activesupport (8.0.2)
|
23
23
|
base64
|
24
24
|
benchmark (>= 0.3)
|
25
25
|
bigdecimal
|
@@ -32,12 +32,12 @@ GEM
|
|
32
32
|
securerandom (>= 0.3)
|
33
33
|
tzinfo (~> 2.0, >= 2.0.5)
|
34
34
|
uri (>= 0.13.1)
|
35
|
-
ast (2.4.
|
35
|
+
ast (2.4.3)
|
36
36
|
attr_extras (7.1.0)
|
37
37
|
base64 (0.2.0)
|
38
38
|
benchmark (0.4.0)
|
39
39
|
bigdecimal (3.1.9)
|
40
|
-
byebug (
|
40
|
+
byebug (12.0.0)
|
41
41
|
committee (5.0.0)
|
42
42
|
json_schema (~> 0.14, >= 0.14.3)
|
43
43
|
openapi_parser (~> 1.0)
|
@@ -46,7 +46,7 @@ GEM
|
|
46
46
|
connection_pool (2.5.0)
|
47
47
|
deprecation (1.1.0)
|
48
48
|
activesupport
|
49
|
-
diff-lcs (1.
|
49
|
+
diff-lcs (1.6.1)
|
50
50
|
docile (1.4.1)
|
51
51
|
drb (2.2.1)
|
52
52
|
dry-core (1.1.0)
|
@@ -59,7 +59,7 @@ GEM
|
|
59
59
|
concurrent-ruby (~> 1.0)
|
60
60
|
dry-core (~> 1.1)
|
61
61
|
zeitwerk (~> 2.6)
|
62
|
-
dry-struct (1.
|
62
|
+
dry-struct (1.8.0)
|
63
63
|
dry-core (~> 1.1)
|
64
64
|
dry-types (~> 1.8, >= 1.8.2)
|
65
65
|
ice_nine (~> 0.11)
|
@@ -78,28 +78,30 @@ GEM
|
|
78
78
|
i18n (1.14.7)
|
79
79
|
concurrent-ruby (~> 1.0)
|
80
80
|
ice_nine (0.11.2)
|
81
|
-
json (2.
|
81
|
+
json (2.10.2)
|
82
82
|
json_schema (0.21.0)
|
83
83
|
jsonpath (1.1.5)
|
84
84
|
multi_json
|
85
85
|
language_server-protocol (3.17.0.4)
|
86
|
-
|
86
|
+
lint_roller (1.1.0)
|
87
|
+
logger (1.7.0)
|
87
88
|
mini_portile2 (2.8.8)
|
88
|
-
minitest (5.25.
|
89
|
+
minitest (5.25.5)
|
89
90
|
multi_json (1.15.0)
|
90
|
-
nokogiri (1.18.
|
91
|
+
nokogiri (1.18.7)
|
91
92
|
mini_portile2 (~> 2.8.2)
|
92
93
|
racc (~> 1.4)
|
93
94
|
openapi_parser (1.0.0)
|
94
|
-
optimist (3.2.
|
95
|
+
optimist (3.2.1)
|
95
96
|
parallel (1.26.3)
|
96
|
-
parser (3.3.
|
97
|
+
parser (3.3.8.0)
|
97
98
|
ast (~> 2.4.1)
|
98
99
|
racc
|
99
100
|
patience_diff (1.2.0)
|
100
101
|
optimist (~> 3.0)
|
102
|
+
prism (1.4.0)
|
101
103
|
racc (1.8.1)
|
102
|
-
rack (3.1.
|
104
|
+
rack (3.1.13)
|
103
105
|
rainbow (3.1.1)
|
104
106
|
rake (13.2.1)
|
105
107
|
regexp_parser (2.10.0)
|
@@ -118,31 +120,26 @@ GEM
|
|
118
120
|
rspec-support (3.13.2)
|
119
121
|
rspec_junit_formatter (0.6.0)
|
120
122
|
rspec-core (>= 2, < 4, != 2.12.0)
|
121
|
-
rubocop (1.
|
123
|
+
rubocop (1.75.2)
|
122
124
|
json (~> 2.3)
|
123
|
-
language_server-protocol (
|
125
|
+
language_server-protocol (~> 3.17.0.2)
|
126
|
+
lint_roller (~> 1.1.0)
|
124
127
|
parallel (~> 1.10)
|
125
128
|
parser (>= 3.3.0.2)
|
126
129
|
rainbow (>= 2.2.2, < 4.0)
|
127
130
|
regexp_parser (>= 2.9.3, < 3.0)
|
128
|
-
rubocop-ast (>= 1.
|
131
|
+
rubocop-ast (>= 1.44.0, < 2.0)
|
129
132
|
ruby-progressbar (~> 1.7)
|
130
133
|
unicode-display_width (>= 2.4.0, < 4.0)
|
131
|
-
rubocop-ast (1.
|
132
|
-
parser (>= 3.3.
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
rubocop (
|
137
|
-
rubocop-
|
138
|
-
|
139
|
-
|
140
|
-
rubocop (~> 1.40)
|
141
|
-
rubocop-capybara (~> 2.17)
|
142
|
-
rubocop-factory_bot (~> 2.22)
|
143
|
-
rubocop-rspec_rails (~> 2.28)
|
144
|
-
rubocop-rspec_rails (2.29.1)
|
145
|
-
rubocop (~> 1.61)
|
134
|
+
rubocop-ast (1.44.1)
|
135
|
+
parser (>= 3.3.7.2)
|
136
|
+
prism (~> 1.4)
|
137
|
+
rubocop-rake (0.7.1)
|
138
|
+
lint_roller (~> 1.1)
|
139
|
+
rubocop (>= 1.72.1)
|
140
|
+
rubocop-rspec (3.5.0)
|
141
|
+
lint_roller (~> 1.1)
|
142
|
+
rubocop (~> 1.72, >= 1.72.1)
|
146
143
|
ruby-progressbar (1.13.0)
|
147
144
|
securerandom (0.4.1)
|
148
145
|
simplecov (0.22.0)
|
@@ -161,8 +158,8 @@ GEM
|
|
161
158
|
unicode-display_width (3.1.4)
|
162
159
|
unicode-emoji (~> 4.0, >= 4.0.4)
|
163
160
|
unicode-emoji (4.0.4)
|
164
|
-
uri (1.0.
|
165
|
-
zeitwerk (2.7.
|
161
|
+
uri (1.0.3)
|
162
|
+
zeitwerk (2.7.2)
|
166
163
|
|
167
164
|
PLATFORMS
|
168
165
|
ruby
|
@@ -177,8 +174,8 @@ DEPENDENCIES
|
|
177
174
|
rspec_junit_formatter
|
178
175
|
rubocop (~> 1.24)
|
179
176
|
rubocop-rake
|
180
|
-
rubocop-rspec
|
177
|
+
rubocop-rspec
|
181
178
|
simplecov
|
182
179
|
|
183
180
|
BUNDLED WITH
|
184
|
-
2.
|
181
|
+
2.6.8
|
data/cocina-models.gemspec
CHANGED
@@ -46,7 +46,7 @@ Gem::Specification.new do |spec|
|
|
46
46
|
spec.add_development_dependency 'rspec', '~> 3.0'
|
47
47
|
spec.add_development_dependency 'rubocop', '~> 1.24'
|
48
48
|
spec.add_development_dependency 'rubocop-rake'
|
49
|
-
spec.add_development_dependency 'rubocop-rspec'
|
49
|
+
spec.add_development_dependency 'rubocop-rspec'
|
50
50
|
spec.add_development_dependency 'simplecov'
|
51
51
|
spec.metadata['rubygems_mfa_required'] = 'true'
|
52
52
|
end
|
@@ -8,26 +8,28 @@ module Cocina
|
|
8
8
|
# TitleBuilder selects the prefered title from the cocina object for solr indexing
|
9
9
|
class TitleBuilder # rubocop:disable Metrics/ClassLength
|
10
10
|
extend Deprecation
|
11
|
-
# @param [
|
11
|
+
# @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
|
12
|
+
# @param [Array<Cocina::Models::FolioCatalogLink>] catalog_links the folio catalog links to check for digital serials part labels
|
12
13
|
# @param [Symbol] strategy ":first" is the strategy for selection when primary or display
|
13
14
|
# title are missing
|
14
15
|
# @param [Boolean] add_punctuation determines if the title should be formmated with punctuation
|
15
16
|
# @return [String, Array] the title value for Solr - for :first strategy, a string; for :all strategy, an array
|
16
17
|
# (e.g. title displayed in blacklight search results vs boosting values for search result rankings)
|
17
|
-
def self.build(titles, strategy: :first, add_punctuation: true)
|
18
|
+
def self.build(titles, catalog_links: [], strategy: :first, add_punctuation: true)
|
19
|
+
part_label = catalog_links.find { |link| link.catalog == 'folio' }&.partLabel
|
18
20
|
if titles.respond_to?(:description)
|
19
21
|
Deprecation.warn(self,
|
20
22
|
"Calling TitleBuilder.build with a #{titles.class} is deprecated. " \
|
21
23
|
'It must be called with an array of titles')
|
22
24
|
titles = titles.description.title
|
23
25
|
end
|
24
|
-
new(strategy: strategy, add_punctuation: add_punctuation).build(titles)
|
26
|
+
new(strategy: strategy, add_punctuation: add_punctuation, part_label: part_label).build(titles)
|
25
27
|
end
|
26
28
|
|
27
29
|
# the "main title" is the title withOUT subtitle, part name, etc. We want to index it separately so
|
28
30
|
# we can boost matches on it in search results (boost matching this string higher than matching full title string)
|
29
31
|
# e.g. "The Hobbit" (main_title) vs "The Hobbit, or, There and Back Again (full_title)
|
30
|
-
# @param [
|
32
|
+
# @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
|
31
33
|
# @return [Array<String>] the main title value(s) for Solr - array due to possible parallelValue
|
32
34
|
def self.main_title(titles)
|
33
35
|
new(strategy: :first, add_punctuation: false).main_title(titles)
|
@@ -35,7 +37,7 @@ module Cocina
|
|
35
37
|
|
36
38
|
# the "full title" is the title WITH subtitle, part name, etc. We want to able able to index it separately so
|
37
39
|
# we can boost matches on it in search results (boost matching this string higher than other titles present)
|
38
|
-
# @param [
|
40
|
+
# @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
|
39
41
|
# @return [Array<String>] the full title value(s) for Solr - array due to possible parallelValue
|
40
42
|
def self.full_title(titles)
|
41
43
|
[new(strategy: :first, add_punctuation: false, only_one_parallel_value: false).build(titles)].flatten.compact
|
@@ -43,7 +45,7 @@ module Cocina
|
|
43
45
|
|
44
46
|
# "additional titles" are all title data except for full_title. We want to able able to index it separately so
|
45
47
|
# we can boost matches on it in search results (boost matching these strings lower than other titles present)
|
46
|
-
# @param [
|
48
|
+
# @param [Array<Cocina::Models::Title,Cocina::Models::DescriptiveValue>] titles the titles to consider
|
47
49
|
# @return [Array<String>] the values for Solr
|
48
50
|
def self.additional_titles(titles)
|
49
51
|
[new(strategy: :all, add_punctuation: false).build(titles)].flatten - full_title(titles)
|
@@ -57,13 +59,16 @@ module Cocina
|
|
57
59
|
# of primary, untyped, first occurrence. When false, return an array containing all the parallel values.
|
58
60
|
# Why? Think of e.g. title displayed in blacklight search results vs boosting values for ranking of search
|
59
61
|
# results
|
60
|
-
|
62
|
+
# @param part_label [String] the partLabel to add for digital serials display
|
63
|
+
def initialize(strategy:, add_punctuation:, only_one_parallel_value: true, part_label: nil)
|
61
64
|
@strategy = strategy
|
62
65
|
@add_punctuation = add_punctuation
|
63
66
|
@only_one_parallel_value = only_one_parallel_value
|
67
|
+
@part_label = part_label
|
64
68
|
end
|
65
69
|
|
66
|
-
# @param [
|
70
|
+
# @param [Array<Cocina::Models::Title>] cocina_titles the titles to consider
|
71
|
+
# @param [String, nil] part_label the partLabel to add to the title for digital serials
|
67
72
|
# @return [String, Array] the title value for Solr - for :first strategy, a string; for :all strategy, an array
|
68
73
|
# (e.g. title displayed in blacklight search results vs boosting values for search result rankings)
|
69
74
|
#
|
@@ -71,9 +76,9 @@ module Cocina
|
|
71
76
|
def build(cocina_titles)
|
72
77
|
cocina_title = primary_title(cocina_titles) || untyped_title(cocina_titles)
|
73
78
|
cocina_title = other_title(cocina_titles) if cocina_title.blank?
|
74
|
-
|
75
79
|
if strategy == :first
|
76
|
-
extract_title(cocina_title)
|
80
|
+
result = extract_title(cocina_title)
|
81
|
+
add_part_label(result)
|
77
82
|
else
|
78
83
|
result = cocina_titles.map { |ctitle| extract_title(ctitle) }.flatten
|
79
84
|
if only_one_parallel_value? && result.length == 1
|
@@ -97,7 +102,13 @@ module Cocina
|
|
97
102
|
|
98
103
|
private
|
99
104
|
|
100
|
-
attr_reader :strategy
|
105
|
+
attr_reader :strategy, :part_label
|
106
|
+
|
107
|
+
def add_part_label(title)
|
108
|
+
# when a digital serial
|
109
|
+
title = "#{title.sub(/[ .,]*$/, '')}, #{part_label}" if part_label.present?
|
110
|
+
title
|
111
|
+
end
|
101
112
|
|
102
113
|
def extract_title(cocina_title)
|
103
114
|
title_values = if cocina_title.value
|
@@ -11,6 +11,10 @@ module Cocina
|
|
11
11
|
attribute :refresh, Types::Strict::Bool.default(false)
|
12
12
|
# Record identifier that is unique within the context of the linked record's catalog.
|
13
13
|
attribute :catalogRecordId, MigratedFromSymphonyIdentifier | MigratedFromVoyagerIdentifier | CreatedInFolioIdentifier
|
14
|
+
# Label for use in display of serials via Folio record
|
15
|
+
attribute? :partLabel, Types::Strict::String
|
16
|
+
# Sorting information for use in display of serials via Folio record
|
17
|
+
attribute? :sortKey, Types::Strict::String
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
@@ -178,6 +178,7 @@ module Cocina
|
|
178
178
|
end
|
179
179
|
|
180
180
|
XPATH_HAS_CONTENT_PREDICATE = '[string-length(normalize-space()) > 0]'
|
181
|
+
private_constant :XPATH_HAS_CONTENT_PREDICATE
|
181
182
|
|
182
183
|
def build_copyright_notice_event(origin_info_node)
|
183
184
|
date_nodes = origin_info_node.xpath("mods:copyrightDate#{XPATH_HAS_CONTENT_PREDICATE}",
|
@@ -56,6 +56,7 @@ module Cocina
|
|
56
56
|
end
|
57
57
|
|
58
58
|
LEGACY_EVENT_TYPES_2_TYPE = Cocina::Models::Mapping::FromMods::Event::LEGACY_EVENT_TYPES_2_TYPE
|
59
|
+
private_constant :LEGACY_EVENT_TYPES_2_TYPE
|
59
60
|
|
60
61
|
# because eventType is a relatively new addition to the MODS schema, records converted from MARC to MODS prior
|
61
62
|
# to its introduction used displayLabel as a stopgap measure, with certain values
|
@@ -21,6 +21,7 @@ module Cocina
|
|
21
21
|
|
22
22
|
validate_catalog('symphony')
|
23
23
|
validate_catalog('folio')
|
24
|
+
validate_sort_key
|
24
25
|
end
|
25
26
|
|
26
27
|
private
|
@@ -36,6 +37,17 @@ module Cocina
|
|
36
37
|
"(only one allowed) #{refresh_catalog_links}"
|
37
38
|
end
|
38
39
|
|
40
|
+
def validate_sort_key
|
41
|
+
# TODO: remove this validation once we upgrade to OpenAPI 3.1 and can use dependentRequired in openapi.yml
|
42
|
+
serials_links = catalog_links.select { |catalog_link| catalog_link[:catalog] == 'folio' && catalog_link[:sortKey].present? }
|
43
|
+
serials_links.each do |catalog_link|
|
44
|
+
# If partLabel is present, catalog_link is valid
|
45
|
+
next if catalog_link[:partLabel].present?
|
46
|
+
|
47
|
+
raise ValidationError, "partLabel must also be present if a sortKey is used in catalog link #{catalog_link}"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
39
51
|
def catalog_links
|
40
52
|
@catalog_links ||= Array(attributes.dig(:identification, :catalogLinks))
|
41
53
|
end
|
data/openapi.yml
CHANGED
@@ -1174,6 +1174,12 @@ components:
|
|
1174
1174
|
- $ref: '#/components/schemas/MigratedFromSymphonyIdentifier'
|
1175
1175
|
- $ref: '#/components/schemas/MigratedFromVoyagerIdentifier'
|
1176
1176
|
- $ref: '#/components/schemas/CreatedInFolioIdentifier'
|
1177
|
+
partLabel:
|
1178
|
+
description: Label for use in display of serials via Folio record
|
1179
|
+
type: string
|
1180
|
+
sortKey:
|
1181
|
+
description: Sorting information for use in display of serials via Folio record
|
1182
|
+
type: string
|
1177
1183
|
required:
|
1178
1184
|
- catalog
|
1179
1185
|
- catalogRecordId
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cocina-models
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.101.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Justin Coyne
|
8
|
-
autorequire:
|
9
8
|
bindir: exe
|
10
9
|
cert_chain: []
|
11
|
-
date: 2025-
|
10
|
+
date: 2025-04-18 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: activesupport
|
@@ -280,16 +279,16 @@ dependencies:
|
|
280
279
|
name: rubocop-rspec
|
281
280
|
requirement: !ruby/object:Gem::Requirement
|
282
281
|
requirements:
|
283
|
-
- - "
|
282
|
+
- - ">="
|
284
283
|
- !ruby/object:Gem::Version
|
285
|
-
version: '
|
284
|
+
version: '0'
|
286
285
|
type: :development
|
287
286
|
prerelease: false
|
288
287
|
version_requirements: !ruby/object:Gem::Requirement
|
289
288
|
requirements:
|
290
|
-
- - "
|
289
|
+
- - ">="
|
291
290
|
- !ruby/object:Gem::Version
|
292
|
-
version: '
|
291
|
+
version: '0'
|
293
292
|
- !ruby/object:Gem::Dependency
|
294
293
|
name: simplecov
|
295
294
|
requirement: !ruby/object:Gem::Requirement
|
@@ -521,7 +520,6 @@ homepage: https://github.com/sul-dlss/cocina-models
|
|
521
520
|
licenses: []
|
522
521
|
metadata:
|
523
522
|
rubygems_mfa_required: 'true'
|
524
|
-
post_install_message:
|
525
523
|
rdoc_options: []
|
526
524
|
require_paths:
|
527
525
|
- lib
|
@@ -536,8 +534,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
536
534
|
- !ruby/object:Gem::Version
|
537
535
|
version: '0'
|
538
536
|
requirements: []
|
539
|
-
rubygems_version: 3.
|
540
|
-
signing_key:
|
537
|
+
rubygems_version: 3.6.2
|
541
538
|
specification_version: 4
|
542
539
|
summary: Data models for the SDR
|
543
540
|
test_files: []
|