json-ld 3.3.0 → 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af55e45e1d219198dd9328c409c201ecc8afa0898978121c6cf47bfb85cd436e
4
- data.tar.gz: f90141a3b8b253f8ec95fcc87a8adf8cec8ef973c32049a6e4bed9ad7b6cf7cb
3
+ metadata.gz: d001920e29ad882ce1ffd196b475b8fdbf4b7ed3f8bf5e569713fa93efda5cf9
4
+ data.tar.gz: f30409b4fc97e1e604a003f0973c20c75cb4c705852d9622aad15d94c574eafb
5
5
  SHA512:
6
- metadata.gz: c1e532afa627d9bd4fed6cb7224fc34c37c8eef7f5435994fc75c13a9efd8c27a6c49509b658aec6937dab27313d69b15fa00f33e27f8bf50462115fe2718359
7
- data.tar.gz: 7f60b2dd9a1f84920b74821c2f9e171706c9dccc90b3ad1777b65846a19115aaf1a3b8119cb0f34036b85a12d68ca50aa540364dcb1db57fd24a76f85e91789e
6
+ metadata.gz: cbb8283e5bf415a9cb05f17f29947d7f546699f8a5fa0c674559b5343ff344d87a36c15b26389bae813fb9daac26876b8ddaa2871181cd2c0ab49c513b5f96e6
7
+ data.tar.gz: 111003a143c84c9820c120bbc42c5199b493cbcd4b1b33de64ef65ea578ba4130aec6e4c534121299f5e2420d51984901056d52a5c856a7c79069c00fb9f257f
data/README.md CHANGED
@@ -603,6 +603,10 @@ To get a local working copy of the development repository, do:
603
603
 
604
604
  % git clone git://github.com/ruby-rdf/json-ld.git
605
605
 
606
+ ## Change Log
607
+
608
+ See [Release Notes on GitHub](https://github.com/ruby-rdf/json-ld/releases)
609
+
606
610
  ## Mailing List
607
611
  * <https://lists.w3.org/Archives/Public/public-rdf-ruby/>
608
612
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.3.0
1
+ 3.3.2
data/lib/json/ld/api.rb CHANGED
@@ -290,8 +290,7 @@ module JSON
290
290
  def self.flatten(input, context, expanded: false, serializer: nil, **options)
291
291
  flattened = []
292
292
  options = {
293
- compactToRelative: true,
294
- extractAllScripts: true
293
+ compactToRelative: true
295
294
  }.merge(options)
296
295
 
297
296
  # Expand input to simplify processing
@@ -518,6 +517,8 @@ module JSON
518
517
  # @option options (see #initialize)
519
518
  # @option options [Boolean] :produceGeneralizedRdf (false)
520
519
  # If true, output will include statements having blank node predicates, otherwise they are dropped.
520
+ # @option options [Boolean] :extractAllScripts (true)
521
+ # If set, when given an HTML input without a fragment identifier, extracts all `script` elements with type `application/ld+json` into an array during expansion.
521
522
  # @raise [JsonLdError]
522
523
  # @yield statement
523
524
  # @yieldparam [RDF::Statement] statement
@@ -638,7 +639,7 @@ module JSON
638
639
  options[:headers]['Accept'].sub('application/ld+json,',
639
640
  "application/ld+json;profile=#{requestProfile}, application/ld+json;q=0.9,")
640
641
  end
641
- documentLoader.call(url, **options) do |remote_doc|
642
+ documentLoader.call(url, extractAllScripts: extractAllScripts, **options) do |remote_doc|
642
643
  case remote_doc
643
644
  when RDF::Util::File::RemoteDocument
644
645
  # Convert to RemoteDocument
@@ -758,6 +759,28 @@ module JSON
758
759
  alias fromRDF fromRdf
759
760
  end
760
761
 
762
+ ##
763
+ # Hash of recognized script types and the loaders that decode them
764
+ # into a hash or array of hashes.
765
+ #
766
+ # @return Hash{type, Proc}
767
+ SCRIPT_LOADERS = {
768
+ 'application/ld+json' => ->(content, url:, **options) do
769
+ validate_input(content, url: url) if options[:validate]
770
+ mj_opts = options.keep_if { |k, v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v) }
771
+ MultiJson.load(content, **mj_opts)
772
+ end
773
+ }
774
+
775
+ ##
776
+ # Adds a loader for some specific content type
777
+ #
778
+ # @param [String] type
779
+ # @param [Proc] loader
780
+ def self.add_script_loader(type, loader)
781
+ SCRIPT_LOADERS[type] = loader
782
+ end
783
+
761
784
  ##
