From 942404ba28501812aa895e5cee56b2d8e263afd7 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Mon, 2 Dec 2019 15:28:40 -0800 Subject: [PATCH 1/2] `@type` may be used as a term definition only if `"@container": "@set"`. --- CHANGELOG.md | 1 + lib/compact.js | 13 +++++++++++-- lib/context.js | 33 +++++++++++++++++++++++---------- tests/test-common.js | 3 --- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea7a1ef5..c468a520 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ - Better checking of absolute IRIs. - Terms that begin with a ':' are not considered absolute or compact IRIs. - Don't use terms with `"@prefix": false` or expanded term definitions to construct compact IRIs. +- "@type" may be used as a term definition only if "@container": "@set". ### Removed - **BREAKING**: Remove callback API support. This includes removing support diff --git a/lib/compact.js b/lib/compact.js index 66369c18..d43d999e 100644 --- a/lib/compact.js +++ b/lib/compact.js @@ -24,7 +24,8 @@ const { expandIri: _expandIri, getContextValue: _getContextValue, isKeyword: _isKeyword, - process: _processContext + process: _processContext, + processingMode: _processingMode } = require('./context'); const { @@ -220,7 +221,15 @@ api.compact = async ({ // use keyword alias and add value const alias = api.compactIri( {activeCtx, iri: expandedProperty, relativeTo: {vocab: true}}); - const isArray = _isArray(compactedValue) && expandedValue.length === 0; + const container = _getContextValue( + activeCtx, alias, '@container') || []; + + // treat as array for @type if @container includes @set + const typeAsSet = isType && + container.includes('@set') && + _processingMode(activeCtx, 1.1); + const isArray = + (_isArray(compactedValue) && expandedValue.length === 0) || typeAsSet; _addValue(rval, alias, compactedValue, {propertyIsArray: isArray}); continue; } diff --git a/lib/context.js b/lib/context.js index bb33d82f..1d69a916 100644 --- a/lib/context.js +++ b/lib/context.js @@ -315,14 +315,30 @@ api.createTermDefinition = ( // now defining term defined.set(term, false); - if(api.isKeyword(term)) { + // get context term value + let value; + if(localCtx.hasOwnProperty(term)) { + value = localCtx[term]; + } + + if(term === '@type' && + _isObject(value) && + value['@container'] === '@set' && + api.processingMode(activeCtx, 1.1)) { + + const validKeys = ['@container', '@id', '@protected']; + if(Object.keys(value).some(k => !validKeys.includes(k))) { + throw new JsonLdError( + 'Invalid JSON-LD syntax; keywords cannot be overridden.', + 'jsonld.SyntaxError', + {code: 'keyword redefinition', context: localCtx, term}); + } + } else if(api.isKeyword(term)) { throw new JsonLdError( 'Invalid JSON-LD syntax; keywords cannot be overridden.', 'jsonld.SyntaxError', {code: 'keyword redefinition', context: localCtx, term}); - } - - if(term === '') { + } else if(term === '') { throw new JsonLdError( 'Invalid JSON-LD syntax; a term cannot be an empty string.', 'jsonld.SyntaxError', @@ -337,12 +353,6 @@ api.createTermDefinition = ( activeCtx.mappings.delete(term); } - // get context term value - let value; - if(localCtx.hasOwnProperty(term)) { - value = localCtx[term]; - } - // clear context entry if(value === null || (_isObject(value) && value['@id'] === null)) { activeCtx.mappings.set(term, null); @@ -468,6 +478,9 @@ api.createTermDefinition = ( // term is an absolute IRI mapping['@id'] = term; } + } else if(term == '@type') { + // Special case, were we've previously determined that container is @set + mapping['@id'] = term; } else { // non-IRIs *must* define @ids if @vocab is not available if(!('@vocab' in activeCtx)) { diff --git a/tests/test-common.js b/tests/test-common.js index 2129378c..eeea0989 100644 --- a/tests/test-common.js +++ b/tests/test-common.js @@ -32,9 +32,6 @@ const TEST_TYPES = { specVersion: ['json-ld-1.0'], // FIXME idRegex: [ - // type set - /compact-manifest.jsonld#t0104$/, - /compact-manifest.jsonld#t0105$/, // @type: @none /compact-manifest.jsonld#ttn01$/, /compact-manifest.jsonld#ttn02$/, From 2d0f5614fb4ece9b5e017903aa4445de40cbef84 Mon Sep 17 00:00:00 2001 From: Gregg Kellogg Date: Tue, 3 Dec 2019 14:37:25 -0500 Subject: [PATCH 2/2] Update lib/compact.js with @davidlehn suggestion. Co-Authored-By: David I. Lehn --- lib/compact.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compact.js b/lib/compact.js index d43d999e..501bd938 100644 --- a/lib/compact.js +++ b/lib/compact.js @@ -229,7 +229,7 @@ api.compact = async ({ container.includes('@set') && _processingMode(activeCtx, 1.1); const isArray = - (_isArray(compactedValue) && expandedValue.length === 0) || typeAsSet; + typeAsSet || (_isArray(compactedValue) && expandedValue.length === 0); _addValue(rval, alias, compactedValue, {propertyIsArray: isArray}); continue; }