Skip to content

Commit b703a19

Browse files
gkelloggdavidlehn
authored andcommitted
Update expansion to use array forms for various keywords when framing.
Update framing for graphs and _filterSubject logic.
1 parent ca2810b commit b703a19

File tree

3 files changed

+264
-75
lines changed

3 files changed

+264
-75
lines changed

lib/expand.js

Lines changed: 71 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const JsonLdError = require('./JsonLdError');
88
const {
99
isArray: _isArray,
1010
isObject: _isObject,
11+
isEmptyObject: _isEmptyObject,
1112
isString: _isString
1213
} = require('./types');
1314

@@ -31,7 +32,8 @@ const {
3132

3233
const {
3334
addValue: _addValue,
34-
validateTypeValue: _validateTypeValue
35+
validateTypeValue: _validateTypeValue,
36+
getValues: _getValues
3537
} = require('./util');
3638

3739
const api = {};
@@ -206,8 +208,11 @@ api.expand = ({
206208
'which can be "@type" or "@language".',
207209
'jsonld.SyntaxError', {code: 'invalid value object', element: rval});
208210
}
211+
const values = rval['@value'] === null ? [] : [].concat(rval['@value']);
212+
const types = _getValues(rval, '@type');
213+
209214
// drop null @values unless custom mapped
210-
if(rval['@value'] === null) {
215+
if(values.length === 0) {
211216
// TODO: use `await` to support async
212217
const mapped = expansionMap({
213218
unmappedValue: rval,
@@ -222,15 +227,16 @@ api.expand = ({
222227
} else {
223228
rval = null;
224229
}
225-
} else if('@language' in rval && !_isString(rval['@value'])) {
230+
} else if(!values.every(v => (_isString(v) || _isEmptyObject(v))) && '@language' in rval) {
226231
// if @language is present, @value must be a string
227232
throw new JsonLdError(
228233
'Invalid JSON-LD syntax; only strings may be language-tagged.',
229234
'jsonld.SyntaxError',
230235
{code: 'invalid language-tagged value', element: rval});
231-
} else if('@type' in rval && (!_isAbsoluteIri(rval['@type']) ||
232-
rval['@type'].indexOf('_:') === 0)) {
233-
throw new JsonLdError(
236+
} else if(!types.every(t =>
237+
(_isAbsoluteIri(t) && !(_isString(t) && t.indexOf('_:') === 0) ||
238+
_isEmptyObject(t)))) {
239+
throw new JsonLdError(
234240
'Invalid JSON-LD syntax; an element containing "@value" and "@type" ' +
235241
'must have an absolute IRI for the value of "@type".',
236242
'jsonld.SyntaxError', {code: 'invalid typed value', element: rval});
@@ -373,22 +379,50 @@ function _expandObject({
373379
}
374380

375381
// syntax error if @id is not a string
376-
if(expandedProperty === '@id' && !_isString(value)) {
377-
if(!options.isFrame) {
378-
throw new JsonLdError(
379-
'Invalid JSON-LD syntax; "@id" value must a string.',
380-
'jsonld.SyntaxError', {code: 'invalid @id value', value: value});
381-
}
382-
if(!_isObject(value)) {
383-
throw new JsonLdError(
384-
'Invalid JSON-LD syntax; "@id" value must be a string or an ' +
385-
'object.', 'jsonld.SyntaxError',
386-
{code: 'invalid @id value', value: value});
382+
if(expandedProperty === '@id') {
383+
if(!_isString(value)) {
384+
if(!options.isFrame) {
385+
throw new JsonLdError(
386+
'Invalid JSON-LD syntax; "@id" value must a string.',
387+
'jsonld.SyntaxError', {code: 'invalid @id value', value: value});
388+
}
389+
if(_isObject(value)) {
390+
// empty object is a wildcard
391+
if(!_isEmptyObject(value)) {
392+
throw new JsonLdError(
393+
'Invalid JSON-LD syntax; "@id" value an empty object or array of strings, if framing',
394+
'jsonld.SyntaxError', {code: 'invalid @id value', value: value});
395+
}
396+
} else if(_isArray(value)) {
397+
if(!value.every(v => _isString(v))) {
398+
throw new JsonLdError(
399+
'Invalid JSON-LD syntax; "@id" value an empty object or array of strings, if framing',
400+
'jsonld.SyntaxError', {code: 'invalid @id value', value: value});
401+
}
402+
} else {
403+
throw new JsonLdError(
404+
'Invalid JSON-LD syntax; "@id" value an empty object or array of strings, if framing',
405+
'jsonld.SyntaxError', {code: 'invalid @id value', value: value});
406+
}
387407
}
408+
409+
_addValue(
410+
expandedParent, '@id',
411+
[].concat(value).map(v => _isString(v) ? _expandIri(activeCtx, v, {base: true}) : v),
412+
{propertyIsArray: options.isFrame});
413+
continue;
388414
}
389415

390416
if(expandedProperty === '@type') {
391417
_validateTypeValue(value);
418+
_addValue(
419+
expandedParent, '@type',
420+
[].concat(value).map(v =>
421+
_isString(v) ?
422+
_expandIri(activeCtx, v, {base: true, vocab: true}) :
423+
v),
424+
{propertyIsArray: options.isFrame});
425+
continue;
392426
}
393427

394428
// @graph must be an array or an object
@@ -400,14 +434,19 @@ function _expandObject({
400434
'jsonld.SyntaxError', {code: 'invalid @graph value', value: value});
401435
}
402436

403-
// @value must not be an object or an array
404-
if(expandedProperty === '@value' &&
405-
(_isObject(value) || _isArray(value))) {
406-
throw new JsonLdError(
407-
'Invalid JSON-LD syntax; "@value" value must not be an ' +
408-
'object or an array.',
409-
'jsonld.SyntaxError',
410-
{code: 'invalid value object value', value: value});
437+
// @value must not be an object or an array (unless framing)
438+
if(expandedProperty === '@value') {
439+
if((_isObject(value) || _isArray(value)) && !options.isFrame) {
440+
throw new JsonLdError(
441+
'Invalid JSON-LD syntax; "@value" value must not be an ' +
442+
'object or an array.',
443+
'jsonld.SyntaxError',
444+
{code: 'invalid value object value', value: value});
445+
}
446+
447+
_addValue(
448+
expandedParent, '@value', value, {propertyIsArray: options.isFrame});
449+
continue;
411450
}
412451

413452
// @language must be a string
@@ -416,14 +455,18 @@ function _expandObject({
416455
// drop null @language values, they expand as if they didn't exist
417456
continue;
418457
}
419-
if(!_isString(value)) {
458+
if(!_isString(value) && !options.isFrame) {
420459
throw new JsonLdError(
421460
'Invalid JSON-LD syntax; "@language" value must be a string.',
422461
'jsonld.SyntaxError',
423462
{code: 'invalid language-tagged string', value: value});
424463
}
425464
// ensure language value is lowercase
426465
value = value.toLowerCase();
466+
467+
_addValue(
468+
expandedParent, '@language', value, {propertyIsArray: options.isFrame});
469+
continue;
427470
}
428471

429472
// @index must be a string
@@ -434,6 +477,8 @@ function _expandObject({
434477
'jsonld.SyntaxError',
435478
{code: 'invalid @index value', value: value});
436479
}
480+
_addValue(expandedParent, '@index', value);
481+
continue;
437482
}
438483

439484
// @reverse must be an object

0 commit comments

Comments
 (0)