Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update direction support. #534

Merged
merged 3 commits into from
Sep 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# jsonld ChangeLog

## 8.3.0 - 2023-09-xx

### Added
- Emit `toRdf` warning if `@direction` is used and `rdfDirection` is not set.

### Fixed
- Add safe mode support for `@direction`. Using `@direction` without
`rdfDirection` set will cause a safe mode failure.

## 8.2.1 - 2023-08-31

### Fixed
Expand Down
6 changes: 3 additions & 3 deletions benchmarks/compare/compare.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
#!/usr/bin/env node

import yargs from 'yargs';
import {hideBin} from 'yargs/helpers';
import commonPathPrefix from 'common-path-prefix';
import {promises as fs} from 'node:fs';
import {hideBin} from 'yargs/helpers';
import {markdownTable} from 'markdown-table';
import commonPathPrefix from 'common-path-prefix';
import yargs from 'yargs';

yargs(hideBin(process.argv))
.alias('h', 'help')
Expand Down
4 changes: 3 additions & 1 deletion lib/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,9 @@ const _notSafeEventCodes = new Set([
'relative graph reference',
'relative object reference',
'relative predicate reference',
'relative subject reference'
'relative subject reference',
// toRDF / fromRDF
'rdfDirection not set'
]);

// safe handler that rejects unsafe warning conditions
Expand Down
22 changes: 18 additions & 4 deletions lib/fromRdf.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved.
* Copyright (c) 2017-2023 Digital Bazaar, Inc. All rights reserved.
*/
'use strict';

