commonmeta-ruby 3.4.5 → 3.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/lib/commonmeta/author_utils.rb +103 -71
  4. data/lib/commonmeta/crossref_utils.rb +31 -25
  5. data/lib/commonmeta/metadata.rb +2 -8
  6. data/lib/commonmeta/metadata_utils.rb +4 -3
  7. data/lib/commonmeta/readers/bibtex_reader.rb +3 -3
  8. data/lib/commonmeta/readers/cff_reader.rb +7 -6
  9. data/lib/commonmeta/readers/codemeta_reader.rb +3 -3
  10. data/lib/commonmeta/readers/crossref_reader.rb +3 -5
  11. data/lib/commonmeta/readers/crossref_xml_reader.rb +7 -6
  12. data/lib/commonmeta/readers/csl_reader.rb +3 -4
  13. data/lib/commonmeta/readers/datacite_reader.rb +3 -5
  14. data/lib/commonmeta/readers/json_feed_reader.rb +2 -2
  15. data/lib/commonmeta/readers/npm_reader.rb +2 -2
  16. data/lib/commonmeta/readers/ris_reader.rb +1 -1
  17. data/lib/commonmeta/readers/schema_org_reader.rb +3 -3
  18. data/lib/commonmeta/schema_utils.rb +1 -1
  19. data/lib/commonmeta/utils.rb +4 -2
  20. data/lib/commonmeta/version.rb +1 -1
  21. data/lib/commonmeta/writers/bibtex_writer.rb +1 -1
  22. data/lib/commonmeta/writers/cff_writer.rb +5 -4
  23. data/lib/commonmeta/writers/codemeta_writer.rb +4 -2
  24. data/lib/commonmeta/writers/csv_writer.rb +4 -2
  25. data/lib/commonmeta/writers/datacite_writer.rb +1 -1
  26. data/lib/commonmeta/writers/jats_writer.rb +9 -5
  27. data/lib/commonmeta/writers/ris_writer.rb +2 -1
  28. data/lib/commonmeta/writers/schema_org_writer.rb +6 -3
  29. data/resources/{commonmeta_v0.9.3.json → commonmeta_v0.10.json} +62 -46
  30. data/spec/author_utils_spec.rb +16 -16
  31. data/spec/cli_spec.rb +1 -1
  32. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_crossref_metadata/missing_contributor.yml +307 -0
  33. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_datacite_metadata/SoftwareSourceCode.yml +76 -0
  34. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/book_oup.yml +107 -0
  35. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/journal_article_plos.yml +407 -0
  36. data/spec/metadata_spec.rb +2 -2
  37. data/spec/readers/bibtex_reader_spec.rb +5 -5
  38. data/spec/readers/cff_reader_spec.rb +127 -127
  39. data/spec/readers/codemeta_reader_spec.rb +11 -11
  40. data/spec/readers/crossref_reader_spec.rb +831 -835
  41. data/spec/readers/crossref_xml_reader_spec.rb +899 -901
  42. data/spec/readers/csl_reader_spec.rb +33 -33
  43. data/spec/readers/datacite_reader_spec.rb +106 -103
  44. data/spec/readers/json_feed_reader_spec.rb +40 -40
  45. data/spec/readers/npm_reader_spec.rb +32 -33
  46. data/spec/readers/ris_reader_spec.rb +36 -36
  47. data/spec/readers/schema_org_reader_spec.rb +284 -284
  48. data/spec/writers/codemeta_writer_spec.rb +19 -20
  49. data/spec/writers/crossref_xml_writer_spec.rb +73 -37
  50. data/spec/writers/datacite_writer_spec.rb +1 -1
  51. metadata +7 -3
@@ -101,6 +101,9 @@ module Commonmeta
101
101
  resource_type = resource_type.present? ? resource_type.underscore.camelcase : nil
102
102
  type = Commonmeta::Utils::CR_TO_CM_TRANSLATIONS.fetch(resource_type, 'Other')
103
103
 
104
+ contributors = crossref_people(bibmeta, 'author')
105
+ contributors += crossref_people(bibmeta, 'editor')
106
+
104
107
  titles = if bibmeta['titles'].present?
