cocina-models 0.86.0 → 0.87.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +1 -1
  3. data/.rubocop.yml +52 -2
  4. data/.rubocop_todo.yml +49 -15
  5. data/Gemfile.lock +56 -52
  6. data/lib/cocina/generator/datatype.rb +1 -1
  7. data/lib/cocina/generator/generator.rb +19 -12
  8. data/lib/cocina/generator/schema.rb +4 -2
  9. data/lib/cocina/generator/schema_array.rb +1 -1
  10. data/lib/cocina/generator/schema_base.rb +36 -16
  11. data/lib/cocina/generator/schema_value.rb +2 -2
  12. data/lib/cocina/generator/union_type.rb +24 -0
  13. data/lib/cocina/models/admin_policy.rb +2 -2
  14. data/lib/cocina/models/admin_policy_administrative.rb +2 -2
  15. data/lib/cocina/models/admin_policy_with_metadata.rb +2 -2
  16. data/lib/cocina/models/administrative.rb +1 -1
  17. data/lib/cocina/models/barcode.rb +7 -0
  18. data/lib/cocina/models/business_barcode.rb +1 -1
  19. data/lib/cocina/models/catalog_link.rb +1 -10
  20. data/lib/cocina/models/catkey_barcode.rb +1 -1
  21. data/lib/cocina/models/cocina_version.rb +1 -1
  22. data/lib/cocina/models/collection.rb +2 -2
  23. data/lib/cocina/models/collection_identification.rb +1 -1
  24. data/lib/cocina/models/collection_with_metadata.rb +2 -2
  25. data/lib/cocina/models/created_in_folio_identifier.rb +9 -0
  26. data/lib/cocina/models/description.rb +2 -2
  27. data/lib/cocina/models/doi.rb +7 -0
  28. data/lib/cocina/models/doi_exceptions.rb +1 -1
  29. data/lib/cocina/models/doi_pattern.rb +1 -1
  30. data/lib/cocina/models/dro.rb +2 -2
  31. data/lib/cocina/models/dro_with_metadata.rb +2 -2
  32. data/lib/cocina/models/druid.rb +1 -1
  33. data/lib/cocina/models/folio_catalog_link.rb +16 -0
  34. data/lib/cocina/models/identification.rb +3 -3
  35. data/lib/cocina/models/lane_medical_barcode.rb +1 -1
  36. data/lib/cocina/models/mapping/from_mods/identifier.rb +1 -1
  37. data/lib/cocina/models/mapping/from_mods/identifier_builder.rb +1 -1
  38. data/lib/cocina/models/mapping/normalizers/mods_normalizer.rb +2 -2
  39. data/lib/cocina/models/migrated_from_symphony_identifier.rb +9 -0
  40. data/lib/cocina/models/migrated_from_voyager_identifier.rb +9 -0
  41. data/lib/cocina/models/purl.rb +1 -1
  42. data/lib/cocina/models/related_resource.rb +2 -2
  43. data/lib/cocina/models/request_admin_policy.rb +1 -1
  44. data/lib/cocina/models/request_administrative.rb +1 -1
  45. data/lib/cocina/models/request_collection.rb +1 -1
  46. data/lib/cocina/models/request_dro.rb +1 -1
  47. data/lib/cocina/models/request_identification.rb +2 -2
  48. data/lib/cocina/models/source_id.rb +1 -1
  49. data/lib/cocina/models/standard_barcode.rb +1 -1
  50. data/lib/cocina/models/symphony_catalog_link.rb +17 -0
  51. data/lib/cocina/models/version.rb +1 -1
  52. data/lib/cocina/models.rb +7 -3
  53. data/openapi.yml +366 -317
  54. metadata +14 -6
@@ -12,10 +12,10 @@ module Cocina
12
12
 
13
13
  # The version of Cocina with which this object conforms.
14
14
  # example: 1.2.3
15
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
15
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
16
16
  attribute :type, Types::Strict::String.enum(*AdminPolicyWithMetadata::TYPES)
17
17
  # example: druid:bc123df4567
18
- attribute :externalIdentifier, Types::Strict::String
18
+ attribute :externalIdentifier, Druid
19
19
  attribute :label, Types::Strict::String
20
20
  attribute :version, Types::Strict::Integer
21
21
  attribute(:administrative, AdminPolicyAdministrative.default { AdminPolicyAdministrative.new })
