cocina-models 0.85.0 → 0.87.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) 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/contributor.rb +1 -0
  26. data/lib/cocina/models/created_in_folio_identifier.rb +9 -0
  27. data/lib/cocina/models/description.rb +1 -1
  28. data/lib/cocina/models/descriptive_parallel_contributor.rb +21 -0
  29. data/lib/cocina/models/doi.rb +7 -0
  30. data/lib/cocina/models/doi_exceptions.rb +1 -1
  31. data/lib/cocina/models/doi_pattern.rb +1 -1
  32. data/lib/cocina/models/dro.rb +2 -2
  33. data/lib/cocina/models/dro_with_metadata.rb +2 -2
  34. data/lib/cocina/models/druid.rb +1 -1
  35. data/lib/cocina/models/folio_catalog_link.rb +16 -0
  36. data/lib/cocina/models/identification.rb +3 -3
  37. data/lib/cocina/models/lane_medical_barcode.rb +1 -1
  38. data/lib/cocina/models/mapping/from_mods/identifier.rb +1 -1
  39. data/lib/cocina/models/mapping/from_mods/identifier_builder.rb +1 -1
  40. data/lib/cocina/models/mapping/normalizers/mods_normalizer.rb +2 -2
  41. data/lib/cocina/models/migrated_from_symphony_identifier.rb +9 -0
  42. data/lib/cocina/models/migrated_from_voyager_identifier.rb +9 -0
  43. data/lib/cocina/models/purl.rb +1 -1
  44. data/lib/cocina/models/related_resource.rb +1 -1
  45. data/lib/cocina/models/request_admin_policy.rb +1 -1
  46. data/lib/cocina/models/request_administrative.rb +1 -1
  47. data/lib/cocina/models/request_collection.rb +1 -1
  48. data/lib/cocina/models/request_dro.rb +1 -1
  49. data/lib/cocina/models/request_identification.rb +2 -2
  50. data/lib/cocina/models/source_id.rb +1 -1
  51. data/lib/cocina/models/standard_barcode.rb +1 -1
  52. data/lib/cocina/models/symphony_catalog_link.rb +17 -0
  53. data/lib/cocina/models/validators/description_types_validator.rb +1 -1
  54. data/lib/cocina/models/version.rb +1 -1
  55. data/lib/cocina/models.rb +7 -3
  56. data/openapi.yml +409 -317
  57. metadata +15 -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.
@@ -14,6 +14,7 @@ module Cocina
14
14
  attribute :note, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
15
15
  # URL or other pointer to the location of the contributor information.
16
16
  attribute? :valueAt, Types::Strict::String
17
+ attribute :parallelContributor, Types::Strict::Array.of(DescriptiveParallelContributor).default([].freeze)
17
18
  end
18
19
  end
19
20
  end
@@ -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
@@ -21,7 +21,7 @@ module Cocina
21
21
  # URL or other pointer to the location of the resource description.
22
22
  attribute? :valueAt, Types::Strict::String
23
23
  # Stanford persistent URL associated with the related resource.
24
- attribute :purl, Types::Strict::String
24
+ attribute :purl, Purl
25
25
  end
26
26
  end
27
27
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cocina
4
+ module Models
5
+ # DEPRECATED
6
+ # Value model for multiple representations of information about the same contributor (e.g. in different languages).
7
+ class DescriptiveParallelContributor < Struct
8
+ attribute :name, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
9
+ # Entity type of the contributor (person, organization, etc.). See https://github.com/sul-dlss/cocina-models/blob/main/docs/description_types.md for valid types.
10
+ attribute? :type, Types::Strict::String
11
+ # Status of the contributor relative to other parallel contributors (e.g. the primary author among a group of contributors).
12
+ attribute? :status, Types::Strict::String
13
+ attribute :role, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
14
+ attribute :identifier, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
15
+ attribute :note, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
16
+ # URL or other pointer to the location of the contributor information.
17
+ attribute? :valueAt, Types::Strict::String
18
+ attribute? :valueLanguage, DescriptiveValueLanguage.optional
19
+ end
20
+ end
21
+ 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
@@ -20,7 +20,7 @@ module Cocina
20
20
  attribute? :standard, Standard.optional
21
21
  attribute :subject, Types::Strict::Array.of(DescriptiveValue).default([].freeze)
22
22
  # Stanford persistent URL associated with the related resource.
23
- attribute? :purl, Types::Strict::String
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
@@ -71,7 +71,7 @@ module Cocina
71
71
  # Some part of the path are ignored for the purpose of matching.
72
72
  def clean_path(path)
73
73
  new_path = path.reject do |part|
74
- part.is_a?(Integer) || %i[parallelValue parallelEvent].include?(part)
74
+ part.is_a?(Integer) || %i[parallelValue parallelContributor parallelEvent].include?(part)
75
75
  end
76
76
  # This needs to happen after parallelValue is removed
77
77
  # to handle structuredValue > parallelValue > structuredValue
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Cocina
4
4
  module Models
5
- VERSION = '0.85.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