graphdb
Version:
Javascript client library supporting GraphDB and RDF4J REST API.
419 lines (399 loc) • 14.2 kB
JavaScript
;
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
var N3 = require('n3');
var DataFactory = N3.DataFactory;
var namedNode = DataFactory.namedNode,
literal = DataFactory.literal,
quad = DataFactory.quad,
blankNode = DataFactory.blankNode,
variable = DataFactory.variable;
var StringUtils = require('../util/string-utils');
var base64url = require('base64url');
var ENCODED_RDFSTAR_TRIPLE_PREFIX = 'urn:rdf4j:triple:';
/**
* Utility class for converting strings to terms, terms to quads and
* quads to string according to the {@link https://rdf.js.org} specification.
*
* @class
* @author Mihail Radkov
* @author Svilen Velikov
* @author Teodossi Dossev
*/
var TermConverter = /*#__PURE__*/function () {
function TermConverter() {
_classCallCheck(this, TermConverter);
}
return _createClass(TermConverter, null, [{
key: "getQuads",
value:
/**
* Convert the supplied params to a collection of quads.
*
* The produced quads size depends on the supplied amount of context.
*
* @public
* @static
* @param {string} subject the quad's subject
* @param {string} predicate the quad's predicate
* @param {string} object the quad's object
* @param {(string|string[])} [contexts] the quad's context
* @return {Quad[]} a collection of quads constructed from the provided params
*/
function getQuads(subject, predicate, object, contexts) {
var objectTerm = TermConverter.toObject(object);
return TermConverter.toQuads(subject, predicate, objectTerm, contexts);
}
/**
* Convert the supplied params to a collection of quads.
*
* The quads object term will be a literal with a data type or a language.
*
* The produced quads size depends on the supplied amount of context.
*
* @public
* @static
* @param {string} subject the quad's subject
* @param {string} predicate the quad's predicate
* @param {string} object the quad's object
* @param {(string|string[])} [contexts] the quad's context
* @param {string} type the quad's data type
* @param {string} language the quad's literal language
* @return {Quad[]} a collection of quads constructed from the provided params
*/
}, {
key: "getLiteralQuads",
value: function getLiteralQuads(subject, predicate, object, contexts, type, language) {
var objectTerm;
if (language) {
objectTerm = TermConverter.toObjectWithLanguage(object, language);
} else {
objectTerm = TermConverter.toObjectWithDataType(object, type);
}
return TermConverter.toQuads(subject, predicate, objectTerm, contexts);
}
/**
* Convert the supplied params to terms and then to a collection of quads.
* The supplied object should already be converted to a term.
*
* The produced quads size depends on the supplied amount of context.
*
* @private
* @static
* @param {string} subject the quad's subject
* @param {string} predicate the quad's predicate
* @param {Term} objectTerm the quads object already converted to a Term
* @param {(string|string[])} contexts the quad's context
* @return {Quad[]} collection of quads constructed from the provided params
*/
}, {
key: "toQuads",
value: function toQuads(subject, predicate, objectTerm, contexts) {
var subjectTerm = TermConverter.toSubject(subject);
var predicateTerm = TermConverter.toPredicate(predicate);
var contextTerms = TermConverter.toGraphs(contexts);
if (contextTerms && contextTerms.length) {
return contextTerms.map(function (graph) {
return quad(subjectTerm, predicateTerm, objectTerm, graph);
});
}
return [quad(subjectTerm, predicateTerm, objectTerm)];
}
/**
* Serializes the provided collection of quads to Turtle format or Trig in
* case any of the quads have context.
*
* @public
* @static
* @param {Quad[]} quads the collection of quads to serialize to Turtle
* @return {string} a promise that will be resolved to Turtle or Trig
* text or rejected if the quads cannot be serialized
*/
}, {
key: "toString",
value: function toString(quads) {
var writer = TermConverter.getWriter();
writer.addQuads(quads);
var converted = '';
writer.end(function (error, result) {
if (error) {
throw new Error(error);
} else {
converted = result.trim();
}
});
return converted;
}
/**
* Converts the provided value to N-Triple encoded value in case it is not
* already one or a literal value.
*
* For example:
* <ul>
* <li><i>http://resource</i> encodes to <i><http://resource></i></li>
* <li><i>"Literal title"@en</i> will not be encoded</li>
* <li><i><http://resource></i> encodes to the same value</li>
* </ul>
*
* Empty or null values are ignored.
*
* @public
* @static
* @param {string} value the value for converting
* @return {string} the converted value to N-Triple
*/
}, {
key: "toNTripleValue",
value: function toNTripleValue(value) {
if (StringUtils.isNotBlank(value)) {
if (value.startsWith('"')) {
// Do not convert literals
return value;
}
if (value.startsWith('<')) {
// Value is probably already encoded as N-Triple
return value;
}
return "<".concat(value, ">");
}
}
/**
* Converts the provided values to N-Triple encoded values in case they are
* not already one or literal values.
*
* Empty or null values are ignored.
*
* @see {@link #toNTripleValue}
* @public
* @static
* @param {string|string[]} values the values for converting
* @return {string|string[]} the converted value or values to N-Triple
*/
}, {
key: "toNTripleValues",
value: function toNTripleValues(values) {
if (values instanceof Array) {
return values.filter(function (value) {
return StringUtils.isNotBlank(value);
}).map(function (value) {
return TermConverter.toNTripleValue(value);
});
}
return TermConverter.toNTripleValue(values);
}
/**
* Converts the provided subject string to a specific Term based on the value.
*
* @private
* @param {string} value the subject to convert
* @return {BlankNode|Variable|NamedNode} the provided subject as Term
*/
}, {
key: "toSubject",
value: function toSubject(value) {
return TermConverter.toTerm(value);
}
/**
* Converts the provided predicate string to a specific Term based on the
* value.
*
* @private
* @param {string} value the predicate to convert
* @return {Variable|NamedNode} the provided predicate as Term
*/
}, {
key: "toPredicate",
value: function toPredicate(value) {
if (TermConverter.isVariable(value)) {
return TermConverter.toVariable(value);
}
return namedNode(value);
}
/**
* Converts the provided object string to a specific Term based on the value.
*
* This is not handling literal strings. For that use
* {@link TermConverter#toObjectWithLanguage} or
* {@link TermConverter#toObjectWithDataType}
*
* @private
* @param {string} value the object to convert
* @return {BlankNode|Variable|NamedNode} the provided object as Term
*/
}, {
key: "toObject",
value: function toObject(value) {
// Same as subject (when it is not literal)
return TermConverter.toSubject(value);
}
/**
* Converts the provided object and language to a Literal term.
*
* @private
* @param {string} object the value to convert
* @param {string} language the object's language
* @return {Literal} the provided object as Literal
*/
}, {
key: "toObjectWithLanguage",
value: function toObjectWithLanguage(object, language) {
return literal(object, language);
}
/**
* Converts the provided object and data type to a Literal term.
*
* @private
* @param {string} object the value to convert
* @param {string} dataType the object's type
* @return {Literal} the provided object as Literal
*/
}, {
key: "toObjectWithDataType",
value: function toObjectWithDataType(object, dataType) {
return literal(object, namedNode(dataType));
}
/**
* Converts the provided context to a collection of Term.
*
* The produced terms size depends on the supplied amount of context.
*
* @private
* @param {string|string[]} [contexts] the contexts to convert
* @return {Term[]} the provided contexts as Terms
*/
}, {
key: "toGraphs",
value: function toGraphs(contexts) {
if (!contexts || contexts.length && contexts.length < 1) {
return [];
}
// Convert to array
if (!(contexts instanceof Array)) {
contexts = [contexts];
}
// Convert to terms
return contexts.map(function (context) {
return TermConverter.toTerm(context);
});
}
/**
* Converts the provided string to a specific Term based on the value.
*
* <ul>
* <li>If the string begins with <code>_:</code> it will be converted to a
* blank node term.</li>
* <li>If the string begins with <code>?</code> it will be converted to a
* variable term.</li>
* <li>Otherwise it will be converted a simple named node term.</li>
* </ul>
*
* @private
* @param {string} value the string to convert
* @return {BlankNode|Variable|NamedNode} the provided value as Term
*/
}, {
key: "toTerm",
value: function toTerm(value) {
if (TermConverter.isBlankNode(value)) {
// Trim leading _:
return blankNode(value.substring(2));
}
if (TermConverter.isVariable(value)) {
return TermConverter.toVariable(value);
}
return namedNode(value);
}
/**
* Returns a variable term from the provided value without leading ?
*
* @private
* @param {string} value the value to convert to variable
* @return {Variable} the produced variable
*/
}, {
key: "toVariable",
value: function toVariable(value) {
// Trim leading ?
return variable(value.substring(1));
}
/**
* Checks if the provided value is a blank node.
*
* Blank nodes are such values that start with <code>_:</code> prefix
*
* @private
* @param {string} value the value to check
* @return {boolean} <code>true</code> if the value is a blank node
* or <code>false</code> otherwise
*/
}, {
key: "isBlankNode",
value: function isBlankNode(value) {
return value.startsWith('_:');
}
/**
* Checks if the provided value is a variable.
*
* Variables are such values that start with <code>?</code> prefix
*
* @private
* @param {string} value the value to check
* @return {boolean} <code>true</code> if the value is a variable
* or <code>false</code> otherwise
*/
}, {
key: "isVariable",
value: function isVariable(value) {
return value.startsWith('?');
}
/**
* Instantiates new N3 writer for quads.
*
* This writer is not reusable, after invoking <code>end()</code> it won't
* allow further quads insertions.
*
* @private
* @return {N3.Writer} new writer for quads
*/
}, {
key: "getWriter",
value: function getWriter() {
return new N3.Writer();
}
/**
* Decodes from Base64 encoded RDFStar triple.
*
* @param {string} encodedTriple to be decoded from base64 url string
* @return {string} decoded RDFStar triple, returns unchanged if the provided
* triple is not in the expected format
*/
}, {
key: "fromBase64RdfStarTriple",
value: function fromBase64RdfStarTriple(encodedTriple) {
if (encodedTriple.startsWith(ENCODED_RDFSTAR_TRIPLE_PREFIX)) {
return base64url.decode(encodedTriple.slice(ENCODED_RDFSTAR_TRIPLE_PREFIX.length));
}
return encodedTriple;
}
/**
* Encodes RDFStarTriple to Base64 string.
*
* @param {string} triple to be encoded as base64 url string
* @return {string} encoded RDFStart triple, returns unchanged if the provided
* triple is not in the expected format
*/
}, {
key: "toBase64RdfStarTriple",
value: function toBase64RdfStarTriple(triple) {
if (triple.startsWith('<<') && triple.endsWith('>>')) {
return ENCODED_RDFSTAR_TRIPLE_PREFIX + base64url.encode(triple);
}
return triple;
}
}]);
}();
module.exports = TermConverter;