@@ -4,7 +4,7 @@ module Cocina
4
4
  module Models
5
5
  class Administrative < Struct
6
6
  # example: druid:bc123df4567
7
- attribute :hasAdminPolicy, Types::Strict::String
7
+ attribute :hasAdminPolicy, Druid
8
8
  attribute :releaseTags, Types::Strict::Array.of(ReleaseTag).default([].freeze)
9
9
  end
10
10
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ Barcode = BusinessBarcode | LaneMedicalBarcode | CatkeyBarcode | StandardBarcode
6
+ end
7
+ end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  BusinessBarcode = Types::String.constrained(
6
- format: /^2050[0-9]{7}$/i
6
+ format: /^2050[0-9]{7}$/
7
7
  )
8
8
  end
9
9
  end
@@ -2,15 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- class CatalogLink < Struct
6
- # Catalog that is the source of the linked record.
7
- # example: symphony
8
- attribute :catalog, Types::Strict::String.enum('symphony', 'previous symphony')
9
- # Only one of the catkeys should be designated for refreshing. This means that this key is the one used to pull metadata from the catalog if there is more than one key present.
10
- attribute :refresh, Types::Strict::Bool.default(false)
11
- # Record identifier that is unique within the context of the linked record's catalog.
12
- # example: 11403803
13
- attribute :catalogRecordId, Types::Strict::String
14
- end
5
+ CatalogLink = FolioCatalogLink | SymphonyCatalogLink
15
6
  end
16
7
  end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  CatkeyBarcode = Types::String.constrained(
6
- format: /^[0-9]+-[0-9]+$/i
6
+ format: /^[0-9]+-[0-9]+$/
7
7
  )
8
8
  end
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  CocinaVersion = Types::String.constrained(
6
- format: /^\d+\.\d+\.\d+$/i
6
+ format: /^\d+\.\d+\.\d+$/
7
7
  )
8
8
  end
9
9
  end
@@ -16,11 +16,11 @@ module Cocina
16
16
 
17
17
  # The version of Cocina with which this object conforms.
18
18
  # example: 1.2.3
19
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
19
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
20
20
  # The content type of the Collection. Selected from an established set of values.
21
21
  attribute :type, Types::Strict::String.enum(*Collection::TYPES)
22
22
  # example: druid:bc123df4567
23
- attribute :externalIdentifier, Types::Strict::String
23
+ attribute :externalIdentifier, Druid
24
24
  # Primary processing label (can be same as title) for a Collection.
25
25
  attribute :label, Types::Strict::String
26
26
  # Version for the Collection within SDR.
@@ -7,7 +7,7 @@ module Cocina
7
7
  # Unique identifier in some other system. This is because a large proportion of what is deposited in SDR, historically and currently, are representations of objects that are also represented in other systems. For example, digitized paper and A/V collections have physical manifestations, and those physical objects are managed in systems that have their own identifiers. Similarly, books have barcodes, archival materials have collection numbers and physical locations, etc. The sourceId allows determining if an item has been deposited before and where to look for the original item if you're looking at its SDR representation. The format is: "namespace:identifier"
8
8
 
9
9
  # example: sul:PC0170_s3_Fiesta_Bowl_2012-01-02_210609_2026
10
- attribute? :sourceId, Types::Strict::String
10
+ attribute? :sourceId, SourceId
11
11
  end
12
12
  end
13
13
  end
@@ -16,11 +16,11 @@ module Cocina
16
16
 
17
17
  # The version of Cocina with which this object conforms.
18
18
  # example: 1.2.3
19
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
19
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
20
20
  # The content type of the Collection. Selected from an established set of values.
21
21
  attribute :type, Types::Strict::String.enum(*CollectionWithMetadata::TYPES)
22
22
  # example: druid:bc123df4567
23
- attribute :externalIdentifier, Types::Strict::String
23
+ attribute :externalIdentifier, Druid
24
24
  # Primary processing label (can be same as title) for a Collection.
25
25
  attribute :label, Types::Strict::String
26
26
  # Version for the Collection within SDR.
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ CreatedInFolioIdentifier = Types::String.constrained(
6
+ format: /^in\d+$/
7
+ )
8
+ end
9
+ end
@@ -20,8 +20,8 @@ module Cocina
20
20
  attribute? :adminMetadata, DescriptiveAdminMetadata.optional
21
21
  # URL or other pointer to the location of the resource description.