105
108
  Array.wrap(bibmeta['titles']).map do |r|
106
109
  if r.blank? || (r['title'].blank? && r['original_language_title'].blank?)
@@ -192,8 +195,7 @@ module Commonmeta
192
195
  'url' => url,
193
196
  'titles' => titles,
194
197
  'alternate_identifiers' => alternate_identifiers,
195
- 'creators' => crossref_people(bibmeta, 'author'),
196
- 'contributors' => crossref_people(bibmeta, 'editor'),
198
+ 'contributors' => contributors,
197
199
  'funding_references' => crossref_funding_reference(program_metadata),
198
200
  'publisher' => { 'name' => publisher },
199
201
  'container' => container,
@@ -296,11 +298,11 @@ module Commonmeta
296
298
  'givenName' => given_name,
297
299
  'familyName' => family_name,
298
300
  'affiliation' => affiliation.presence,
299
- 'contributorType' => contributor_role == 'editor' ? 'Editor' : nil }.compact
301
+ 'contributorRoles' => contributor_role == 'editor' ? ['Editor'] : ['Author'] }.compact
300
302
  else
301
303
  { 'type' => 'Organization',
302
304
  'name' => a['name'] || a['__content__'],
303
- 'contributorType' => contributor_role == 'editor' ? 'Editor' : nil }.compact
305
+ 'contributorRoles' => contributor_role == 'editor' ? ['Editor'] : ['Author'] }.compact
304
306
  end
305
307
  end
306
308
  end
@@ -359,7 +361,7 @@ module Commonmeta
359
361
  {
360
362
  'key' => reference.dig('key'),
361
363
  'doi' => doi ? normalize_doi(doi) : nil,
362
- 'creator' => reference.dig('author'),
364
+ 'contributor' => reference.dig('author'),
363
365
  'title' => reference.dig('article_title'),
364
366
  'publisher' => reference.dig('publisher'),
365
367
  'publicationYear' => reference.dig('cYear'),
@@ -369,7 +371,6 @@ module Commonmeta
369
371
  'lastPage' => reference.dig('last_page'),
370
372
  'containerTitle' => reference.dig('journal_title'),
371
373
  'edition' => nil,
372
- 'contributor' => nil,
373
374
  'unstructured' => doi.nil? ? reference.dig('unstructured') : nil
374
375
  }.compact
375
376
  end.unwrap
@@ -17,12 +17,12 @@ module Commonmeta
17
17
  citeproc_type = meta.fetch('type', nil)
18
18
  type = Commonmeta::Utils::CSL_TO_CM_TRANSLATIONS.fetch(citeproc_type, 'Other')
19
19
 
20
- creators = if meta.fetch('author', nil).present?
20
+ contributors = if meta.fetch('author', nil).present?
21
21
  get_authors(from_csl(Array.wrap(meta.fetch('author', nil))))
22
22
  else
23
- [{ 'type' => 'Organization', 'name' => ':(unav)' }]
23
+ [{ 'type' => 'Organization', 'name' => ':(unav)', 'contributorRoles' => ['Author'] }]
24
24
  end
25
- contributors = get_authors(from_csl(Array.wrap(meta.fetch('editor', nil))))
25
+ contributors += get_authors(from_csl(Array.wrap(meta.fetch('editor', nil))))
26
26
 
27
27
  date = {}
28
28
  d = get_date_from_date_parts(meta.fetch('issued', nil))
@@ -62,7 +62,6 @@ module Commonmeta
62
62
  'type' => type,
63
63
  'url' => normalize_id(meta.fetch('URL', nil)),
64
64
  'titles' => [{ 'title' => meta.fetch('title', nil) }],
65
- 'creators' => creators,
66
65
  'contributors' => contributors,
67
66
  'container' => container,
68
67
  'publisher' => if meta.fetch('publisher', nil)
@@ -53,10 +53,10 @@ module Commonmeta
53
53
  titles = Array.wrap(meta.fetch('titles', nil)).map do |title|
54
54
  title.compact
55
55
  end