762
785
  # Load one or more script tags from an HTML source.
763
786
  # Unescapes and uncomments input, returns the internal representation
@@ -812,47 +835,52 @@ module JSON
812
835
  element = input.at_xpath("//script[@id='#{id}']")
813
836
  raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found with id=#{id}" unless element
814
837
 
815
- unless element.attributes['type'].to_s.start_with?('application/ld+json')
838
+ script_type = SCRIPT_LOADERS.keys.detect {|type| element.attributes['type'].to_s.start_with?(type)}
839
+ unless script_type
816
840
  raise JSON::LD::JsonLdError::LoadingDocumentFailed,
817
841
  "Script tag has type=#{element.attributes['type']}"
818
842
  end
819
843
 
820
- content = element.inner_html
821
- validate_input(content, url: url) if options[:validate]
822
- mj_opts = options.keep_if { |k, v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v) }
823
- MultiJson.load(content, **mj_opts)
844
+ loader = SCRIPT_LOADERS[script_type]
845
+ loader.call(element.inner_html, url: url, **options)
824
846
  elsif extractAllScripts
825
847
  res = []
826
- elements = if profile
827
- es = input.xpath("//script[starts-with(@type, 'application/ld+json;profile=#{profile}')]")
828
- # If no profile script, just take a single script without profile
829
- es = [input.at_xpath("//script[starts-with(@type, 'application/ld+json')]")].compact if es.empty?
830
- es
831
- else
832
- input.xpath("//script[starts-with(@type, 'application/ld+json')]")
833
- end
834
- elements.each do |element|
835
- content = element.inner_html
836
- validate_input(content, url: url) if options[:validate]
837
- mj_opts = options.keep_if { |k, v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v) }
838
- r = MultiJson.load(content, **mj_opts)
839
- if r.is_a?(Hash)
840
- res << r
841
- elsif r.is_a?(Array)
842
- res.concat(r)
848
+
849
+ SCRIPT_LOADERS.each do |type, loader|
850
+ elements = if profile
851
+ es = input.xpath("//script[starts-with(@type, '#{type};profile=#{profile}')]")
852
+ # If no profile script, just take a single script without profile
853
+ es = [input.at_xpath("//script[starts-with(@type, '#{type}')]")].compact if es.empty?
854
+ es
855
+ else
856
+ input.xpath("//script[starts-with(@type, '#{type}')]")
857
+ end
858
+ elements.each do |element|
859
+ content = element.inner_html
860
+ r = loader.call(content, url: url, extractAllScripts: true, **options)
861
+ if r.is_a?(Hash)
862
+ res << r
863
+ elsif r.is_a?(Array)
864
+ res.concat(r)
865
+ end
843
866
  end
844
867
  end
845
868
  res
846
869
  else
847
- # Find the first script with type application/ld+json.
848
- element = input.at_xpath("//script[starts-with(@type, 'application/ld+json;profile=#{profile}')]") if profile
849
- element ||= input.at_xpath("//script[starts-with(@type, 'application/ld+json')]")
850
- raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found" unless element
870
+ # Find the first script with a known type
871
+ script_type, element = nil, nil
872
+ SCRIPT_LOADERS.keys.each do |type|
873
+ next if script_type # already found the type
874
+ element = input.at_xpath("//script[starts-with(@type, '#{type};profile=#{profile}')]") if profile
875
+ element ||= input.at_xpath("//script[starts-with(@type, '#{type}')]")
876
+ script_type = type if element
877
+ end
878
+ unless script_type
879
+ raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found" unless element
880
+ end
851
881
 
852
882
  content = element.inner_html
