@@ -213,12 +213,16 @@ api.expand = async ({
213
213
// set the type-scoped context to the context on input, for use later
214
214
typeScopedContext = activeCtx ;
215
215
216
+ // Remember the first key found expanding to @type
217
+ let typeKey = null ;
218
+
216
219
// look for scoped contexts on `@type`
217
220
for ( const key of keys ) {
218
221
const expandedProperty = _expandIri ( activeCtx , key , { vocab : true } , options ) ;
219
222
if ( expandedProperty === '@type' ) {
220
223
// set scoped contexts from @type
221
224
// avoid sorting if possible
225
+ typeKey = typeKey || key ;
222
226
const value = element [ key ] ;
223
227
const types =
224
228
Array . isArray ( value ) ?
@@ -248,6 +252,7 @@ api.expand = async ({
248
252
options,
249
253
insideList,
250
254
typeScopedContext,
255
+ typeKey,
251
256
expansionMap} ) ;
252
257
253
258
// get property count on expanded output
@@ -283,7 +288,10 @@ api.expand = async ({
283
288
const types = _getValues ( rval , '@type' ) ;
284
289
285
290
// drop null @values unless custom mapped
286
- if ( values . length === 0 ) {
291
+ if ( _processingMode ( activeCtx , 1.1 ) && types . includes ( '@json' ) &&
292
+ types . length === 1 ) {
293
+ // Any value of @value is okay if @type: @json
294
+ } else if ( values . length === 0 ) {
287
295
const mapped = await expansionMap ( {
288
296
unmappedValue : rval ,
289
297
activeCtx,
@@ -304,9 +312,6 @@ api.expand = async ({
304
312
'Invalid JSON-LD syntax; only strings may be language-tagged.' ,
305
313
'jsonld.SyntaxError' ,
306
314
{ code : 'invalid language-tagged value' , element : rval } ) ;
307
- } else if ( _processingMode ( activeCtx , 1.1 ) && types . includes ( '@json' ) &&
308
- types . length === 1 ) {
309
- // Any value of @value is okay if @type: @json
310
315
} else if ( ! types . every ( t =>
311
316
( _isAbsoluteIri ( t ) && ! ( _isString ( t ) && t . indexOf ( '_:' ) === 0 ) ||
312
317
_isEmptyObject ( t ) ) ) ) {
@@ -402,11 +407,20 @@ async function _expandObject({
402
407
options = { } ,
403
408
insideList,
404
409
typeScopedContext,
410
+ typeKey,
405
411
expansionMap
406
412
} ) {
407
413
const keys = Object . keys ( element ) . sort ( ) ;
408
414
const nests = [ ] ;
409
415
let unexpandedValue ;
416
+
417
+ // Remember inputType to aid with JSON literals
418
+ let inputType = element [ typeKey ] ;
419
+ if ( inputType ) {
420
+ inputType = _asArray ( inputType ) . slice ( - 1 ) [ 0 ] ;
421
+ inputType = _expandIri ( activeCtx , inputType , { vocab : true } , options ) ;
422
+ }
423
+
410
424
for ( const key of keys ) {
411
425
let value = element [ key ] ;
412
426
let expandedValue ;
@@ -517,8 +531,13 @@ async function _expandObject({
517
531
// capture value for later
518
532
// "colliding keywords" check prevents this from being set twice
519
533
unexpandedValue = value ;
520
- _addValue (
521
- expandedParent , '@value' , value , { propertyIsArray : options . isFrame } ) ;
534
+ if ( inputType === '@json' && _processingMode ( activeCtx , 1.1 ) ) {
535
+ // no coercion to array, and retain all values
536
+ expandedParent [ '@value' ] = value ;
537
+ } else {
538
+ _addValue (
539
+ expandedParent , '@value' , value , { propertyIsArray : options . isFrame } ) ;
540
+ }
522
541
continue ;
523
542
}
524
543
@@ -803,6 +822,7 @@ async function _expandObject({
803
822
expandedParent,
804
823
options,
805
824
insideList,
825
+ typeKey,
806
826
expansionMap} ) ;
807
827
}
808
828
}
0 commit comments