Skip to content

Commit e84e691

Browse files
committed
Use events for language value warnings.
1 parent 32f481a commit e84e691

File tree

4 files changed

+149
-11
lines changed

4 files changed

+149
-11
lines changed

lib/expand.js

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ const {
3939
validateTypeValue: _validateTypeValue
4040
} = require('./util');
4141

42+
const {
43+
handleEvent: _handleEvent
44+
} = require('./events');
45+
4246
const api = {};
4347
module.exports = api;
4448
const REGEX_BCP47 = /^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/;
@@ -609,9 +613,19 @@ async function _expandObject({
609613
value = _asArray(value).map(v => _isString(v) ? v.toLowerCase() : v);
610614

611615
// ensure language tag matches BCP47
612-
for(const lang of value) {
613-
if(_isString(lang) && !lang.match(REGEX_BCP47)) {
614-
console.warn(`@language must be valid BCP47: ${lang}`);
616+
for(const language of value) {
617+
if(_isString(language) && !language.match(REGEX_BCP47)) {
618+
_handleEvent({
619+
event: {
620+
code: 'invalid @language value',
621+
level: 'warning',
622+
message: '@language value must be valid BCP47.',
623+
details: {
624+
language
625+
}
626+
},
627+
options
628+
});
615629
}
616630
}
617631

lib/fromRdf.js

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ const graphTypes = require('./graphTypes');
88
const types = require('./types');
99
const util = require('./util');
1010

11+
const {
12+
handleEvent: _handleEvent
13+
} = require('./events');
14+
1115
// constants
1216
const {
1317
// RDF,
@@ -44,15 +48,16 @@ module.exports = api;
4448
*/
4549
api.fromRDF = async (
4650
dataset,
47-
{
48-
useRdfType = false,
49-
useNativeTypes = false,
50-
rdfDirection = null
51-
}
51+
options
5252
) => {
5353
const defaultGraph = {};
5454
const graphMap = {'@default': defaultGraph};
5555
const referencedOnce = {};
56+
const {
57+
useRdfType = false,
58+
useNativeTypes = false,
59+
rdfDirection = null
60+
} = options;
5661

5762
for(const quad of dataset) {
5863
// TODO: change 'name' to 'graph'
@@ -87,7 +92,7 @@ api.fromRDF = async (
8792
continue;
8893
}
8994

90-
const value = _RDFToObject(o, useNativeTypes, rdfDirection);
95+
const value = _RDFToObject(o, useNativeTypes, rdfDirection, options);
9196
util.addValue(node, p, value, {propertyIsArray: true});
9297

9398
// object may be an RDF list/partial list node but we can't know easily
@@ -275,10 +280,12 @@ api.fromRDF = async (
275280
*
276281
* @param o the RDF triple object to convert.
277282
* @param useNativeTypes true to output native types, false not to.
283+
* @param rdfDirection text direction mode [null, i18n-datatype]
284+
* @param options top level API options
278285
*
279286
* @return the JSON-LD object.
280287
*/
281-
function _RDFToObject(o, useNativeTypes, rdfDirection) {
288+
function _RDFToObject(o, useNativeTypes, rdfDirection, options) {
282289
// convert NamedNode/BlankNode object to JSON-LD
283290
if(o.termType.endsWith('Node')) {
284291
return {'@id': o.value};
@@ -334,7 +341,17 @@ function _RDFToObject(o, useNativeTypes, rdfDirection) {
334341
if(language.length > 0) {
335342
rval['@language'] = language;
336343
if(!language.match(REGEX_BCP47)) {
337-
console.warn(`@language must be valid BCP47: ${language}`);
344+
_handleEvent({
345+
event: {
346+
code: 'invalid @language value',
347+
level: 'warning',
348+
message: '@language value must be valid BCP47.',
349+
details: {
350+
language
351+
}
352+
},
353+
options
354+
});
338355
}
339356
}
340357
rval['@direction'] = direction;

lib/jsonld.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -602,6 +602,8 @@ jsonld.normalize = jsonld.canonize = async function(input, options) {
602602
* (default: false).
603603
* [useNativeTypes] true to convert XSD types into native types
604604
* (boolean, integer, double), false not to (default: false).
605+
* [rdfDirection] 'i18n-datatype' to support RDF transformation of
606+
* @direction (default: null).
605607
* [handleEvent] handler for events such as warnings.
606608
*
607609
* @return a Promise that resolves to the JSON-LD document.

tests/misc.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1174,4 +1174,109 @@ describe('events', () => {
11741174
assert.equal(ranHandler3, true, 'ran handler 3');
11751175
assert.equal(handled, true, 'handled');
11761176
});
1177+
it('handle known warning events', async () => {
1178+
const d =
1179+
{
1180+
"@context": {
1181+
"id-at": {"@id": "@test"},
1182+
"@RESERVED": "ex:test"
1183+
},
1184+
"@RESERVED": "test",
1185+
"ex:language": {
1186+
"@value": "test",
1187+
"@language": "!"
1188+
}
1189+
}
1190+
;
1191+
const ex =
1192+
[
1193+
{
1194+
"ex:language": [
1195+
{
1196+
"@value": "test",
1197+
"@language": "!"
1198+
}
1199+
]
1200+
}
1201+
]
1202+
;
1203+
1204+
let handledReservedTerm = false;
1205+
let handledReservedValue = false;
1206+
let handledLanguage = false;
1207+
const e = await jsonld.expand(d, {
1208+
handleEvent: {
1209+
'invalid reserved term': () => {
1210+
handledReservedTerm = true;
1211+
},
1212+
'invalid reserved value': () => {
1213+
handledReservedValue = true;
1214+
},
1215+
'invalid @language value': () => {
1216+
handledLanguage = true;
1217+
}
1218+
}
1219+
});
1220+
assert.deepStrictEqual(e, ex);
1221+
assert.equal(handledReservedTerm, true);
1222+
assert.equal(handledReservedValue, true);
1223+
assert.equal(handledLanguage, true);
1224+
1225+
// dataset with invalid language tag
1226+
// Equivalent N-Quads:
1227+
// <ex:s> <ex:p> "..."^^<https://www.w3.org/ns/i18n#!_rtl> .'
1228+
// Using JSON dataset to bypass N-Quads parser checks.
1229+
const d2 =
1230+
[
1231+
{
1232+
"subject": {
1233+
"termType": "NamedNode",
1234+
"value": "ex:s"
1235+
},
1236+
"predicate": {
1237+
"termType": "NamedNode",
1238+
"value": "ex:p"
1239+
},
1240+
"object": {
1241+
"termType": "Literal",
1242+
"value": "invalid @language value",
1243+
"datatype": {
1244+
"termType": "NamedNode",
1245+
"value": "https://www.w3.org/ns/i18n#!_rtl"
1246+
}
1247+
},
1248+
"graph": {
1249+
"termType": "DefaultGraph",
1250+
"value": ""
1251+
}
1252+
}
1253+
]
1254+
;
1255+
const ex2 =
1256+
[
1257+
{
1258+
"@id": "ex:s",
1259+
"ex:p": [
1260+
{
1261+
"@value": "invalid @language value",
1262+
"@language": "!",
1263+
"@direction": "rtl"
1264+
}
1265+
]
1266+
}
1267+
]
1268+
;
1269+
1270+
let handledLanguage2 = false;
1271+
const e2 = await jsonld.fromRDF(d2, {
1272+
rdfDirection: 'i18n-datatype',
1273+
handleEvent: {
1274+
'invalid @language value': () => {
1275+
handledLanguage2 = true;
1276+
}
1277+
}
1278+
});
1279+
assert.deepStrictEqual(e2, ex2);
1280+
assert.equal(handledLanguage2, true);
1281+
});
11771282
});

0 commit comments

Comments
 (0)