56
- creators = get_authors(from_datacite(meta.fetch('creators', nil)))
56
+ contributors = get_authors(from_datacite(meta.fetch('creators', nil)))
57
+ contributors += get_authors(from_datacite(meta.fetch('contributors', nil)))
57
58
  publisher = { 'name' => meta.fetch('publisher', nil) }
58
59
 
59
- contributors = get_authors(from_datacite(meta.fetch('contributors', nil)))
60
60
  container = meta.fetch('container', nil)
61
61
  funding_references = meta.fetch('funding_references', nil)
62
62
 
@@ -98,7 +98,6 @@ module Commonmeta
98
98
  'additional_type' => resource_type == type ? nil : resource_type,
99
99
  'url' => url,
100
100
  'titles' => titles,
101
- 'creators' => creators,
102
101
  'contributors' => contributors,
103
102
  'container' => container,
104
103
  'publisher' => publisher,
@@ -150,7 +149,7 @@ module Commonmeta
150
149
  'key' => key,
151
150
  'doi' => doi,
152
151
  'url' => url,
153
- 'creator' => reference.dig('author'),
152
+ 'contributor' => reference.dig('author'),
154
153
  'title' => reference.dig('article-title'),
155
154
  'publisher' => reference.dig('publisher'),
156
155
  'publicationYear' => reference.dig('year'),
@@ -160,7 +159,6 @@ module Commonmeta
160
159
  'lastPage' => reference.dig('last-page'),
161
160
  'containerTitle' => reference.dig('journal-title'),
162
161
  'edition' => nil,
163
- 'contributor' => nil,
164
162
  'unstructured' => doi.nil? ? reference.dig('unstructured') : nil
165
163
  }.compact
166
164
  end
@@ -25,7 +25,7 @@ module Commonmeta
25
25
  id = url if id.blank? && url.present?
26
26
 
27
27
  type = "Article"
28
- creators = if meta.fetch("authors", nil).present?
28
+ contributors = if meta.fetch("authors", nil).present?
29
29
  get_authors(from_json_feed(Array.wrap(meta.fetch("authors"))))
30
30
  else
31
31
  [{ "type" => "Organization", "name" => ":(unav)" }]
@@ -70,7 +70,7 @@ module Commonmeta
70
70
  "type" => type,
71
71
  "url" => url,
72
72
  "titles" => titles,
73
- "creators" => creators,
73
+ "contributors" => contributors,
74
74
  "publisher" => publisher,
75
75
  "container" => container,
76
76
  "date" => date,
@@ -26,7 +26,7 @@ module Commonmeta
26
26
 
27
27
  type = 'Software'
28
28
 
29
- creators = get_authors(Array.wrap(meta.fetch('author', nil)))
29
+ contributors = get_authors(Array.wrap(meta.fetch('author', nil)))
30
30
  license = hsh_to_spdx('rightsIdentifier' => meta.fetch('license', nil))
31
31
 
32
32
  # container = if meta.fetch("container-title", nil).present?
@@ -71,7 +71,7 @@ module Commonmeta
71
71
  # "doi" => doi_from_url(doi),
72
72
  # "url" => normalize_id(meta.fetch("URL", nil)),
73
73
  'titles' => [{ 'title' => meta.fetch('name', nil) }],
74
- 'creators' => creators,
74
+ 'contributors' => contributors,
75
75
  # "contributors" => contributors,
76
76
  # "container" => container,
77
77
  # "publisher" => meta.fetch("publisher", nil),
@@ -41,7 +41,7 @@ module Commonmeta
41
41
  'type' => type,
42
42
  'url' => meta.fetch('UR', nil),
43
43
  'titles' => meta.fetch('T1', nil).present? ? [{ 'title' => meta.fetch('T1', nil) }] : nil,
44
- 'creators' => get_authors(author),
44
+ 'contributors' => get_authors(author),
45
45
  'publisher' => { 'name' => meta.fetch('PB', '(:unav)') },
46
46
  'container' => container,
47
47
  'date' => date,
@@ -106,8 +106,9 @@ module Commonmeta
106
106
  additional_type = meta.fetch('additionalType', nil)
