WIP
This commit is contained in:
399
node_modules/n3/lib/N3DataFactory.js
generated
vendored
Normal file
399
node_modules/n3/lib/N3DataFactory.js
generated
vendored
Normal file
@@ -0,0 +1,399 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = exports.Variable = exports.Triple = exports.Term = exports.Quad = exports.NamedNode = exports.Literal = exports.DefaultGraph = exports.BlankNode = void 0;
|
||||
exports.escapeQuotes = escapeQuotes;
|
||||
exports.fromQuad = fromQuad;
|
||||
exports.fromTerm = fromTerm;
|
||||
exports.termFromId = termFromId;
|
||||
exports.termToId = termToId;
|
||||
exports.unescapeQuotes = unescapeQuotes;
|
||||
var _IRIs = _interopRequireDefault(require("./IRIs"));
|
||||
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
||||
// N3.js implementations of the RDF/JS core data types
|
||||
// See http://rdf.js.org/data-model-spec/
|
||||
|
||||
const {
|
||||
rdf,
|
||||
xsd
|
||||
} = _IRIs.default;
|
||||
|
||||
// eslint-disable-next-line prefer-const
|
||||
let DEFAULTGRAPH;
|
||||
let _blankNodeCounter = 0;
|
||||
const escapedLiteral = /^"(.*".*)(?="[^"]*$)/;
|
||||
|
||||
// ## DataFactory singleton
|
||||
const DataFactory = {
|
||||
namedNode,
|
||||
blankNode,
|
||||
variable,
|
||||
literal,
|
||||
defaultGraph,
|
||||
quad,
|
||||
triple: quad,
|
||||
fromTerm,
|
||||
fromQuad
|
||||
};
|
||||
var _default = exports.default = DataFactory; // ## Term constructor
|
||||
class Term {
|
||||
constructor(id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
// ### The value of this term
|
||||
get value() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
// ### Returns whether this object represents the same term as the other
|
||||
equals(other) {
|
||||
// If both terms were created by this library,
|
||||
// equality can be computed through ids
|
||||
if (other instanceof Term) return this.id === other.id;
|
||||
// Otherwise, compare term type and value
|
||||
return !!other && this.termType === other.termType && this.value === other.value;
|
||||
}
|
||||
|
||||
// ### Implement hashCode for Immutable.js, since we implement `equals`
|
||||
// https://immutable-js.com/docs/v4.0.0/ValueObject/#hashCode()
|
||||
hashCode() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ### Returns a plain object representation of this term
|
||||
toJSON() {
|
||||
return {
|
||||
termType: this.termType,
|
||||
value: this.value
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ## NamedNode constructor
|
||||
exports.Term = Term;
|
||||
class NamedNode extends Term {
|
||||
// ### The term type of this term
|
||||
get termType() {
|
||||
return 'NamedNode';
|
||||
}
|
||||
}
|
||||
|
||||
// ## Literal constructor
|
||||
exports.NamedNode = NamedNode;
|
||||
class Literal extends Term {
|
||||
// ### The term type of this term
|
||||
get termType() {
|
||||
return 'Literal';
|
||||
}
|
||||
|
||||
// ### The text value of this literal
|
||||
get value() {
|
||||
return this.id.substring(1, this.id.lastIndexOf('"'));
|
||||
}
|
||||
|
||||
// ### The language of this literal
|
||||
get language() {
|
||||
// Find the last quotation mark (e.g., '"abc"@en-us')
|
||||
const id = this.id;
|
||||
let atPos = id.lastIndexOf('"') + 1;
|
||||
// If "@" it follows, return the remaining substring; empty otherwise
|
||||
return atPos < id.length && id[atPos++] === '@' ? id.substr(atPos).toLowerCase() : '';
|
||||
}
|
||||
|
||||
// ### The datatype IRI of this literal
|
||||
get datatype() {
|
||||
return new NamedNode(this.datatypeString);
|
||||
}
|
||||
|
||||
// ### The datatype string of this literal
|
||||
get datatypeString() {
|
||||
// Find the last quotation mark (e.g., '"abc"^^http://ex.org/types#t')
|
||||
const id = this.id,
|
||||
dtPos = id.lastIndexOf('"') + 1;
|
||||
const char = dtPos < id.length ? id[dtPos] : '';
|
||||
// If "^" it follows, return the remaining substring
|
||||
return char === '^' ? id.substr(dtPos + 2) :
|
||||
// If "@" follows, return rdf:langString; xsd:string otherwise
|
||||
char !== '@' ? xsd.string : rdf.langString;
|
||||
}
|
||||
|
||||
// ### Returns whether this object represents the same term as the other
|
||||
equals(other) {
|
||||
// If both literals were created by this library,
|
||||
// equality can be computed through ids
|
||||
if (other instanceof Literal) return this.id === other.id;
|
||||
// Otherwise, compare term type, value, language, and datatype
|
||||
return !!other && !!other.datatype && this.termType === other.termType && this.value === other.value && this.language === other.language && this.datatype.value === other.datatype.value;
|
||||
}
|
||||
toJSON() {
|
||||
return {
|
||||
termType: this.termType,
|
||||
value: this.value,
|
||||
language: this.language,
|
||||
datatype: {
|
||||
termType: 'NamedNode',
|
||||
value: this.datatypeString
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ## BlankNode constructor
|
||||
exports.Literal = Literal;
|
||||
class BlankNode extends Term {
|
||||
constructor(name) {
|
||||
super(`_:${name}`);
|
||||
}
|
||||
|
||||
// ### The term type of this term
|
||||
get termType() {
|
||||
return 'BlankNode';
|
||||
}
|
||||
|
||||
// ### The name of this blank node
|
||||
get value() {
|
||||
return this.id.substr(2);
|
||||
}
|
||||
}
|
||||
exports.BlankNode = BlankNode;
|
||||
class Variable extends Term {
|
||||
constructor(name) {
|
||||
super(`?${name}`);
|
||||
}
|
||||
|
||||
// ### The term type of this term
|
||||
get termType() {
|
||||
return 'Variable';
|
||||
}
|
||||
|
||||
// ### The name of this variable
|
||||
get value() {
|
||||
return this.id.substr(1);
|
||||
}
|
||||
}
|
||||
|
||||
// ## DefaultGraph constructor
|
||||
exports.Variable = Variable;
|
||||
class DefaultGraph extends Term {
|
||||
constructor() {
|
||||
super('');
|
||||
return DEFAULTGRAPH || this;
|
||||
}
|
||||
|
||||
// ### The term type of this term
|
||||
get termType() {
|
||||
return 'DefaultGraph';
|
||||
}
|
||||
|
||||
// ### Returns whether this object represents the same term as the other
|
||||
equals(other) {
|
||||
// If both terms were created by this library,
|
||||
// equality can be computed through strict equality;
|
||||
// otherwise, compare term types.
|
||||
return this === other || !!other && this.termType === other.termType;
|
||||
}
|
||||
}
|
||||
|
||||
// ## DefaultGraph singleton
|
||||
exports.DefaultGraph = DefaultGraph;
|
||||
DEFAULTGRAPH = new DefaultGraph();
|
||||
|
||||
// ### Constructs a term from the given internal string ID
|
||||
// The third 'nested' parameter of this function is to aid
|
||||
// with recursion over nested terms. It should not be used
|
||||
// by consumers of this library.
|
||||
// See https://github.com/rdfjs/N3.js/pull/311#discussion_r1061042725
|
||||
function termFromId(id, factory, nested) {
|
||||
factory = factory || DataFactory;
|
||||
|
||||
// Falsy value or empty string indicate the default graph
|
||||
if (!id) return factory.defaultGraph();
|
||||
|
||||
// Identify the term type based on the first character
|
||||
switch (id[0]) {
|
||||
case '?':
|
||||
return factory.variable(id.substr(1));
|
||||
case '_':
|
||||
return factory.blankNode(id.substr(2));
|
||||
case '"':
|
||||
// Shortcut for internal literals
|
||||
if (factory === DataFactory) return new Literal(id);
|
||||
// Literal without datatype or language
|
||||
if (id[id.length - 1] === '"') return factory.literal(id.substr(1, id.length - 2));
|
||||
// Literal with datatype or language
|
||||
const endPos = id.lastIndexOf('"', id.length - 1);
|
||||
return factory.literal(id.substr(1, endPos - 1), id[endPos + 1] === '@' ? id.substr(endPos + 2) : factory.namedNode(id.substr(endPos + 3)));
|
||||
case '[':
|
||||
id = JSON.parse(id);
|
||||
break;
|
||||
default:
|
||||
if (!nested || !Array.isArray(id)) {
|
||||
return factory.namedNode(id);
|
||||
}
|
||||
}
|
||||
return factory.quad(termFromId(id[0], factory, true), termFromId(id[1], factory, true), termFromId(id[2], factory, true), id[3] && termFromId(id[3], factory, true));
|
||||
}
|
||||
|
||||
// ### Constructs an internal string ID from the given term or ID string
|
||||
// The third 'nested' parameter of this function is to aid
|
||||
// with recursion over nested terms. It should not be used
|
||||
// by consumers of this library.
|
||||
// See https://github.com/rdfjs/N3.js/pull/311#discussion_r1061042725
|
||||
function termToId(term, nested) {
|
||||
if (typeof term === 'string') return term;
|
||||
if (term instanceof Term && term.termType !== 'Quad') return term.id;
|
||||
if (!term) return DEFAULTGRAPH.id;
|
||||
|
||||
// Term instantiated with another library
|
||||
switch (term.termType) {
|
||||
case 'NamedNode':
|
||||
return term.value;
|
||||
case 'BlankNode':
|
||||
return `_:${term.value}`;
|
||||
case 'Variable':
|
||||
return `?${term.value}`;
|
||||
case 'DefaultGraph':
|
||||
return '';
|
||||
case 'Literal':
|
||||
return `"${term.value}"${term.language ? `@${term.language}` : term.datatype && term.datatype.value !== xsd.string ? `^^${term.datatype.value}` : ''}`;
|
||||
case 'Quad':
|
||||
const res = [termToId(term.subject, true), termToId(term.predicate, true), termToId(term.object, true)];
|
||||
if (term.graph && term.graph.termType !== 'DefaultGraph') {
|
||||
res.push(termToId(term.graph, true));
|
||||
}
|
||||
return nested ? res : JSON.stringify(res);
|
||||
default:
|
||||
throw new Error(`Unexpected termType: ${term.termType}`);
|
||||
}
|
||||
}
|
||||
|
||||
// ## Quad constructor
|
||||
class Quad extends Term {
|
||||
constructor(subject, predicate, object, graph) {
|
||||
super('');
|
||||
this._subject = subject;
|
||||
this._predicate = predicate;
|
||||
this._object = object;
|
||||
this._graph = graph || DEFAULTGRAPH;
|
||||
}
|
||||
|
||||
// ### The term type of this term
|
||||
get termType() {
|
||||
return 'Quad';
|
||||
}
|
||||
get subject() {
|
||||
return this._subject;
|
||||
}
|
||||
get predicate() {
|
||||
return this._predicate;
|
||||
}
|
||||
get object() {
|
||||
return this._object;
|
||||
}
|
||||
get graph() {
|
||||
return this._graph;
|
||||
}
|
||||
|
||||
// ### Returns a plain object representation of this quad
|
||||
toJSON() {
|
||||
return {
|
||||
termType: this.termType,
|
||||
subject: this._subject.toJSON(),
|
||||
predicate: this._predicate.toJSON(),
|
||||
object: this._object.toJSON(),
|
||||
graph: this._graph.toJSON()
|
||||
};
|
||||
}
|
||||
|
||||
// ### Returns whether this object represents the same quad as the other
|
||||
equals(other) {
|
||||
return !!other && this._subject.equals(other.subject) && this._predicate.equals(other.predicate) && this._object.equals(other.object) && this._graph.equals(other.graph);
|
||||
}
|
||||
}
|
||||
exports.Triple = exports.Quad = Quad;
|
||||
// ### Escapes the quotes within the given literal
|
||||
function escapeQuotes(id) {
|
||||
return id.replace(escapedLiteral, (_, quoted) => `"${quoted.replace(/"/g, '""')}`);
|
||||
}
|
||||
|
||||
// ### Unescapes the quotes within the given literal
|
||||
function unescapeQuotes(id) {
|
||||
return id.replace(escapedLiteral, (_, quoted) => `"${quoted.replace(/""/g, '"')}`);
|
||||
}
|
||||
|
||||
// ### Creates an IRI
|
||||
function namedNode(iri) {
|
||||
return new NamedNode(iri);
|
||||
}
|
||||
|
||||
// ### Creates a blank node
|
||||
function blankNode(name) {
|
||||
return new BlankNode(name || `n3-${_blankNodeCounter++}`);
|
||||
}
|
||||
|
||||
// ### Creates a literal
|
||||
function literal(value, languageOrDataType) {
|
||||
// Create a language-tagged string
|
||||
if (typeof languageOrDataType === 'string') return new Literal(`"${value}"@${languageOrDataType.toLowerCase()}`);
|
||||
|
||||
// Automatically determine datatype for booleans and numbers
|
||||
let datatype = languageOrDataType ? languageOrDataType.value : '';
|
||||
if (datatype === '') {
|
||||
// Convert a boolean
|
||||
if (typeof value === 'boolean') datatype = xsd.boolean;
|
||||
// Convert an integer or double
|
||||
else if (typeof value === 'number') {
|
||||
if (Number.isFinite(value)) datatype = Number.isInteger(value) ? xsd.integer : xsd.double;else {
|
||||
datatype = xsd.double;
|
||||
if (!Number.isNaN(value)) value = value > 0 ? 'INF' : '-INF';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a datatyped literal
|
||||
return datatype === '' || datatype === xsd.string ? new Literal(`"${value}"`) : new Literal(`"${value}"^^${datatype}`);
|
||||
}
|
||||
|
||||
// ### Creates a variable
|
||||
function variable(name) {
|
||||
return new Variable(name);
|
||||
}
|
||||
|
||||
// ### Returns the default graph
|
||||
function defaultGraph() {
|
||||
return DEFAULTGRAPH;
|
||||
}
|
||||
|
||||
// ### Creates a quad
|
||||
function quad(subject, predicate, object, graph) {
|
||||
return new Quad(subject, predicate, object, graph);
|
||||
}
|
||||
function fromTerm(term) {
|
||||
if (term instanceof Term) return term;
|
||||
|
||||
// Term instantiated with another library
|
||||
switch (term.termType) {
|
||||
case 'NamedNode':
|
||||
return namedNode(term.value);
|
||||
case 'BlankNode':
|
||||
return blankNode(term.value);
|
||||
case 'Variable':
|
||||
return variable(term.value);
|
||||
case 'DefaultGraph':
|
||||
return DEFAULTGRAPH;
|
||||
case 'Literal':
|
||||
return literal(term.value, term.language || term.datatype);
|
||||
case 'Quad':
|
||||
return fromQuad(term);
|
||||
default:
|
||||
throw new Error(`Unexpected termType: ${term.termType}`);
|
||||
}
|
||||
}
|
||||
function fromQuad(inQuad) {
|
||||
if (inQuad instanceof Quad) return inQuad;
|
||||
if (inQuad.termType !== 'Quad') throw new Error(`Unexpected termType: ${inQuad.termType}`);
|
||||
return quad(fromTerm(inQuad.subject), fromTerm(inQuad.predicate), fromTerm(inQuad.object), fromTerm(inQuad.graph));
|
||||
}
|
||||
Reference in New Issue
Block a user