commonmeta-ruby 3.4.4 → 3.5

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.
Files changed (53) 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 +3 -3
  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/get_json_feed_item_metadata/ghost_post_with_related_identifiers_and_funding.yml +36 -36
  35. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/get_json_feed_item_metadata/ghost_post_with_related_identifiers_and_link_to_peer-reviewed_article.yml +4911 -0
  36. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/book_oup.yml +107 -0
  37. data/spec/fixtures/vcr_cassettes/Commonmeta_Metadata/write_metadata_as_crossref/journal_article_plos.yml +407 -0
  38. data/spec/metadata_spec.rb +2 -2
  39. data/spec/readers/bibtex_reader_spec.rb +5 -5
  40. data/spec/readers/cff_reader_spec.rb +127 -127
  41. data/spec/readers/codemeta_reader_spec.rb +11 -11
  42. data/spec/readers/crossref_reader_spec.rb +831 -835
  43. data/spec/readers/crossref_xml_reader_spec.rb +899 -901
  44. data/spec/readers/csl_reader_spec.rb +33 -33
  45. data/spec/readers/datacite_reader_spec.rb +106 -103
  46. data/spec/readers/json_feed_reader_spec.rb +64 -38
  47. data/spec/readers/npm_reader_spec.rb +32 -33
  48. data/spec/readers/ris_reader_spec.rb +36 -36
  49. data/spec/readers/schema_org_reader_spec.rb +284 -284
  50. data/spec/writers/codemeta_writer_spec.rb +19 -20
  51. data/spec/writers/crossref_xml_writer_spec.rb +73 -37
  52. data/spec/writers/datacite_writer_spec.rb +1 -1
  53. metadata +8 -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,
@@ -109,7 +109,7 @@ module Commonmeta
109
109
 
110
110
  def get_related_identifiers(meta)
111
111
  # check that relationships resolve and has a supported type
112
- supported_types = %w[IsIdenticalTo isPreprintOf isTranslationOf]
112
+ supported_types = %w[IsIdenticalTo IsPreprintOf IsTranslationOf]
113
113
  Array.wrap(meta["relationships"]).reduce([]) do |sum, relationship|
114
114
  begin
115
115
  if supported_types.include?(relationship["type"]) && [200, 301, 302].include?(HTTP.head(relationship["url"]).status)
@@ -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.4'
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
  }