@@ -2543,7 +2543,9 @@ Processor.prototype.compact = function(
2543
2543
var value = compactedValue [ compactedProperty ] ;
2544
2544
var container = jsonld . getContextValue (
2545
2545
activeCtx , compactedProperty , '@container' ) ;
2546
- var useArray = ( container === '@set' || ! options . compactArrays ) ;
2546
+ container = [ ] . concat ( container ) ;
2547
+ var useArray = (
2548
+ container . includes ( '@set' ) || ! options . compactArrays ) ;
2547
2549
jsonld . addValue (
2548
2550
rval , compactedProperty , value , { propertyIsArray : useArray } ) ;
2549
2551
delete compactedValue [ compactedProperty ] ;
@@ -2604,17 +2606,22 @@ Processor.prototype.compact = function(
2604
2606
insideReverse ) ;
2605
2607
var container = jsonld . getContextValue (
2606
2608
activeCtx , itemActiveProperty , '@container' ) ;
2609
+ container = [ ] . concat ( container ) ;
2607
2610
2608
- // get @list value if appropriate
2611
+ // get simple @graph or @list value if appropriate
2612
+ var isSimpleGraph = _isSimpleGraph ( expandedItem ) ;
2609
2613
var isList = _isList ( expandedItem ) ;
2610
- var list = null ;
2614
+ var inner ;
2611
2615
if ( isList ) {
2612
- list = expandedItem [ '@list' ] ;
2616
+ inner = expandedItem [ '@list' ] ;
2617
+ } else if ( isSimpleGraph ) {
2618
+ inner = expandedItem [ '@graph' ] ;
2613
2619
}
2614
2620
2615
2621
// recursively compact expanded item
2616
2622
var compactedItem = this . compact (
2617
- activeCtx , itemActiveProperty , isList ? list : expandedItem , options ) ;
2623
+ activeCtx , itemActiveProperty ,
2624
+ ( isList || isSimpleGraph ) ? inner : expandedItem , options ) ;
2618
2625
2619
2626
// handle @list
2620
2627
if ( isList ) {
@@ -2623,7 +2630,7 @@ Processor.prototype.compact = function(
2623
2630
compactedItem = [ compactedItem ] ;
2624
2631
}
2625
2632
2626
- if ( container !== '@list' ) {
2633
+ if ( ! container . includes ( '@list' ) ) {
2627
2634
// wrap using @list alias
2628
2635
var wrapper = { } ;
2629
2636
wrapper [ _compactIri ( activeCtx , '@list' ) ] = compactedItem ;
@@ -2645,8 +2652,22 @@ Processor.prototype.compact = function(
2645
2652
}
2646
2653
}
2647
2654
2655
+ // handle simple @graph
2656
+ if ( isSimpleGraph && ! container . includes ( '@graph' ) ) {
2657
+ // wrap using @graph alias
2658
+ var wrapper = { } ;
2659
+ wrapper [ _compactIri ( activeCtx , '@graph' ) ] = compactedItem ;
2660
+ compactedItem = wrapper ;
2661
+
2662
+ // include @index from expanded @graph, if any
2663
+ if ( '@index' in expandedItem ) {
2664
+ compactedItem [ _compactIri ( activeCtx , '@index' ) ] =
2665
+ expandedItem [ '@index' ] ;
2666
+ }
2667
+ }
2668
+
2648
2669
// handle language and index maps
2649
- if ( container === '@language' || container === '@index' ) {
2670
+ if ( container . includes ( '@language' ) || container . includes ( '@index' ) ) {
2650
2671
// get or create the map object
2651
2672
var mapObject ;
2652
2673
if ( itemActiveProperty in rval ) {
@@ -2657,7 +2678,7 @@ Processor.prototype.compact = function(
2657
2678
2658
2679
// if container is a language map, simplify compacted value to
2659
2680
// a simple string
2660
- if ( container === '@language' && _isValue ( compactedItem ) ) {
2681
+ if ( container . includes ( '@language' ) && _isValue ( compactedItem ) ) {
2661
2682
compactedItem = compactedItem [ '@value' ] ;
2662
2683
}
2663
2684
@@ -2668,8 +2689,8 @@ Processor.prototype.compact = function(
2668
2689
// use an array if: compactArrays flag is false,
2669
2690
// @container is @set or @list , value is an empty
2670
2691
// array, or key is @graph
2671
- var isArray = ( ! options . compactArrays || container === '@set' ||
2672
- container === '@list' ||
2692
+ var isArray = ( ! options . compactArrays || container . includes ( '@set' ) ||
2693
+ container . includes ( '@list' ) ||
2673
2694
( _isArray ( compactedItem ) && compactedItem . length === 0 ) ||
2674
2695
expandedProperty === '@list' || expandedProperty === '@graph' ) ;
2675
2696
@@ -2907,11 +2928,12 @@ Processor.prototype.expand = function(
2907
2928
}
2908
2929
2909
2930
var container = jsonld . getContextValue ( activeCtx , key , '@container' ) ;
2931
+ container = [ ] . concat ( container ) ;
2910
2932
2911
- if ( container === '@language' && _isObject ( value ) ) {
2933
+ if ( container . includes ( '@language' ) && _isObject ( value ) ) {
2912
2934
// handle language map container (skip if value is not an object)
2913
2935
expandedValue = _expandLanguageMap ( value ) ;
2914
- } else if ( container === '@index' && _isObject ( value ) ) {
2936
+ } else if ( container . includes ( '@index' ) && _isObject ( value ) ) {
2915
2937
// handle index container (skip if value is not an object)
2916
2938
expandedValue = ( function _expandIndexMap ( activeProperty ) {
2917
2939
var rval = [ ] ;
@@ -2961,13 +2983,20 @@ Processor.prototype.expand = function(
2961
2983
2962
2984
// convert expanded value to @list if container specifies it
2963
2985
if ( expandedProperty !== '@list' && ! _isList ( expandedValue ) &&
2964
- container === '@list' ) {
2986
+ container . includes ( '@list' ) ) {
2965
2987
// ensure expanded value is an array
2966
2988
expandedValue = ( _isArray ( expandedValue ) ?
2967
2989
expandedValue : [ expandedValue ] ) ;
2968
2990
expandedValue = { '@list' : expandedValue } ;
2969
2991
}
2970
2992
2993
+ // convert expanded value to @graph if container specifies it
2994
+ if ( container . includes ( '@graph' ) ) {
2995
+ // ensure expanded value is an array
2996
+ expandedValue = [ ] . concat ( expandedValue ) ;
2997
+ expandedValue = { '@graph' : expandedValue } ;
2998
+ }
2999
+
2971
3000
// FIXME: can this be merged with code above to simplify?
2972
3001
// merge in reverse properties
2973
3002
if ( activeCtx . mappings [ key ] && activeCtx . mappings [ key ] . reverse ) {
@@ -3439,6 +3468,18 @@ Processor.prototype.processContext = function(activeCtx, localCtx, options) {
3439
3468
// define context mappings for keys in local context
3440
3469
var defined = { } ;
3441
3470
3471
+ // handle @version
3472
+ if ( '@version' in ctx ) {
3473
+ if ( ctx [ '@version' ] !== 1.1 ) {
3474
+ throw new JsonLdError (
3475
+ 'Unsupported JSON-LD version: ' + ctx [ '@version' ] ,
3476
+ 'jsonld.UnsupportedVersion' ,
3477
+ { code : 'unsupported version' , context : ctx } ) ;
3478
+ }
3479
+ rval [ '@version' ] = ctx [ '@version' ] ;
3480
+ defined [ '@version' ] = true ;
3481
+ }
3482
+
3442
3483
// handle @base
3443
3484
if ( '@base' in ctx ) {
3444
3485
var base = ctx [ '@base' ] ;
@@ -4710,6 +4751,13 @@ function _compactIri(activeCtx, iri, value, relativeTo, reverse) {
4710
4751
containers . push ( '@index' ) ;
4711
4752
}
4712
4753
4754
+ // prefer `['@graph', '@set']` and then `@graph` if value is a simple graph
4755
+ // TODO: support `@graphId`?
4756
+ if ( _isSimpleGraph ( value ) ) {
4757
+ containers . push ( '@graph@set' ) ;
4758
+ containers . push ( '@graph' ) ;
4759
+ }
4760
+
4713
4761
// defaults for term selection based on type/language
4714
4762
var typeOrLanguage = '@language' ;
4715
4763
var typeOrLanguageValue = '@null' ;
@@ -5004,7 +5052,7 @@ function _createTermDefinition(activeCtx, localCtx, term, defined) {
5004
5052
5005
5053
if ( ! _isObject ( value ) ) {
5006
5054
throw new JsonLdError (
5007
- 'Invalid JSON-LD syntax; @context property values must be ' +
5055
+ 'Invalid JSON-LD syntax; @context term values must be ' +
5008
5056
'strings or objects.' ,
5009
5057
'jsonld.SyntaxError' ,
5010
5058
{ code : 'invalid term definition' , context : localCtx } ) ;
@@ -5137,11 +5185,25 @@ function _createTermDefinition(activeCtx, localCtx, term, defined) {
5137
5185
var container = value [ '@container' ] ;
5138
5186
if ( container !== '@list' && container !== '@set' &&
5139
5187
container !== '@index' && container !== '@language' ) {
5140
- throw new JsonLdError (
5141
- 'Invalid JSON-LD syntax; @context @container value must be ' +
5142
- 'one of the following: @list, @set, @index, or @language.' ,
5143
- 'jsonld.SyntaxError' ,
5144
- { code : 'invalid container mapping' , context : localCtx } ) ;
5188
+ let isValid = false ;
5189
+ const validContainers = [ '@list' , '@set' , '@index' , '@language' ] ;
5190
+ // JSON-LD 1.1 support
5191
+ if ( activeCtx [ '@version' ] === 1.1 ) {
5192
+ // || processingMode === 'jsonld-1.1') {
5193
+ validContainers . push ( '@graph' ) ;
5194
+ if ( container === '@graph' ||
5195
+ ( _isArray ( container ) && container . length === 2 &&
5196
+ container . includes ( '@graph' ) && container . includes ( '@set' ) ) ) {
5197
+ isValid = true ;
5198
+ }
5199
+ }
5200
+ if ( ! isValid ) {
5201
+ throw new JsonLdError (
5202
+ 'Invalid JSON-LD syntax; @context @container value must be ' +
5203
+ 'one of the following: ' + validContainers . join ( ', ' ) ,
5204
+ 'jsonld.SyntaxError' ,
5205
+ { code : 'invalid container mapping' , context : localCtx } ) ;
5206
+ }
5145
5207
}
5146
5208
if ( mapping . reverse && container !== '@index' && container !== '@set' &&
5147
5209
container !== null ) {
@@ -5441,6 +5503,7 @@ function _getInitialContext(options) {
5441
5503
var base = jsonld . url . parse ( options . base || '' ) ;
5442
5504
return {
5443
5505
'@base' : base ,
5506
+ '@version' : 1.0 ,
5444
5507
mappings : { } ,
5445
5508
inverse : null ,
5446
5509
getInverse : _createInverseContext ,
@@ -5481,6 +5544,7 @@ function _getInitialContext(options) {
5481
5544
}
5482
5545
5483
5546
var container = mapping [ '@container' ] || '@none' ;
5547
+ container = [ ] . concat ( container ) . sort ( ) . join ( '' ) ;
5484
5548
5485
5549
// iterate over every IRI in the mapping
5486
5550
var ids = mapping [ '@id' ] ;
@@ -5653,6 +5717,7 @@ function _isKeyword(v) {
5653
5717
case '@set' :
5654
5718
case '@type' :
5655
5719
case '@value' :
5720
+ case '@version' :
5656
5721
case '@vocab' :
5657
5722
return true ;
5658
5723
}
@@ -5856,6 +5921,24 @@ function _isList(v) {
5856
5921
return _isObject ( v ) && ( '@list' in v ) ;
5857
5922
}
5858
5923
5924
+ /**
5925
+ * Returns true if the given value is a simple @graph.
5926
+ *
5927
+ * @return true if the value is a simple @graph, false if not.
5928
+ */
5929
+ function _isSimpleGraph ( v ) {
5930
+ // Note: A value is a simple graph if all of these hold true:
5931
+ // 1. It is an object.
5932
+ // 2. It has an `@graph` key.
5933
+ // 3. It has only 1 key or 2 keys where one of them is `@index`.
5934
+ if ( ! _isObject ( v ) ) {
5935
+ return false ;
5936
+ }
5937
+ const keyLength = Object . keys ( v ) . length ;
5938
+ return ( '@graph' in v &&
5939
+ ( keyLength === 1 || ( keyLength === 2 && '@index' in v ) ) ) ;
5940
+ }
5941
+
5859
5942
/**
5860
5943
* Returns true if the given value is a blank node.
5861
5944
*
0 commit comments