107
107
  authors = meta.fetch('author', nil) || meta.fetch('creator', nil)
108
108
  # Authors should be an object, if it's just a plain string don't try and parse it.
109
- creators = get_authors(from_schema_org(Array.wrap(authors))) unless authors.is_a?(String)
110
- contributors = get_authors(from_schema_org(Array.wrap(meta.fetch('editor', nil))))
109
+ contributors = get_authors(from_schema_org(Array.wrap(authors))) unless authors.is_a?(String)
110
+ contributors = [] if contributors.nil?
111
+ contributors += get_authors(from_schema_org(Array.wrap(meta.fetch('editor', nil))))
111
112
  publisher = parse_attributes(meta.fetch('publisher', nil), content: 'name', first: true)
112
113
 
113
114
  ct = schema_org == 'Dataset' ? 'includedInDataCatalog' : 'Periodical'
@@ -230,7 +231,6 @@ module Commonmeta
230
231
  else
231
232
  [{ 'title' => meta.fetch('headline', nil) }]
232
233
  end,
233
- 'creators' => creators,
234
234
  'contributors' => contributors,
235
235
  'publisher' => { 'name' => publisher },
236
236
  'provider' => parse_attributes(meta.fetch('provider', nil), content: 'name', first: true),
@@ -5,7 +5,7 @@ require "pathname"
5
5
 
6
6
  module Commonmeta
7
7
  module SchemaUtils