853
- validate_input(content, url: url) if options[:validate]
854
- mj_opts = options.keep_if { |k, v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v) }
855
- MultiJson.load(content, **mj_opts)
883
+ SCRIPT_LOADERS[script_type].call(content, url: url, **options)
856
884
  end
857
885
  rescue MultiJson::ParseError => e
858
886
  raise JSON::LD::JsonLdError::InvalidScriptElement, e.message
@@ -299,10 +299,10 @@ module JSON
299
299
  else
300
300
  index_key = context.expand_iri(index_key, vocab: true)
301
301
  container_key = context.compact_iri(index_key, vocab: true)
302
- map_key, *others = Array(compacted_item[container_key])
302
+ map_key, *others = Array(compacted_item.is_a?(Hash) && compacted_item[container_key])
303
303
  if map_key.is_a?(String)
304
304
  case others.length
305
- when 0 then compacted_item.delete(container_key)
305
+ when 0 then compacted_item.delete(container_key) if compacted_item.is_a?(Hash)
306
306
  when 1 then compacted_item[container_key] = others.first
307
307
  else compacted_item[container_key] = others
308
308
  end
@@ -316,15 +316,15 @@ module JSON
316
316
  map_key = expanded_item['@language']
317
317
  value?(expanded_item) ? expanded_item['@value'] : compacted_item
318
318
  elsif container.include?('@type')
319
- map_key, *types = Array(compacted_item[container_key])
319
+ map_key, *types = Array(compacted_item.is_a?(Hash) && compacted_item[container_key])
320
320
  case types.length
321
- when 0 then compacted_item.delete(container_key)
321
+ when 0 then compacted_item.delete(container_key) if compacted_item.is_a?(Hash)
322
322
  when 1 then compacted_item[container_key] = types.first
323
323
  else compacted_item[container_key] = types
324
324
  end
325
325
 
326
326
  # if compacted_item contains a single entry who's key maps to @id, then recompact the item without @type
327
- if compacted_item.keys.length == 1 && expanded_item.key?('@id')
327
+ if compacted_item.is_a?(Hash) && compacted_item.keys.length == 1 && expanded_item.key?('@id')
328
328
  compacted_item = compact({ '@id' => expanded_item['@id'] },
329
329
  base: base,
330
330
  property: item_active_property,
@@ -843,9 +843,11 @@ module JSON
843
843
  end
844
844
  end
845
845
 
846
- if previous_definition&.protected? && definition != previous_definition && !override_protected
846
+ if !override_protected && previous_definition&.protected?
847
+ if definition != previous_definition
848
+ raise JSON::LD::JsonLdError::ProtectedTermRedefinition, "Attempt to redefine protected term #{term}"
849
+ end
847
850
  definition = previous_definition
848
- raise JSON::LD::JsonLdError::ProtectedTermRedefinition, "Attempt to redefine protected term #{term}"
849
851
  end
850
852
 
851
853
  term_definitions[term] = definition
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: json-ld
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.3.0
4
+ version: 3.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gregg Kellogg
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-01 00:00:00.000000000 Z
11
+ date: 2024-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: htmlentities
@@ -30,20 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.3'
34
- - - ">="
35
- - !ruby/object:Gem::Version
36
- version: 0.3.2
33
+ version: '1.0'
37
34
  type: :runtime
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
38
  - - "~>"
42
39
  - !ruby/object:Gem::Version
43
- version: '0.3'
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: 0.3.2
40
+ version: '1.0'
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: link_header
49
43
  requirement: !ruby/object:Gem::Requirement
@@ -112,6 +106,34 @@ dependencies:
112
106
  - - "~>"
113
107
  - !ruby/object:Gem::Version
114
108
  version: '3.3'
109
+ - !ruby/object:Gem::Dependency
110
+ name: rexml
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '3.2'
116
+ type: :runtime
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '3.2'
123
+ - !ruby/object:Gem::Dependency
124
+ name: getoptlong
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '0.2'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '0.2'
115
137
  - !ruby/object:Gem::Dependency
116
138
  name: jsonlint
117
139
  requirement: !ruby/object:Gem::Requirement