Skip to content

Commit d1dbda1

Browse files
committed
Use events for language value warnings.
1 parent bf23404 commit d1dbda1

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
@@ -1432,4 +1432,109 @@ describe('events', () => {
14321432
assert.equal(ranHandler3, true, 'ran handler 3');
14331433
assert.equal(handled, true, 'handled');
14341434
});
1435+
it('handle known warning events', async () => {
1436+
const d =
1437+
{
1438+
"@context": {
1439+
"id-at": {"@id": "@test"},
1440+
"@RESERVED": "ex:test"
1441+
},
1442+
"@RESERVED": "test",
1443+
"ex:language": {
1444+
"@value": "test",
1445+
"@language": "!"
1446+
}
1447+
}
1448+
;
1449+
const ex =
1450+
[
1451+
{
1452+
"ex:language": [
1453+
{
1454+
"@value": "test",
1455+
"@language": "!"
1456+
}
1457+
]
1458+
}
1459+
]
1460+
;
1461+
1462+
let handledReservedTerm = false;
1463+
let handledReservedValue = false;
1464+
let handledLanguage = false;
1465+
const e = await jsonld.expand(d, {
1466+
handleEvent: {
1467+
'invalid reserved term': () => {
1468+
handledReservedTerm = true;
1469+
},
1470+
'invalid reserved value': () => {
1471+
handledReservedValue = true;
1472+
},
1473+
'invalid @language value': () => {
1474+
handledLanguage = true;
1475+
}
1476+
}
1477+
});
1478+
assert.deepStrictEqual(e, ex);
1479+
assert.equal(handledReservedTerm, true);
1480+
assert.equal(handledReservedValue, true);
1481+
assert.equal(handledLanguage, true);
1482+
1483+
// dataset with invalid language tag
1484+
// Equivalent N-Quads:
1485+
// <ex:s> <ex:p> "..."^^<https://www.w3.org/ns/i18n#!_rtl> .'
1486+
// Using JSON dataset to bypass N-Quads parser checks.
1487+
const d2 =
1488+
[
1489+
{
1490+
"subject": {
1491+
"termType": "NamedNode",
1492+
"value": "ex:s"
1493+
},
1494+
"predicate": {
1495+
"termType": "NamedNode",
1496+
"value": "ex:p"
1497+
},
1498+
"object": {
1499+
"termType": "Literal",
1500+
"value": "invalid @language value",
1501+
"datatype": {
1502+
"termType": "NamedNode",
1503+
"value": "https://www.w3.org/ns/i18n#!_rtl"
1504+
}
1505+
},
1506+
"graph": {
1507+
"termType": "DefaultGraph",
1508+
"value": ""
1509+
}
1510+
}
1511+
]
1512+
;
1513+
const ex2 =
1514+
[
1515+
{
1516+
"@id": "ex:s",
1517+
"ex:p": [
1518+
{
1519+
"@value": "invalid @language value",
1520+
"@language": "!",
1521+
"@direction": "rtl"
1522+
}
1523+
]
1524+
}
1525+
]
1526+
;
1527+
1528+
let handledLanguage2 = false;
1529+
const e2 = await jsonld.fromRDF(d2, {
1530+
rdfDirection: 'i18n-datatype',
1531+
handleEvent: {
1532+
'invalid @language value': () => {
1533+
handledLanguage2 = true;
1534+
}
1535+
}
1536+
});
1537+
assert.deepStrictEqual(e2, ex2);
1538+
assert.equal(handledLanguage2, true);
1539+
});
14351540
});

0 commit comments

Comments
 (0)