8
- COMMONMETA = File.read(File.expand_path("../../resources/commonmeta_v0.9.3.json",
8
+ COMMONMETA = File.read(File.expand_path("../../resources/commonmeta_v0.10.json",
9
9
  __dir__))
10
10
 
11
11
  def json_schema_errors
@@ -869,7 +869,7 @@ module Commonmeta
869
869
  end
870
870
 
871
871
  def map_hash_keys(element: nil, mapping: nil)
872
- Array.wrap(element).map do |a|
872
+ a = Array.wrap(element).map do |a|
873
873
  a.map { |k, v| [mapping.fetch(k, k), v] }.reduce({}) do |hsh, (k, v)|
874
874
  if k == "affiliation" && v.is_a?(Array)
875
875
  hsh[k] = v.map do |affiliation|
@@ -883,6 +883,8 @@ module Commonmeta
883
883
  elsif k == "type" && v.is_a?(String)
884
884
  hsh[k] = v.capitalize
885
885
  hsh
886
+ elsif k == "contributorRoles"
887
+ hsh
886
888
  elsif v.is_a?(Hash)
887
889
  hsh[k] = to_schema_org(v)
888
890
  hsh
@@ -930,7 +932,7 @@ module Commonmeta
930
932
  a["given"] = a["givenName"]
931
933
  a["literal"] = a["name"] unless a["familyName"].present?
932
934
  a.except("nameType", "type", "@type", "id", "@id", "name", "familyName", "givenName",
933
- "affiliation", "contributorType").compact
935
+ "affiliation", "contributorRoles").compact
934
936
  end.presence
935
937
  end
936
938
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Commonmeta
4
- VERSION = '3.4.5'
4
+ VERSION = '3.5'
5
5
  end
@@ -13,7 +13,7 @@ module Commonmeta
13
13
  bibtex_key: normalize_id(id),
14
14
  doi: doi_from_url(id),
15
15
  url: url,
16
- author: authors_as_string(creators),
16
+ author: authors_as_string(contributors),
17
17
  keywords: if subjects.present?
18
18
  Array.wrap(subjects).map do |k|
19
19
  parse_attributes(k, content: 'subject', first: true)
@@ -10,14 +10,15 @@ module Commonmeta
10
10
  return nil unless %w[Software Collection].include?(type)
11
11
 
12
12
  title = parse_attributes(titles, content: 'title', first: true)
13
-
13
+ authors = Array.wrap(contributors).select { |c| c['contributorRoles'] == ['Author'] }
14
+
14
15
  hsh = {
15
16
  'cff-version' => '1.2.0',
16
17
  'message' => "If you use #{title} in your research, please cite it using the following metadata",
17
18
  'doi' => normalize_doi(id),
18
19
  'repository-code' => url,
19
20
  'title' => title,
20
- 'authors' => write_cff_creators(creators),
21
+ 'authors' => write_cff_contributors(authors),
21
22
  'abstract' => parse_attributes(descriptions, content: 'description', first: true),
22
23
  'version' => version,
23
24
  'keywords' => if subjects.present?
@@ -34,8 +35,8 @@ module Commonmeta
34
35
  hsh.to_yaml
35
36
  end
36
37
 
37
- def write_cff_creators(creators)
38
- Array.wrap(creators).map do |a|
38
+ def write_cff_contributors(contributors)
39
+ Array.wrap(contributors).map do |a|
39
40
  if a['givenName'].present? || a['id'].present?
40
41
  { 'given-names' => a['givenName'],
41
42
  'family-names' => a['familyName'],
@@ -5,7 +5,9 @@ module Commonmeta
5
5
  module CodemetaWriter
6
6
  def codemeta
7
7
  return nil unless valid? || show_errors
8
-
8
+
9
+ authors = Array.wrap(contributors).select { |c| c['contributorRoles'] == ['Author'] }
10
+
9
11
  hsh = {
10
12
  '@context' => id.present? ? 'https://raw.githubusercontent.com/codemeta/codemeta/master/codemeta.jsonld' : nil,
11
13
  '@type' => Commonmeta::Utils::CM_TO_SO_TRANSLATIONS.fetch(type, 'SoftwareSourceCode'),
@@ -13,7 +15,7 @@ module Commonmeta
13
15
  'identifier' => to_schema_org_identifiers(alternate_identifiers),
14
16
  'codeRepository' => url,
15
17
  'name' => parse_attributes(titles, content: 'title', first: true),
16
- 'authors' => creators,
18
+ 'authors' => to_schema_org(authors),
17
19
  'description' => parse_attributes(descriptions, content: 'description', first: true),
18
20
  'version' => version,
19
21
  'tags' => if subjects.present?
@@ -7,7 +7,9 @@ module Commonmeta
7
7
 
8
8
  def csv
9
9
  return nil unless valid?
10
-
10
+
11
+ authors = contributors.select { |c| c['contributorRoles'] == ['Author'] }
12
+
11
13
  bib = {
12
14
  doi: doi_from_url(id),
13
15
  url: url,
@@ -15,7 +17,7 @@ module Commonmeta
15
17
  state: state,
16
18
  type: Commonmeta::Utils::CM_TO_BIB_TRANSLATIONS.fetch(type, 'misc'),
17
19
  title: parse_attributes(titles, content: 'title', first: true),
18
- author: authors_as_string(creators),
20
+ author: authors_as_string(authors),
19
21
  publisher: publisher['name']
20
22
  }.values
21
23
 
@@ -22,7 +22,7 @@ module Commonmeta
22
22
  'doi' => doi_from_url(id),
23
23
  'url' => url,
24
24
  'types' => types,
25
- 'creators' => Array.wrap(creators).map { |c| datacite_contributor(c) },
25
+ 'creators' => Array.wrap(contributors).map { |c| datacite_contributor(c) },
26
26
  'titles' => titles,
27
27
  'publisher' => publisher.to_h['name'],
28
28
  'container' => container,
@@ -39,10 +39,12 @@ module Commonmeta
39
39
  end
40
40
 
41
41
  def insert_authors(xml)
42
- return unless creators.present?
43
-
42
+ authors = contributors.select { |c| c['contributorRoles'] == ['Author'] }
43
+
44
+ return unless authors.present?
45
+
44
46
  xml.send(:'person-group', 'person-group-type' => 'author') do
45
- Array.wrap(creators).each do |au|
47
+ Array.wrap(authors).each do |au|
46
48
  xml.name do
47
49
  insert_contributor(xml, au)
48
50
  end
@@ -51,10 +53,12 @@ module Commonmeta
51
53
  end
52
54
 
53
55
  def insert_editors(xml)
54
- return unless contributors.present?
56
+ editors = contributors.select { |c| c['contributorRoles'] == ['Editor'] }
57
+
58
+ return unless editors.present?
55
59
 
56
60
  xml.send(:'person-group', 'person-group-type' => 'editor') do
57
- Array.wrap(contributors).each do |con|
61
+ Array.wrap(editors).each do |con|
58
62
  xml.name do
59
63
  insert_contributor(xml, con)
60
64
  end
@@ -4,13 +4,14 @@ module Commonmeta
4
4
  module Writers
5
5
  module RisWriter
6
6
  def ris
7
+ authors = contributors.select { |c| c['contributorRoles'] == ['Author'] }
7
8
  sn = container.to_h['identifier']
8
9
  sn = sn.downcase if sn.present? && container.to_h['identifierType'] == 'DOI'
9
10
  {
10
11
  'TY' => Commonmeta::Utils::CM_TO_RIS_TRANSLATIONS.fetch(type, 'GEN'),
11
12
  'T1' => parse_attributes(titles, content: 'title', first: true),
12
13
  'T2' => container.to_h['title'],
13
- 'AU' => to_ris(creators),
14
+ 'AU' => to_ris(authors),
14
15
  'DO' => doi_from_url(id),
15
16
  'UR' => url,
16
17
  'AB' => parse_attributes(descriptions, content: 'description', first: true),
@@ -2,8 +2,11 @@
2
2
 
3
3
  module Commonmeta
4
4
  module Writers
5
- module SchemaOrgWriter
5
+ module SchemaOrgWriter
6
6
  def schema_hsh
7
+ authors = contributors.select { |c| c['contributorRoles'] == ['Author'] }
8
+ editors = contributors.select { |c| c['contributorRoles'] == ['Editor'] }
9
+
7
10
  { '@context' => 'http://schema.org',
8
11
  '@type' => Commonmeta::Utils::CM_TO_SO_TRANSLATIONS.fetch(type, 'CreativeWork'),
9
12
  '@id' => id,
@@ -11,8 +14,8 @@ module Commonmeta
11
14
  'url' => url,
12
15
  'additionalType' => additional_type,
13
16
  'name' => parse_attributes(titles, content: 'title', first: true),
14
- 'author' => to_schema_org(creators),
15
- 'editor' => to_schema_org(contributors),
17
+ 'author' => to_schema_org(authors),
18
+ 'editor' => to_schema_org(editors),
16
19
  'description' => parse_attributes(descriptions, content: 'description', first: true),
17
20
  'license' => license.to_h['url'],
18
21
  'version' => version,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "http://json-schema.org/draft-07/schema#",
3
- "$id": "https://commonmeta.org/commonmeta_v0.9.3.json",
4
- "title": "Commonmeta v0.9.3",
3
+ "$id": "https://commonmeta.org/commonmeta_v0.10.json",
4
+ "title": "Commonmeta v0.10",
5
5
  "description": "JSON representation of the Commonmeta schema.",
6
6
  "additionalProperties": false,
7
7
  "definitions": {
@@ -24,6 +24,38 @@
24
24
  },
25
25
  "uniqueItems": true
26
26
  },
27
+ "contributorRole": {
28
+ "description": "The type of contribution made by a contributor",
29
+ "enum": [
30
+ "Author",
31
+ "Editor",
32
+ "Chair",
33
+ "Reviewer",
34
+ "ReviewAssistant",
35
+ "StatsReviewer",
36
+ "ReviewerExternal",
37
+ "Reader",
38
+ "Translator",
39
+ "ContactPerson",
40
+ "Maintainer",
41
+ "Conceptualization",
42
+ "DataCuration",
43
+ "FormalAnalysis",
44
+ "FundingAcquisition",
45
+ "Investigation",
46
+ "Methodology",
47
+ "ProjectAdministration",
48
+ "Resources",
49
+ "Software",
50
+ "Supervision",
51
+ "Validation",
52
+ "Visualization",
53
+ "WritingOriginalDraft",
54
+ "WritingReviewEditing",
55
+ "Other"
56
+ ],
57
+ "type": "string"
58
+ },
27
59
  "latitude": {
28
60
  "type": "number",
29
61
  "minimum": -90,
@@ -91,36 +123,52 @@
91
123
  "type": "string",
92
124
  "format": "uri"
93
125
  },
94
- "creators": {
95
- "description": "The creators of the resource.",
126
+ "contributors": {
127
+ "description": "The contributors to the resource.",
96
128
  "type": "array",
97
129
  "items": {
98
130
  "type": "object",
99
131
  "properties": {
100
132
  "id": {
101
- "description": "The unique identifier for the creator.",
102
- "type": "string",
103
- "format": "uri"
133
+ "description": "The unique identifier for the contributor.",
134
+ "type": "string"
104
135
  },
105
136
  "type": {
106
- "description": "The type of the creator.",
137
+ "description": "The type of the contributor.",
107
138
  "type": "string",
108
139
  "enum": ["Organization", "Person"]
109
140
  },
141
+ "contributorRoles": {
142
+ "description": "List of roles assumed by the contributor when working on the resource.",
143
+ "items": {
144
+ "$ref": "#/definitions/contributorRole"
145
+ },
146
+ "type": "array",
147
+ "uniqueItems": true
148
+ },
110
149
  "name": {
111
- "description": "The name of the creator.",
150
+ "description": "The name of the contributor.",
112
151
  "type": "string"
113
152
  },
114
153
  "givenName": {
115
- "description": "The given name of the creator.",
154
+ "description": "The given name of the contributor.",
116
155
  "type": "string"
117
156
  },
118
157
  "familyName": {
119
- "description": "The family name of the creator.",
158
+ "description": "The family name of the contributor.",
120
159
  "type": "string"
121
160
  },
122
161
  "affiliation": { "$ref": "#/definitions/affiliations" }
123
- }
162
+ },
163
+ "anyOf": [
164
+ {
165
+ "required": ["familyName"]
166
+ },
167
+ {
168
+ "required": ["name"]
169
+ }
170
+ ],
171
+ "required": ["type", "contributorRoles"]
124
172
  },
125
173
  "minItems": 1,
126
174
  "uniqueItems": true
@@ -190,37 +238,6 @@
190
238
  }
191
239
  }
192
240
  },
193
- "contributors": {
194
- "description": "The contributors to the resource.",
195
- "type": "array",
196
- "items": {
197
- "type": "object",
198
- "properties": {
199
- "id": {
200
- "description": "The unique identifier for the contributor.",
201
- "type": "string"
202
- },
203
- "type": {
204
- "description": "The type of the contributor.",
205
- "type": "string",
206
- "enum": ["Organization", "Person"]
207
- },
208
- "name": {
209
- "description": "The name of the contributor.",
210
- "type": "string"
211
- },
212
- "givenName": {
213
- "description": "The given name of the contributor.",
214
- "type": "string"
215
- },
216
- "familyName": {
217
- "description": "The family name of the contributor.",
218
- "type": "string"
219
- },
220
- "affiliation": { "$ref": "#/definitions/affiliations" }
221
- }
222
- }
223
- },
224
241
  "subjects": {
225
242
  "type": "array",
226
243
  "items": {
@@ -271,7 +288,7 @@
271
288
  "properties": {
272
289
  "key": { "type": "string" },
273
290
  "doi": { "type": "string" },
274
- "creator": { "type": "string" },
291
+ "contributor": { "type": "string" },
275
292
  "title": { "type": "string" },
276
293
  "publisher": { "type": "string" },
277
294
  "publicationYear": { "type": "string" },
@@ -281,7 +298,6 @@
281
298
  "lastPage": { "type": "string" },
282
299
  "containerTitle": { "type": "string" },
283
300
  "edition": { "type": "string" },
284
- "contributor": { "type": "string" },
285
301
  "unstructured": { "type": "string" }
286
302
  },
287
303
  "required": ["key"]
@@ -443,5 +459,5 @@
443
459
  "enum": ["findable", "not_found"]
444
460
  }
445
461
  },
446
- "required": ["id", "type", "url", "creators", "titles", "publisher", "date"]
462
+ "required": ["id", "type", "url", "contributors", "titles", "publisher", "date"]
447
463
  }