Expand Down Expand Up @@ -52,14 +52,28 @@ api.fromRDF = async (
dataset,
options
) => {
const defaultGraph = {};
const graphMap = {'@default': defaultGraph};
const referencedOnce = {};
const {
useRdfType = false,
useNativeTypes = false,
rdfDirection = null
} = options;
// FIXME: use Maps?
const defaultGraph = {};
const graphMap = {'@default': defaultGraph};
const referencedOnce = {};
if(rdfDirection) {
if(rdfDirection === 'compound-literal') {
throw new JsonLdError(
'Unsupported rdfDirection value.',
'jsonld.InvalidRdfDirection',
{value: rdfDirection});
} else if(rdfDirection !== 'i18n-datatype') {
throw new JsonLdError(
'Unknown rdfDirection value.',
'jsonld.InvalidRdfDirection',
{value: rdfDirection});
}
}

for(const quad of dataset) {
// TODO: change 'name' to 'graph'
Expand Down
17 changes: 12 additions & 5 deletions lib/jsonld.js
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ const _resolvedContextCache = new LRU({max: RESOLVED_CONTEXT_CACHE_MAX_SIZE});
* [graph] true to always output a top-level graph (default: false).
* [expandContext] a context to expand with.
* [skipExpansion] true to assume the input is expanded and skip
* expansion, false not to, defaults to false.
* expansion, false not to, defaults to false. Some well-formed
* and safe-mode checks may be omitted.
* [documentLoader(url, options)] the document loader.
* [framing] true if compaction is occuring during a framing operation.
* [safe] true to use safe mode. (default: false)
Expand Down Expand Up @@ -538,13 +539,16 @@ jsonld.link = async function(input, ctx, options) {
* [base] the base IRI to use (default: `null`).
* [expandContext] a context to expand with.
* [skipExpansion] true to assume the input is expanded and skip
* expansion, false not to, defaults to false.
* expansion, false not to, defaults to false. Some well-formed
* and safe-mode checks may be omitted.
* [inputFormat] the format if input is not JSON-LD:
* 'application/n-quads' for N-Quads.
* [format] the format if output is a string:
* 'application/n-quads' for N-Quads.
* [documentLoader(url, options)] the document loader.
* [useNative] true to use a native canonize algorithm
* [rdfDirection] null or 'i18n-datatype' to support RDF
* transformation of @direction (default: null).
* [safe] true to use safe mode. (default: true).
* [contextResolver] internal use only.
*
Expand Down Expand Up @@ -601,8 +605,8 @@ jsonld.normalize = jsonld.canonize = async function(input, options) {
* (default: false).
* [useNativeTypes] true to convert XSD types into native types
* (boolean, integer, double), false not to (default: false).
* [rdfDirection] 'i18n-datatype' to support RDF transformation of
* @direction (default: null).
* [rdfDirection] null or 'i18n-datatype' to support RDF
* transformation of @direction (default: null).
* [safe] true to use safe mode. (default: false)
*
* @return a Promise that resolves to the JSON-LD document.
Expand Down Expand Up @@ -647,13 +651,16 @@ jsonld.fromRDF = async function(dataset, options) {
* [base] the base IRI to use.
* [expandContext] a context to expand with.
* [skipExpansion] true to assume the input is expanded and skip
* expansion, false not to, defaults to false.
* expansion, false not to, defaults to false. Some well-formed
* and safe-mode checks may be omitted.
* [format] the format to use to output a string:
* 'application/n-quads' for N-Quads.
* [produceGeneralizedRdf] true to output generalized RDF, false
* to produce only standard RDF (default: false).
* [documentLoader(url, options)] the document loader.
* [safe] true to use safe mode. (default: false)
* [rdfDirection] null or 'i18n-datatype' to support RDF
* transformation of @direction (default: null).
* [contextResolver] internal use only.
*
* @return a Promise that resolves to the RDF dataset.
Expand Down
56 changes: 50 additions & 6 deletions lib/toRdf.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/*
* Copyright (c) 2017 Digital Bazaar, Inc. All rights reserved.
* Copyright (c) 2017-2023 Digital Bazaar, Inc. All rights reserved.
*/
'use strict';

const {createNodeMap} = require('./nodeMap');
const {isKeyword} = require('./context');
const graphTypes = require('./graphTypes');
const jsonCanonicalize = require('canonicalize');
const JsonLdError = require('./JsonLdError');
const types = require('./types');
const util = require('./util');

Expand Down Expand Up @@ -312,18 +313,61 @@ function _objectToRDF(
} else if(types.isNumber(value)) {
object.value = value.toFixed(0);
object.datatype.value = datatype || XSD_INTEGER;
} else if(rdfDirection === 'i18n-datatype' &&
'@direction' in item) {
const datatype = 'https://www.w3.org/ns/i18n#' +
(item['@language'] || '') +
`_${item['@direction']}`;
} else if('@direction' in item && rdfDirection === 'i18n-datatype') {
const language = (item['@language'] || '').toLowerCase();
const direction = item['@direction'];
const datatype = `https://www.w3.org/ns/i18n#${language}_${direction}`;
object.datatype.value = datatype;
object.value = value;
} else if('@direction' in item && rdfDirection === 'compound-literal') {
throw new JsonLdError(
'Unsupported rdfDirection value.',
'jsonld.InvalidRdfDirection',
{value: rdfDirection});
} else if('@direction' in item && rdfDirection) {
throw new JsonLdError(
'Unknown rdfDirection value.',
'jsonld.InvalidRdfDirection',
{value: rdfDirection});
} else if('@language' in item) {
if('@direction' in item && rdfDirection === null) {
if(options.eventHandler) {
// FIXME: only emit once?
_handleEvent({
event: {
type: ['JsonLdEvent'],
code: 'rdfDirection not set',
level: 'warning',
message: 'rdfDirection not set for @direction.',
details: {
object: object.value
}
},
options
});
}
}
object.value = value;
object.datatype.value = datatype || RDF_LANGSTRING;
object.language = item['@language'];
} else {
if('@direction' in item && rdfDirection === null) {
if(options.eventHandler) {
// FIXME: only emit once?
_handleEvent({
event: {
type: ['JsonLdEvent'],
code: 'rdfDirection not set',
level: 'warning',
message: 'rdfDirection not set for @direction.',
details: {
object: object.value
}
},
options
});
}
}
object.value = value;
object.datatype.value = datatype || XSD_STRING;
}
Expand Down
Loading
Loading