22
22
  attribute? :valueAt, Types::Strict::String
23
- # Stanford persistent URL associated with the related resource. Note this is http, not https.
24
- attribute :purl, Types::Strict::String
23
+ # Stanford persistent URL associated with the related resource.
24
+ attribute :purl, Purl
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ DOI = DoiPattern | DoiExceptions
6
+ end
7
+ end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  DoiExceptions = Types::String.constrained(
6
- format: %r{^10\.(25740/([vV][aA]90-[cC][tT]15|[sS][yY][xX][aA]-[mM]256|12[qQ][fF]-5243|65[jJ]8-6114)|25936/629[tT]-[bB][xX]79)$}i
6
+ format: %r{^10\.(25740/([vV][aA]90-[cC][tT]15|[sS][yY][xX][aA]-[mM]256|12[qQ][fF]-5243|65[jJ]8-6114)|25936/629[tT]-[bB][xX]79)$}
7
7
  )
8
8
  end
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  DoiPattern = Types::String.constrained(
6
- format: %r{^10\.(25740|80343)/[b-df-hjkmnp-tv-z]{2}[0-9]{3}[b-df-hjkmnp-tv-z]{2}[0-9]{4}$}i
6
+ format: %r{^10\.(25740|80343)/[b-df-hjkmnp-tv-z]{2}[0-9]{3}[b-df-hjkmnp-tv-z]{2}[0-9]{4}$}
7
7
  )
8
8
  end
9
9
  end
@@ -26,11 +26,11 @@ module Cocina
26
26
 
27
27
  # The version of Cocina with which this object conforms.
28
28
  # example: 1.2.3
29
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
29
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
30
30
  # The content type of the DRO. Selected from an established set of values.
31
31
  attribute :type, Types::Strict::String.enum(*DRO::TYPES)
32
32
  # example: druid:bc123df4567
33
- attribute :externalIdentifier, Types::Strict::String
33
+ attribute :externalIdentifier, Druid
34
34
  # Primary processing label (can be same as title) for a DRO.
35
35
  attribute :label, Types::Strict::String
36
36
  # Version for the DRO within SDR.
@@ -26,11 +26,11 @@ module Cocina
26
26
 
27
27
  # The version of Cocina with which this object conforms.
28
28
  # example: 1.2.3
29
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
29
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
30
30
  # The content type of the DRO. Selected from an established set of values.
31
31
  attribute :type, Types::Strict::String.enum(*DROWithMetadata::TYPES)
32
32
  # example: druid:bc123df4567
33
- attribute :externalIdentifier, Types::Strict::String
33
+ attribute :externalIdentifier, Druid
34
34
  # Primary processing label (can be same as title) for a DRO.
35
35
  attribute :label, Types::Strict::String
36
36
  # Version for the DRO within SDR.
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  Druid = Types::String.constrained(
6
- format: /^druid:[b-df-hjkmnp-tv-z]{2}[0-9]{3}[b-df-hjkmnp-tv-z]{2}[0-9]{4}$/i
6
+ format: /^druid:[b-df-hjkmnp-tv-z]{2}[0-9]{3}[b-df-hjkmnp-tv-z]{2}[0-9]{4}$/
7
7
  )
8
8
  end
9
9
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ # A linkage between an object and a Folio catalog record
6
+ class FolioCatalogLink < Struct
7
+ # Catalog that is the source of the linked record.
8
+ # example: folio
9
+ attribute :catalog, Types::Strict::String.enum('folio', 'previous folio')
10
+ # Only one of the catkeys should be designated for refreshing. This means that this key is the one used to pull metadata from the catalog if there is more than one key present.
11
+ attribute :refresh, Types::Strict::Bool.default(false)
12
+ # Record identifier that is unique within the context of the linked record's catalog.
13
+ attribute :catalogRecordId, MigratedFromSymphonyIdentifier | MigratedFromVoyagerIdentifier | CreatedInFolioIdentifier
14
+ end
15
+ end
16
+ end
@@ -4,14 +4,14 @@ module Cocina
4
4
  module Models
5
5
  class Identification < Struct
6
6
  # A barcode
7
- attribute? :barcode, Types::Nominal::Any
7
+ attribute? :barcode, Barcode
8
8
  attribute :catalogLinks, Types::Strict::Array.of(CatalogLink).default([].freeze)
9
9
  # Digital Object Identifier (https://www.doi.org)
