json-ld 3.1.10 → 3.2.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 +4 -4
- data/README.md +9 -10
- data/VERSION +1 -1
- data/lib/json/ld/api.rb +53 -16
- data/lib/json/ld/context.rb +8 -8
- data/lib/json/ld/expand.rb +2 -2
- data/lib/json/ld/flatten.rb +1 -1
- data/lib/json/ld/format.rb +2 -1
- data/lib/json/ld/reader.rb +2 -2
- data/lib/json/ld/streaming_reader.rb +2 -1
- data/lib/json/ld/to_rdf.rb +9 -8
- data/lib/json/ld/writer.rb +9 -10
- data/lib/json/ld.rb +3 -0
- data/spec/api_spec.rb +67 -19
- data/spec/format_spec.rb +7 -3
- data/spec/frame_spec.rb +25 -1
- data/spec/reader_spec.rb +14 -14
- data/spec/suite_helper.rb +1 -0
- data/spec/test-files/{test-1-compacted.json → test-1-compacted.jsonld} +0 -0
- data/spec/test-files/{test-1-context.json → test-1-context.jsonld} +0 -0
- data/spec/test-files/{test-1-expanded.json → test-1-expanded.jsonld} +0 -0
- data/spec/test-files/{test-1-input.json → test-1-input.jsonld} +0 -0
- data/spec/test-files/{test-2-compacted.json → test-2-compacted.jsonld} +0 -0
- data/spec/test-files/{test-2-context.json → test-2-context.jsonld} +0 -0
- data/spec/test-files/{test-2-expanded.json → test-2-expanded.jsonld} +0 -0
- data/spec/test-files/{test-2-input.json → test-2-input.jsonld} +0 -0
- data/spec/test-files/{test-3-compacted.json → test-3-compacted.jsonld} +0 -0
- data/spec/test-files/{test-3-context.json → test-3-context.jsonld} +0 -0
- data/spec/test-files/{test-3-expanded.json → test-3-expanded.jsonld} +0 -0
- data/spec/test-files/{test-3-input.json → test-3-input.jsonld} +0 -0
- data/spec/test-files/{test-4-compacted.json → test-4-compacted.jsonld} +0 -0
- data/spec/test-files/{test-4-context.json → test-4-context.jsonld} +0 -0
- data/spec/test-files/{test-4-expanded.json → test-4-expanded.jsonld} +0 -0
- data/spec/test-files/{test-4-input.json → test-4-input.jsonld} +0 -0
- data/spec/test-files/{test-5-compacted.json → test-5-compacted.jsonld} +0 -0
- data/spec/test-files/{test-5-context.json → test-5-context.jsonld} +0 -0
- data/spec/test-files/{test-5-expanded.json → test-5-expanded.jsonld} +0 -0
- data/spec/test-files/{test-5-input.json → test-5-input.jsonld} +0 -0
- data/spec/test-files/{test-6-compacted.json → test-6-compacted.jsonld} +0 -0
- data/spec/test-files/{test-6-context.json → test-6-context.jsonld} +0 -0
- data/spec/test-files/{test-6-expanded.json → test-6-expanded.jsonld} +0 -0
- data/spec/test-files/{test-6-input.json → test-6-input.jsonld} +0 -0
- data/spec/test-files/{test-7-compacted.json → test-7-compacted.jsonld} +0 -0
- data/spec/test-files/{test-7-context.json → test-7-context.jsonld} +0 -0
- data/spec/test-files/{test-7-expanded.json → test-7-expanded.jsonld} +0 -0
- data/spec/test-files/{test-7-input.json → test-7-input.jsonld} +0 -0
- data/spec/test-files/{test-8-compacted.json → test-8-compacted.jsonld} +0 -0
- data/spec/test-files/{test-8-context.json → test-8-context.jsonld} +0 -0
- data/spec/test-files/{test-8-expanded.json → test-8-expanded.jsonld} +0 -0
- data/spec/test-files/{test-8-frame.json → test-8-frame.jsonld} +0 -0
- data/spec/test-files/{test-8-framed.json → test-8-framed.jsonld} +0 -0
- data/spec/test-files/{test-8-input.json → test-8-input.jsonld} +0 -0
- data/spec/test-files/{test-9-compacted.json → test-9-compacted.jsonld} +0 -0
- data/spec/test-files/{test-9-context.json → test-9-context.jsonld} +0 -0
- data/spec/test-files/{test-9-expanded.json → test-9-expanded.jsonld} +0 -0
- data/spec/test-files/{test-9-input.json → test-9-input.jsonld} +0 -0
- metadata +110 -111
- data/spec/test-files/test-1-normalized.json +0 -8
- data/spec/test-files/test-2-normalized.json +0 -32
- data/spec/test-files/test-3-normalized.json +0 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 63c237710b5f32fe8037a11969feaf712a79f68a4d1d568a89ece1a5d1d26ff2
|
4
|
+
data.tar.gz: cac81da94266cac30a7e31e5018477ef55e52b6b1701b048214947f266439236
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 440da082cc1cbabcd69e8cb3d34858c4fe8fd96b116c0d67651d5ce7338d6e787f9d00451ff1f730d08982f0d8697d097f51d09d033ff7f8e290252006f96c78
|
7
|
+
data.tar.gz: 0b877d9d96857964a4913aef1790aa04dc98f83676ec0154c016ad05e7a9dc0a22b1b3bd31ae785cfb4447ac6914291ac56d42f5dc6781fc58c6687ccd4d15cd
|
data/README.md
CHANGED
@@ -32,10 +32,10 @@ This gem also implements an optimized streaming writer used for generating JSON-
|
|
32
32
|
* Each statement written as a separate node in expanded/flattened form.
|
33
33
|
* `RDF List`s are written as separate nodes using `rdf:first` and `rdf:rest` properties.
|
34
34
|
|
35
|
-
The order of triples retrieved from the `RDF::Enumerable` dataset determines the way that JSON-LD node objects are written; for best results, statements should be ordered by _graph name_,
|
35
|
+
The order of triples retrieved from the `RDF::Enumerable` dataset determines the way that JSON-LD node objects are written; for best results, statements should be ordered by _graph name_, _subject_, _predicate_ and _object_.
|
36
36
|
|
37
37
|
### MultiJson parser
|
38
|
-
The [MultiJson](https://rubygems.org/gems/multi_json) gem is used for parsing JSON; this defaults to the native JSON parser, but will use a more performant parser if one is available. A specific parser can be specified by adding the `:adapter` option to any API call. See [MultiJson](https://rubygems.org/gems/multi_json) for more information.
|
38
|
+
The [MultiJson](https://rubygems.org/gems/multi_json) gem is used for parsing and serializing JSON; this defaults to the native JSON parser/serializer, but will use a more performant parser if one is available. A specific parser can be specified by adding the `:adapter` option to any API call. Additionally, a custom serialilzer may be specified by passing the `:serializer` option to {JSON::LD::Writer} or methods of {JSON::LD::API}. See [MultiJson](https://rubygems.org/gems/multi_json) for more information.
|
39
39
|
|
40
40
|
### JSON-LD-star (RDFStar)
|
41
41
|
|
@@ -72,7 +72,7 @@ In the first case, the embedded node is not asserted, and only appears as the su
|
|
72
72
|
|
73
73
|
#### Serializing a Graph containing embedded statements
|
74
74
|
|
75
|
-
require 'json
|
75
|
+
require 'json/ld'
|
76
76
|
statement = RDF::Statement(RDF::URI('bob'), RDF::Vocab::FOAF.age, RDF::Literal(23))
|
77
77
|
graph = RDF::Graph.new << [statement, RDF::URI("ex:certainty"), RDF::Literal(0.9)]
|
78
78
|
graph.dump(:jsonld, validate: false, standard_prefixes: true)
|
@@ -565,7 +565,7 @@ The {JSON::LD::ContentNegotiation#call} method looks for a result which includes
|
|
565
565
|
See [Rack::LinkedData][] to do the same thing with an RDF Graph or Dataset as the source, rather than Ruby objects.
|
566
566
|
|
567
567
|
## Documentation
|
568
|
-
Full documentation available on [RubyDoc](https://
|
568
|
+
Full documentation available on [RubyDoc](https://ruby-rdf.github.io/json-ld/file/README.md)
|
569
569
|
|
570
570
|
## Differences from [JSON-LD API][]
|
571
571
|
The specified JSON-LD API is based on a WebIDL definition implementing [Promises][] intended for use within a browser.
|
@@ -588,9 +588,9 @@ Note, the API method signatures differed in versions before 1.0, in that they al
|
|
588
588
|
* {JSON::LD::Writer}
|
589
589
|
|
590
590
|
## Dependencies
|
591
|
-
* [Ruby](https://ruby-lang.org/) (>= 2.
|
592
|
-
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.
|
593
|
-
* [JSON](https://rubygems.org/gems/json) (>= 2.
|
591
|
+
* [Ruby](https://ruby-lang.org/) (>= 2.6)
|
592
|
+
* [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)
|
593
|
+
* [JSON](https://rubygems.org/gems/json) (>= 2.6)
|
594
594
|
|
595
595
|
## Installation
|
596
596
|
The recommended installation method is via [RubyGems](https://rubygems.org/).
|
@@ -624,8 +624,7 @@ To get a local working copy of the development repository, do:
|
|
624
624
|
which you will be asked to agree to on the first commit to a repo within the organization.
|
625
625
|
Note that the agreement applies to all repos in the [Ruby RDF](https://github.com/ruby-rdf/) organization.
|
626
626
|
|
627
|
-
License
|
628
|
-
-------
|
627
|
+
## License
|
629
628
|
|
630
629
|
This is free and unencumbered public domain software. For more information,
|
631
630
|
see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
@@ -641,7 +640,7 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
641
640
|
[Backports]: https://rubygems.org/gems/backports
|
642
641
|
[JSON-LD]: https://www.w3.org/TR/json-ld11/ "JSON-LD 1.1"
|
643
642
|
[JSON-LD API]: https://www.w3.org/TR/json-ld11-api/ "JSON-LD 1.1 Processing Algorithms and API"
|
644
|
-
[JSON-LD Framing]: https://www.w3.org/TR/json-ld11-framing/ "JSON-LD
|
643
|
+
[JSON-LD Framing]: https://www.w3.org/TR/json-ld11-framing/ "JSON-LD 1.1 Framing"
|
645
644
|
[Promises]: https://dom.spec.whatwg.org/#promises
|
646
645
|
[jsonlint]: https://rubygems.org/gems/jsonlint
|
647
646
|
[Sinatra]: https://www.sinatrarb.com/
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.
|
1
|
+
3.2.2
|
data/lib/json/ld/api.rb
CHANGED
@@ -126,7 +126,8 @@ module JSON::LD
|
|
126
126
|
|
127
127
|
case remote_doc.document
|
128
128
|
when String
|
129
|
-
|
129
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
130
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
130
131
|
else
|
131
132
|
# Already parsed
|
132
133
|
remote_doc.document
|
@@ -155,6 +156,9 @@ module JSON::LD
|
|
155
156
|
#
|
156
157
|
# @param [String, #read, Hash, Array] input
|
157
158
|
# The JSON-LD object to copy and perform the expansion upon.
|
159
|
+
# @param [Proc] serializer (nil)
|
160
|
+
# A Serializer method used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
161
|
+
# See {JSON::LD::API.serializer}.
|
158
162
|
# @param [Hash{Symbol => Object}] options
|
159
163
|
# @option options (see #initialize)
|
160
164
|
# @raise [JsonLdError]
|
@@ -167,7 +171,7 @@ module JSON::LD
|
|
167
171
|
# @return [Object, Array<Hash>]
|
168
172
|
# If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
|
169
173
|
# @see https://www.w3.org/TR/json-ld11-api/#expansion-algorithm
|
170
|
-
def self.expand(input, framing: false, **options, &block)
|
174
|
+
def self.expand(input, framing: false, serializer: nil, **options, &block)
|
171
175
|
result = doc_base = nil
|
172
176
|
API.new(input, options[:expandContext], **options) do
|
173
177
|
result = self.expand(self.value, nil, self.context,
|
@@ -180,6 +184,7 @@ module JSON::LD
|
|
180
184
|
|
181
185
|
# Finally, if element is a JSON object, it is wrapped into an array.
|
182
186
|
result = [result].compact unless result.is_a?(Array)
|
187
|
+
result = serializer.call(result, **options) if serializer
|
183
188
|
|
184
189
|
if block_given?
|
185
190
|
case block.arity
|
@@ -204,6 +209,9 @@ module JSON::LD
|
|
204
209
|
# The JSON-LD object to copy and perform the compaction upon.
|
205
210
|
# @param [String, #read, Hash, Array, JSON::LD::Context] context
|
206
211
|
# The base context to use when compacting the input.
|
212
|
+
# @param [Proc] serializer (nil)
|
213
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
214
|
+
# See {JSON::LD::API.serializer}.
|
207
215
|
# @param [Boolean] expanded (false) Input is already expanded
|
208
216
|
# @param [Hash{Symbol => Object}] options
|
209
217
|
# @option options (see #initialize)
|
@@ -215,7 +223,7 @@ module JSON::LD
|
|
215
223
|
# If a block is given, the result of evaluating the block is returned, otherwise, the compacted JSON-LD document
|
216
224
|
# @raise [JsonLdError]
|
217
225
|
# @see https://www.w3.org/TR/json-ld11-api/#compaction-algorithm
|
218
|
-
def self.compact(input, context, expanded: false, **options)
|
226
|
+
def self.compact(input, context, expanded: false, serializer: nil, **options)
|
219
227
|
result = nil
|
220
228
|
options = {compactToRelative: true}.merge(options)
|
221
229
|
|
@@ -238,6 +246,7 @@ module JSON::LD
|
|
238
246
|
end
|
239
247
|
result = ctx.merge(result) unless ctx.fetch('@context', {}).empty?
|
240
248
|
end
|
249
|
+
result = serializer.call(result, **options) if serializer
|
241
250
|
block_given? ? yield(result) : result
|
242
251
|
end
|
243
252
|
|
@@ -251,6 +260,9 @@ module JSON::LD
|
|
251
260
|
# @param [String, #read, Hash, Array, JSON::LD::EvaluationContext] context
|
252
261
|
# An optional external context to use additionally to the context embedded in input when expanding the input.
|
253
262
|
# @param [Boolean] expanded (false) Input is already expanded
|
263
|
+
# @param [Proc] serializer (nil)
|
264
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
265
|
+
# See {JSON::LD::API.serializer}.
|
254
266
|
# @param [Hash{Symbol => Object}] options
|
255
267
|
# @option options (see #initialize)
|
256
268
|
# @option options [Boolean] :createAnnotations
|
@@ -262,7 +274,7 @@ module JSON::LD
|
|
262
274
|
# @return [Object, Hash]
|
263
275
|
# If a block is given, the result of evaluating the block is returned, otherwise, the flattened JSON-LD document
|
264
276
|
# @see https://www.w3.org/TR/json-ld11-api/#framing-algorithm
|
265
|
-
def self.flatten(input, context, expanded: false, **options)
|
277
|
+
def self.flatten(input, context, expanded: false, serializer: nil, **options)
|
266
278
|
flattened = []
|
267
279
|
options = {
|
268
280
|
compactToRelative: true,
|
@@ -318,6 +330,7 @@ module JSON::LD
|
|
318
330
|
end
|
319
331
|
end
|
320
332
|
|
333
|
+
flattened = serializer.call(flattened, **options) if serializer
|
321
334
|
block_given? ? yield(flattened) : flattened
|
322
335
|
end
|
323
336
|
|
@@ -350,7 +363,7 @@ module JSON::LD
|
|
350
363
|
# If a block is given, the result of evaluating the block is returned, otherwise, the framed JSON-LD document
|
351
364
|
# @raise [InvalidFrame]
|
352
365
|
# @see https://www.w3.org/TR/json-ld11-api/#framing-algorithm
|
353
|
-
def self.frame(input, frame, expanded: false, **options)
|
366
|
+
def self.frame(input, frame, expanded: false, serializer: nil, **options)
|
354
367
|
result = nil
|
355
368
|
options = {
|
356
369
|
base: (RDF::URI(input) if input.is_a?(String)),
|
@@ -379,7 +392,8 @@ module JSON::LD
|
|
379
392
|
requestProfile: 'http://www.w3.org/ns/json-ld#frame',
|
380
393
|
**options)
|
381
394
|
if remote_doc.document.is_a?(String)
|
382
|
-
|
395
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
396
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
383
397
|
else
|
384
398
|
remote_doc.document
|
385
399
|
end
|
@@ -467,6 +481,7 @@ module JSON::LD
|
|
467
481
|
result
|
468
482
|
end
|
469
483
|
|
484
|
+
result = serializer.call(result, **options) if serializer
|
470
485
|
block_given? ? yield(result) : result
|
471
486
|
end
|
472
487
|
|
@@ -528,18 +543,21 @@ module JSON::LD
|
|
528
543
|
# The resulting `Array` is either returned or yielded, if a block is given.
|
529
544
|
#
|
530
545
|
# @param [RDF::Enumerable] input
|
546
|
+
# @param [Boolean] useRdfType (false)
|
547
|
+
# If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`.
|
548
|
+
# @param [Boolean] useNativeTypes (false) use native representations
|
549
|
+
# @param [Proc] serializer (nil)
|
550
|
+
# A Serializer instance used for generating the JSON serialization of the result. If absent, the internal Ruby objects are returned, which can be transformed to JSON externally via `#to_json`.
|
551
|
+
# See {JSON::LD::API.serializer}.
|
531
552
|
# @param [Hash{Symbol => Object}] options
|
532
553
|
# @option options (see #initialize)
|
533
|
-
# @option options [Boolean] :useRdfType (false)
|
534
|
-
# If set to `true`, the JSON-LD processor will treat `rdf:type` like a normal property instead of using `@type`.
|
535
|
-
# @option options [Boolean] :useNativeTypes (false) use native representations
|
536
554
|
# @yield jsonld
|
537
555
|
# @yieldparam [Hash] jsonld
|
538
556
|
# The JSON-LD document in expanded form
|
539
557
|
# @yieldreturn [Object] returned object
|
540
558
|
# @return [Object, Hash]
|
541
559
|
# If a block is given, the result of evaluating the block is returned, otherwise, the expanded JSON-LD document
|
542
|
-
def self.fromRdf(input, useRdfType: false, useNativeTypes: false, **options, &block)
|
560
|
+
def self.fromRdf(input, useRdfType: false, useNativeTypes: false, serializer: nil, **options, &block)
|
543
561
|
result = nil
|
544
562
|
|
545
563
|
API.new(nil, nil, **options) do
|
@@ -548,6 +566,7 @@ module JSON::LD
|
|
548
566
|
useNativeTypes: useNativeTypes)
|
549
567
|
end
|
550
568
|
|
569
|
+
result = serializer.call(result, **options) if serializer
|
551
570
|
block_given? ? yield(result) : result
|
552
571
|
end
|
553
572
|
|
@@ -648,7 +667,8 @@ module JSON::LD
|
|
648
667
|
end
|
649
668
|
else
|
650
669
|
validate_input(remote_doc.document, url: remote_doc.documentUrl) if validate
|
651
|
-
|
670
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
671
|
+
MultiJson.load(remote_doc.document, **mj_opts)
|
652
672
|
end
|
653
673
|
end
|
654
674
|
|
@@ -682,8 +702,8 @@ module JSON::LD
|
|
682
702
|
base_uri ||= url.base_uri if url.respond_to?(:base_uri)
|
683
703
|
content_type = options[:content_type]
|
684
704
|
content_type ||= url.content_type if url.respond_to?(:content_type)
|
685
|
-
context_url = if url.respond_to?(:links) && url.links
|
686
|
-
(content_type == '
|
705
|
+
context_url = if url.respond_to?(:links) && url.links &&
|
706
|
+
(content_type == 'application/json' || content_type.match?(%r(application/(^ld)+json)))
|
687
707
|
link = url.links.find_link(LINK_REL_CONTEXT)
|
688
708
|
link.href if link
|
689
709
|
end
|
@@ -759,7 +779,8 @@ module JSON::LD
|
|
759
779
|
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "Script tag has type=#{element.attributes['type']}" unless element.attributes['type'].to_s.start_with?('application/ld+json')
|
760
780
|
content = element.inner_html
|
761
781
|
validate_input(content, url: url) if options[:validate]
|
762
|
-
|
782
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
783
|
+
MultiJson.load(content, **mj_opts)
|
763
784
|
elsif extractAllScripts
|
764
785
|
res = []
|
765
786
|
elements = if profile
|
@@ -773,7 +794,8 @@ module JSON::LD
|
|
773
794
|
elements.each do |element|
|
774
795
|
content = element.inner_html
|
775
796
|
validate_input(content, url: url) if options[:validate]
|
776
|
-
|
797
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
798
|
+
r = MultiJson.load(content, **mj_opts)
|
777
799
|
if r.is_a?(Hash)
|
778
800
|
res << r
|
779
801
|
elsif r.is_a?(Array)
|
@@ -788,12 +810,27 @@ module JSON::LD
|
|
788
810
|
raise JSON::LD::JsonLdError::LoadingDocumentFailed, "No script tag found" unless element
|
789
811
|
content = element.inner_html
|
790
812
|
validate_input(content, url: url) if options[:validate]
|
791
|
-
|
813
|
+
mj_opts = options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
814
|
+
MultiJson.load(content, **mj_opts)
|
792
815
|
end
|
793
816
|
rescue MultiJson::ParseError => e
|
794
817
|
raise JSON::LD::JsonLdError::InvalidScriptElement, e.message
|
795
818
|
end
|
796
819
|
|
820
|
+
##
|
821
|
+
# The default serializer for serialzing Ruby Objects to JSON.
|
822
|
+
#
|
823
|
+
# Defaults to `MultiJson.dump`
|
824
|
+
#
|
825
|
+
# @param [Object] object
|
826
|
+
# @param [Array<Object>] args
|
827
|
+
# other arguments that may be passed for some specific implementation.
|
828
|
+
# @param [Hash<Symbol, Object>] options
|
829
|
+
# options passed from the invoking context.
|
830
|
+
def self.serializer(object, *args, **options)
|
831
|
+
MultiJson.dump(object, JSON_STATE)
|
832
|
+
end
|
833
|
+
|
797
834
|
##
|
798
835
|
# Validate JSON using JsonLint, if loaded
|
799
836
|
private
|
data/lib/json/ld/context.rb
CHANGED
@@ -5,13 +5,6 @@ require 'bigdecimal'
|
|
5
5
|
require 'set'
|
6
6
|
require 'rdf/util/cache'
|
7
7
|
|
8
|
-
begin
|
9
|
-
# Attempt to load this to avoid unnecessary context fetches
|
10
|
-
require 'json-ld-preloaded'
|
11
|
-
rescue LoadError
|
12
|
-
# Silently allow this to fail
|
13
|
-
end
|
14
|
-
|
15
8
|
module JSON::LD
|
16
9
|
class Context
|
17
10
|
include Utils
|
@@ -50,6 +43,13 @@ module JSON::LD
|
|
50
43
|
end
|
51
44
|
end
|
52
45
|
|
46
|
+
begin
|
47
|
+
# Attempt to load this to avoid unnecessary context fetches
|
48
|
+
require 'json/ld/preloaded'
|
49
|
+
rescue LoadError
|
50
|
+
# Silently allow this to fail
|
51
|
+
end
|
52
|
+
|
53
53
|
# The base.
|
54
54
|
#
|
55
55
|
# @return [RDF::URI] Current base IRI, used for expanding relative IRIs.
|
@@ -1688,7 +1688,7 @@ module JSON::LD
|
|
1688
1688
|
ec.default_direction = that.default_direction
|
1689
1689
|
ec.default_language = that.default_language
|
1690
1690
|
ec.previous_context = that.previous_context
|
1691
|
-
ec.processingMode = that.processingMode if that.instance_variable_get(:@
|
1691
|
+
ec.processingMode = that.processingMode if that.instance_variable_get(:@processingMode)
|
1692
1692
|
ec.vocab = that.vocab if that.vocab
|
1693
1693
|
|
1694
1694
|
ec.instance_eval do
|
data/lib/json/ld/expand.rb
CHANGED
@@ -88,7 +88,7 @@ module JSON::LD
|
|
88
88
|
|
89
89
|
# If element contains the key @context, set active context to the result of the Context Processing algorithm, passing active context and the value of the @context key as local context.
|
90
90
|
if input.key?('@context')
|
91
|
-
context = context.parse(input
|
91
|
+
context = context.parse(input['@context'], base: @options[:base])
|
92
92
|
log_debug("expand", depth: log_depth.to_i) {"context: #{context.inspect}"}
|
93
93
|
end
|
94
94
|
|
@@ -99,7 +99,7 @@ module JSON::LD
|
|
99
99
|
|
100
100
|
# See if keys mapping to @type have terms with a local context
|
101
101
|
type_key = nil
|
102
|
-
input.keys.sort.
|
102
|
+
(input.keys - %w(@context)).sort.
|
103
103
|
select {|k| context.expand_iri(k, vocab: true, base: @options[:base]) == '@type'}.
|
104
104
|
each do |tk|
|
105
105
|
|
data/lib/json/ld/flatten.rb
CHANGED
@@ -202,7 +202,7 @@ module JSON::LD
|
|
202
202
|
# * Deserialize the key into a map, and re-serialize the value of `@id`.
|
203
203
|
# * If the map contains an entry with that value (after re-canonicalizing, as appropriate), and the associated antry has a item which matches the non-`@id` item from the map, the node is used to create an `@annotation` entry within that value.
|
204
204
|
#
|
205
|
-
# @param [Hash{String => Hash}]
|
205
|
+
# @param [Hash{String => Hash}] node_map
|
206
206
|
# @return [Hash{String => Hash}]
|
207
207
|
def create_annotations(node_map)
|
208
208
|
node_map.keys.
|
data/lib/json/ld/format.rb
CHANGED
@@ -23,7 +23,8 @@ module JSON::LD
|
|
23
23
|
class Format < RDF::Format
|
24
24
|
content_type 'application/ld+json',
|
25
25
|
extension: :jsonld,
|
26
|
-
alias: 'application/x-ld+json'
|
26
|
+
alias: 'application/x-ld+json',
|
27
|
+
uri: 'http://www.w3.org/ns/formats/JSON-LD'
|
27
28
|
content_encoding 'utf-8'
|
28
29
|
|
29
30
|
reader { JSON::LD::Reader }
|
data/lib/json/ld/reader.rb
CHANGED
@@ -12,7 +12,7 @@ module JSON::LD
|
|
12
12
|
|
13
13
|
##
|
14
14
|
# JSON-LD Reader options
|
15
|
-
# @see
|
15
|
+
# @see https://ruby-rdf.github.io/rdf/RDF/Reader#options-class_method
|
16
16
|
def self.options
|
17
17
|
super + [
|
18
18
|
RDF::CLI::Option.new(
|
@@ -57,7 +57,7 @@ module JSON::LD
|
|
57
57
|
end
|
58
58
|
|
59
59
|
##
|
60
|
-
# Initializes the
|
60
|
+
# Initializes the JSON-LD reader instance.
|
61
61
|
#
|
62
62
|
# @param [IO, File, String] input
|
63
63
|
# @param [Hash{Symbol => Object}] options
|
@@ -26,7 +26,8 @@ module JSON::LD
|
|
26
26
|
unique_bnodes, rename_bnodes = @options[:unique_bnodes], @options.fetch(:rename_bnodes, true)
|
27
27
|
# FIXME: document loader doesn't stream
|
28
28
|
@base = RDF::URI(@options[:base] || base_uri)
|
29
|
-
|
29
|
+
mj_opts = @options.keep_if {|k,v| k != :adapter || MUTLI_JSON_ADAPTERS.include?(v)}
|
30
|
+
value = MultiJson.load(@doc, mj_opts)
|
30
31
|
context_ref = @options[:expandContext]
|
31
32
|
#context_ref = @options.fetch(:expandContext, remote_doc.contextUrl)
|
32
33
|
context = Context.parse(context_ref, **@options)
|
data/lib/json/ld/to_rdf.rb
CHANGED
@@ -11,10 +11,11 @@ module JSON::LD
|
|
11
11
|
##
|
12
12
|
# @param [Hash{String => Object}] item
|
13
13
|
# @param [RDF::Resource] graph_name
|
14
|
+
# @param [Boolean] quoted emitted triples are quoted triples.
|
14
15
|
# @yield statement
|
15
16
|
# @yieldparam [RDF::Statement] statement
|
16
17
|
# @return RDF::Resource the subject of this item
|
17
|
-
def item_to_rdf(item, graph_name: nil, &block)
|
18
|
+
def item_to_rdf(item, graph_name: nil, quoted: false, &block)
|
18
19
|
# Just return value object as Term
|
19
20
|
return unless item
|
20
21
|
|
@@ -82,9 +83,9 @@ module JSON::LD
|
|
82
83
|
when nil then node
|
83
84
|
when String then as_resource(item['@id'])
|
84
85
|
when Object
|
85
|
-
# Embedded statement
|
86
|
+
# Embedded/quoted statement
|
86
87
|
# (No error checking, as this is done in expansion)
|
87
|
-
to_enum(:item_to_rdf, item['@id']).to_a.first
|
88
|
+
to_enum(:item_to_rdf, item['@id'], quoted: true).to_a.first
|
88
89
|
end
|
89
90
|
|
90
91
|
#log_debug("item_to_rdf") {"subject: #{subject.to_ntriples rescue 'malformed rdf'}"}
|
@@ -95,12 +96,12 @@ module JSON::LD
|
|
95
96
|
values.each do |v|
|
96
97
|
object = as_resource(v)
|
97
98
|
#log_debug("item_to_rdf") {"type: #{object.to_ntriples rescue 'malformed rdf'}"}
|
98
|
-
yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name)
|
99
|
+
yield RDF::Statement(subject, RDF.type, object, graph_name: graph_name, quoted: quoted)
|
99
100
|
end
|
100
101
|
when '@graph'
|
101
102
|
values = [values].compact unless values.is_a?(Array)
|
102
103
|
values.each do |nd|
|
103
|
-
item_to_rdf(nd, graph_name: subject, &block)
|
104
|
+
item_to_rdf(nd, graph_name: subject, quoted: quoted, &block)
|
104
105
|
end
|
105
106
|
when '@reverse'
|
106
107
|
raise "Huh?" unless values.is_a?(Hash)
|
@@ -113,7 +114,7 @@ module JSON::LD
|
|
113
114
|
object = item_to_rdf(v, graph_name: graph_name, &block)
|
114
115
|
#log_debug("item_to_rdf") {"subject: #{object.to_ntriples rescue 'malformed rdf'}"}
|
115
116
|
# yield subject, prediate, and literal to results.
|
116
|
-
yield RDF::Statement(object, predicate, subject, graph_name: graph_name)
|
117
|
+
yield RDF::Statement(object, predicate, subject, graph_name: graph_name, quoted: quoted)
|
117
118
|
end
|
118
119
|
end
|
119
120
|
when '@included'
|
@@ -136,13 +137,13 @@ module JSON::LD
|
|
136
137
|
object = parse_list(v['@list'], graph_name: graph_name, &block)
|
137
138
|
|
138
139
|
# Append a triple composed of subject, prediate, and object to results and add all triples from list_results to results.
|
139
|
-
yield RDF::Statement(subject, predicate, object, graph_name: graph_name)
|
140
|
+
yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
|
140
141
|
else
|
141
142
|
# Otherwise, item is a value object or a node definition. Generate object as the result of the Object Converstion algorithm passing item.
|
142
143
|
object = item_to_rdf(v, graph_name: graph_name, &block)
|
143
144
|
#log_debug("item_to_rdf") {"object: #{object.to_ntriples rescue 'malformed rdf'}"}
|
144
145
|
# yield subject, prediate, and literal to results.
|
145
|
-
yield RDF::Statement(subject, predicate, object, graph_name: graph_name)
|
146
|
+
yield RDF::Statement(subject, predicate, object, graph_name: graph_name, quoted: quoted)
|
146
147
|
end
|
147
148
|
end
|
148
149
|
end
|
data/lib/json/ld/writer.rb
CHANGED
@@ -71,7 +71,7 @@ module JSON::LD
|
|
71
71
|
|
72
72
|
##
|
73
73
|
# JSON-LD Writer options
|
74
|
-
# @see
|
74
|
+
# @see https://ruby-rdf.github.io/rdf/RDF/Writer#options-class_method
|
75
75
|
def self.options
|
76
76
|
super + [
|
77
77
|
RDF::CLI::Option.new(
|
@@ -186,10 +186,6 @@ module JSON::LD
|
|
186
186
|
# @return [Boolean]
|
187
187
|
# @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
|
188
188
|
def accept?(accept_params)
|
189
|
-
# Profiles that aren't specific IANA relations represent the URL
|
190
|
-
# of a context or frame that may be subject to black- or white-listing
|
191
|
-
profile = accept_params[:profile].to_s.split(/\s+/)
|
192
|
-
|
193
189
|
if block_given?
|
194
190
|
yield(accept_params)
|
195
191
|
else
|
@@ -229,6 +225,8 @@ module JSON::LD
|
|
229
225
|
# frame to use when serializing.
|
230
226
|
# @option options [Boolean] :unique_bnodes (false)
|
231
227
|
# Use unique bnode identifiers, defaults to using the identifier which the node was originall initialized with (if any).
|
228
|
+
# @option options [Proc] serializer (JSON::LD::API.serializer)
|
229
|
+
# A Serializer method used for generating the JSON serialization of the result.
|
232
230
|
# @option options [Boolean] :stream (false)
|
233
231
|
# Do not attempt to optimize graph presentation, suitable for streaming large graphs.
|
234
232
|
# @yield [writer] `self`
|
@@ -239,6 +237,7 @@ module JSON::LD
|
|
239
237
|
def initialize(output = $stdout, **options, &block)
|
240
238
|
options[:base_uri] ||= options[:base] if options.key?(:base)
|
241
239
|
options[:base] ||= options[:base_uri] if options.key?(:base_uri)
|
240
|
+
@serializer = options.fetch(:serializer, JSON::LD::API.method(:serializer))
|
242
241
|
super do
|
243
242
|
@repo = RDF::Repository.new
|
244
243
|
|
@@ -300,7 +299,7 @@ module JSON::LD
|
|
300
299
|
else
|
301
300
|
|
302
301
|
log_debug("writer") { "serialize #{@repo.count} statements, #{@options.inspect}"}
|
303
|
-
result = API.fromRdf(@repo, **@options)
|
302
|
+
result = API.fromRdf(@repo, **@options.merge(serializer: nil))
|
304
303
|
|
305
304
|
# Some options may be indicated from accept parameters
|
306
305
|
profile = @options.fetch(:accept_params, {}).fetch(:profile, "").split(' ')
|
@@ -322,20 +321,20 @@ module JSON::LD
|
|
322
321
|
|
323
322
|
# Rename BNodes to uniquify them, if necessary
|
324
323
|
if options[:unique_bnodes]
|
325
|
-
result = API.flatten(result, context, **@options)
|
324
|
+
result = API.flatten(result, context, **@options.merge(serializer: nil))
|
326
325
|
end
|
327
326
|
|
328
327
|
if frame = @options[:frame]
|
329
328
|
# Perform framing, if given a frame
|
330
329
|
log_debug("writer") { "frame result"}
|
331
|
-
result = API.frame(result, frame, **@options)
|
330
|
+
result = API.frame(result, frame, **@options.merge(serializer: nil))
|
332
331
|
elsif context
|
333
332
|
# Perform compaction, if we have a context
|
334
333
|
log_debug("writer") { "compact result"}
|
335
|
-
result = API.compact(result, context, **@options)
|
334
|
+
result = API.compact(result, context, **@options.merge(serializer: nil))
|
336
335
|
end
|
337
336
|
|
338
|
-
@output.write(
|
337
|
+
@output.write(@serializer.call(result, **@options))
|
339
338
|
end
|
340
339
|
|
341
340
|
super
|
data/lib/json/ld.rb
CHANGED
@@ -46,6 +46,9 @@ module JSON
|
|
46
46
|
# Default context when compacting without one being specified
|
47
47
|
DEFAULT_CONTEXT = "http://schema.org"
|
48
48
|
|
49
|
+
# Acceptable MultiJson adapters
|
50
|
+
MUTLI_JSON_ADAPTERS = %i(oj json_gem json_pure ok_json yajl nsjsonseerialization)
|
51
|
+
|
49
52
|
KEYWORDS = Set.new(%w(
|
50
53
|
@annotation
|
51
54
|
@base
|
data/spec/api_spec.rb
CHANGED
@@ -48,30 +48,78 @@ describe JSON::LD::API do
|
|
48
48
|
context "with MultiJson adapter #{adapter.inspect}" do
|
49
49
|
Dir.glob(File.expand_path(File.join(File.dirname(__FILE__), 'test-files/*-input.*'))) do |filename|
|
50
50
|
test = File.basename(filename).sub(/-input\..*$/, '')
|
51
|
-
frame = filename.sub(/-input\..*$/, '-frame.
|
52
|
-
framed = filename.sub(/-input\..*$/, '-framed.
|
53
|
-
compacted = filename.sub(/-input\..*$/, '-compacted.
|
54
|
-
context = filename.sub(/-input\..*$/, '-context.
|
55
|
-
expanded = filename.sub(/-input\..*$/, '-expanded.
|
51
|
+
frame = filename.sub(/-input\..*$/, '-frame.jsonld')
|
52
|
+
framed = filename.sub(/-input\..*$/, '-framed.jsonld')
|
53
|
+
compacted = filename.sub(/-input\..*$/, '-compacted.jsonld')
|
54
|
+
context = filename.sub(/-input\..*$/, '-context.jsonld')
|
55
|
+
expanded = filename.sub(/-input\..*$/, '-expanded.jsonld')
|
56
56
|
ttl = filename.sub(/-input\..*$/, '-rdf.ttl')
|
57
57
|
|
58
58
|
context test, skip: ("Not supported in JRuby" if RUBY_ENGINE == "jruby" && %w(oj yajl).include?(adapter.to_s)) do
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
59
|
+
around do |example|
|
60
|
+
@file = File.open(filename)
|
61
|
+
case filename
|
62
|
+
when /.jsonld$/
|
63
|
+
@file.define_singleton_method(:content_type) {'application/ld+json'}
|
64
|
+
end
|
65
|
+
if context
|
66
|
+
@ctx_io = File.open(context)
|
67
|
+
case context
|
68
|
+
when /.jsonld$/
|
69
|
+
@ctx_io.define_singleton_method(:content_type) {'application/ld+json'}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
example.run
|
73
|
+
@file.close
|
74
|
+
@ctx_io.close if @ctx_io
|
75
|
+
end
|
76
|
+
|
77
|
+
if File.exist?(expanded)
|
78
|
+
it "expands" do
|
79
|
+
options = {logger: logger, adapter: adapter}
|
80
|
+
options[:expandContext] = @ctx_io if context
|
81
|
+
jld = described_class.expand(@file, **options)
|
82
|
+
expect(jld).to produce_jsonld(JSON.parse(File.read(expanded)), logger)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "expands with serializer" do
|
86
|
+
options = {logger: logger, adapter: adapter}
|
87
|
+
options[:expandContext] = @ctx_io if context
|
88
|
+
jld = described_class.expand(@file, serializer: JSON::LD::API.method(:serializer), **options)
|
89
|
+
expect(jld).to be_a(String)
|
90
|
+
expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(expanded)), logger)
|
91
|
+
end
|
92
|
+
end
|
65
93
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
94
|
+
if File.exist?(compacted) && File.exist?(context)
|
95
|
+
it "compacts" do
|
96
|
+
jld = described_class.compact(@file, @ctx_io, adapter: adapter, logger: logger)
|
97
|
+
expect(jld).to produce_jsonld(JSON.parse(File.read(compacted)), logger)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "compacts with serializer" do
|
101
|
+
jld = described_class.compact(@file, @ctx_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger)
|
102
|
+
expect(jld).to be_a(String)
|
103
|
+
expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(compacted)), logger)
|
104
|
+
end
|
105
|
+
end
|
70
106
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
107
|
+
if File.exist?(framed) && File.exist?(frame)
|
108
|
+
it "frames" do
|
109
|
+
File.open(frame) do |frame_io|
|
110
|
+
jld = described_class.frame(@file, frame_io, adapter: adapter, logger: logger)
|
111
|
+
expect(jld).to produce_jsonld(JSON.parse(File.read(framed)), logger)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
it "frames with serializer" do
|
116
|
+
File.open(frame) do |frame_io|
|
117
|
+
jld = described_class.frame(@file, frame_io, serializer: JSON::LD::API.method(:serializer), adapter: adapter, logger: logger)
|
118
|
+
expect(jld).to be_a(String)
|
119
|
+
expect(JSON.load(jld)).to produce_jsonld(JSON.parse(File.read(framed)), logger)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
75
123
|
|
76
124
|
it "toRdf" do
|
77
125
|
expect(RDF::Repository.load(filename, format: :jsonld, adapter: adapter, logger: logger)).to be_equivalent_graph(RDF::Repository.load(ttl), logger: logger)
|