10
- attribute? :doi, Types::Nominal::Any
10
+ attribute? :doi, DOI
11
11
  # Unique identifier in some other system. This is because a large proportion of what is deposited in SDR, historically and currently, are representations of objects that are also represented in other systems. For example, digitized paper and A/V collections have physical manifestations, and those physical objects are managed in systems that have their own identifiers. Similarly, books have barcodes, archival materials have collection numbers and physical locations, etc. The sourceId allows determining if an item has been deposited before and where to look for the original item if you're looking at its SDR representation. The format is: "namespace:identifier"
12
12
 
13
13
  # example: sul:PC0170_s3_Fiesta_Bowl_2012-01-02_210609_2026
14
- attribute :sourceId, Types::Strict::String
14
+ attribute :sourceId, SourceId
15
15
  end
16
16
  end
17
17
  end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  LaneMedicalBarcode = Types::String.constrained(
6
- format: /^245[0-9]{8}$/i
6
+ format: /^245[0-9]{8}$/
7
7
  )
8
8
  end
9
9
  end
@@ -42,7 +42,7 @@ module Cocina
42
42
  def identifiers
43
43
  (resource_element.xpath('mods:identifier', mods: Description::DESC_METADATA_NS) +
44
44
  resource_element.xpath('mods:recordIdentifier',
45
- mods: Description::DESC_METADATA_NS)).reject { |identifier_node| identifier_node.text.blank? && identifier_node.attributes.size.zero? }
45
+ mods: Description::DESC_METADATA_NS)).reject { |identifier_node| identifier_node.text.blank? && identifier_node.attributes.empty? }
46
46
  end
47
47
  end
48
48
  end
@@ -31,7 +31,7 @@ module Cocina
31
31
  end
32
32
 
33
33
  def build
34
- return if identifier_element.text.blank? && identifier_element.attributes.size.zero?
34
+ return if identifier_element.text.blank? && identifier_element.attributes.empty?
35
35
 
36
36
  {
37
37
  displayLabel: identifier_element['displayLabel']
@@ -105,9 +105,9 @@ module Cocina
105
105
  return unless start_node
106
106
 
107
107
  # remove node if there are no element children, there is no text value and there are no attributes
108
- if start_node.elements.size.zero? &&
108
+ if start_node.elements.empty? &&
109
109
  start_node.text.blank? &&
110
- start_node.attributes.size.zero? &&
110
+ start_node.attributes.empty? &&
111
111
  start_node.name != 'etal'
112
112
  parent = start_node.parent
113
113
  start_node.remove
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ MigratedFromSymphonyIdentifier = Types::String.constrained(
6
+ format: /^a\d+$/
7
+ )
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ MigratedFromVoyagerIdentifier = Types::String.constrained(
6
+ format: /^L\d+$/
7
+ )
8
+ end
9
+ end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  Purl = Types::String.constrained(
6
- format: %r{^https://}i
6
+ format: %r{^https://}
7
7
  )
8
8
  end
9
9
  end
@@ -19,8 +19,8 @@ module Cocina
19
19
  attribute :identifier, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
20
20
  attribute? :standard, Standard.optional
21
21
  attribute :subject, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
22
- # Stanford persistent URL associated with the related resource. Note this is http, not https.
23
- attribute? :purl, Types::Strict::String
22
+ # Stanford persistent URL associated with the related resource.
23
+ attribute? :purl, Purl
24
24
  attribute? :access, DescriptiveAccessMetadata.optional
25
25
  attribute :relatedResource, Types::Strict::Array.of(RelatedResource).default([].freeze)
26
26
  attribute? :adminMetadata, DescriptiveAdminMetadata.optional
@@ -12,7 +12,7 @@ module Cocina
12
12
 
13
13
  # The version of Cocina with which this object conforms.
14
14
  # example: 1.2.3
15
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
15
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
16
16
  attribute :type, Types::Strict::String.enum(*RequestAdminPolicy::TYPES)
17
17
  attribute :label, Types::Strict::String
18
18
  attribute :version, Types::Strict::Integer.default(1).enum(1)
@@ -4,7 +4,7 @@ module Cocina
4
4
  module Models
5
5
  class RequestAdministrative < Struct
6
6
  # example: druid:bc123df4567
7
- attribute :hasAdminPolicy, Types::Strict::String
7
+ attribute :hasAdminPolicy, Druid
8
8
  attribute :releaseTags, Types::Strict::Array.of(ReleaseTag).default([].freeze)
9
9
  # Internal project this resource is a part of. This governs routing of messages about this object.
10
10
  # example: Google Books
@@ -16,7 +16,7 @@ module Cocina
16
16
 
17
17
  # The version of Cocina with which this object conforms.
18
18
  # example: 1.2.3
19
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
19
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
20
20
  attribute :type, Types::Strict::String.enum(*RequestCollection::TYPES)
21
21
  attribute :label, Types::Strict::String
22
22
  attribute :version, Types::Strict::Integer.default(1).enum(1)
@@ -26,7 +26,7 @@ module Cocina
26
26
 
27
27
  # The version of Cocina with which this object conforms.
28
28
  # example: 1.2.3
29
- attribute :cocinaVersion, Types::Strict::String.default(Cocina::Models::VERSION)
29
+ attribute :cocinaVersion, CocinaVersion.default(VERSION)
30
30
  attribute :type, Types::Strict::String.enum(*RequestDRO::TYPES)
31
31
  attribute :label, Types::Strict::String
32
32
  attribute :version, Types::Strict::Integer.default(1).enum(1)
@@ -5,12 +5,12 @@ module Cocina
5
5
  # Same as a Identification, but requires a sourceId and doesn't permit a DOI.
6
6
  class RequestIdentification < Struct
7
7
  # A barcode
8
- attribute? :barcode, Types::Nominal::Any
8
+ attribute? :barcode, Barcode
9
9
  attribute :catalogLinks, Types::Strict::Array.of(CatalogLink).default([].freeze)
10
10
  # Unique identifier in some other system. This is because a large proportion of what is deposited in SDR, historically and currently, are representations of objects that are also represented in other systems. For example, digitized paper and A/V collections have physical manifestations, and those physical objects are managed in systems that have their own identifiers. Similarly, books have barcodes, archival materials have collection numbers and physical locations, etc. The sourceId allows determining if an item has been deposited before and where to look for the original item if you're looking at its SDR representation. The format is: "namespace:identifier"
11
11
 
12
12
  # example: sul:PC0170_s3_Fiesta_Bowl_2012-01-02_210609_2026
13
- attribute :sourceId, Types::Strict::String
13
+ attribute :sourceId, SourceId
14
14
  end
15
15
  end
16
16
  end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  SourceId = Types::String.constrained(
6
- format: /^.+:.+$/i
6
+ format: /^.+:.+$/
7
7
  )
8
8
  end
9
9
  end
@@ -3,7 +3,7 @@
3
3
  module Cocina
4
4
  module Models
5
5
  StandardBarcode = Types::String.constrained(
6
- format: /^36105[0-9]{9}$/i
6
+ format: /^36105[0-9]{9}$/
7
7
  )
8
8
  end
9
9
  end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ # A linkage between an object and a Symphony catalog record
6
+ class SymphonyCatalogLink < Struct
7
+ # Catalog that is the source of the linked record.
8
+ # example: symphony
9
+ attribute :catalog, Types::Strict::String.enum('symphony', 'previous symphony')
10
+ # Only one of the catkeys should be designated for refreshing. This means that this key is the one used to pull metadata from the catalog if there is more than one key present.
11
+ attribute :refresh, Types::Strict::Bool.default(false)
12
+ # Record identifier that is unique within the context of the linked record's catalog.
13
+ # example: 11403803
14
+ attribute :catalogRecordId, Types::Strict::String.constrained(format: /^\d+$/)
15
+ end
16
+ end
17
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.86.0'
5
+ VERSION = '0.87.0'
6
6
  end
7
7
  end
data/lib/cocina/models.rb CHANGED
@@ -148,9 +148,13 @@ module Cocina
148
148
  end
149
149
 
150
150
  def self.type_for(dyn)
151
- dyn.with_indifferent_access.fetch('type')
152
- rescue KeyError
153
- raise ValidationError, 'Type field not found'
151
+ # Intentionally checking both string- and symbol-type keys in the hash via `#[]`
152
+ # instead of `#with_indifferent_access` (and/or `#fetch`) in order to be more memory-efficient
153
+ object_type = dyn[:type] || dyn['type']
154
+
155
+ raise(ValidationError, 'Type field not found') unless object_type
156
+
157
+ object_type
154
158
  end
155
159
  private_class_method :type_for
156
160