lincd-jsonld
Version:
Utilities to parse and write JSON-LD for the LINCD library
405 lines • 18.4 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.JSONWriter = exports.URIMappings = void 0;
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
const models_1 = require("lincd/models");
const QuadSet_1 = require("lincd/collections/QuadSet");
const NodeSet_1 = require("lincd/collections/NodeSet");
const ShapeSet_1 = require("lincd/collections/ShapeSet");
const Shape_1 = require("lincd/shapes/Shape");
const CoreMap_1 = require("lincd/collections/CoreMap");
const CoreSet_1 = require("lincd/collections/CoreSet");
const JSONLDWriter_js_1 = require("./JSONLDWriter.js");
const package_js_1 = require("../package.js");
const QuadArray_1 = require("lincd/collections/QuadArray");
const N3_js_1 = require("./N3.js");
const rdf_1 = require("lincd/ontologies/rdf");
const shacl_1 = require("lincd/ontologies/shacl");
let URIMappings = class URIMappings {
constructor(map = []) {
this.map = map;
}
addMapping(mapping) {
this.map.push(mapping);
}
};
exports.URIMappings = URIMappings;
exports.URIMappings = URIMappings = __decorate([
package_js_1.linkedUtil,
__metadata("design:paramtypes", [Array])
], URIMappings);
let JSONWriter = class JSONWriter {
static toJsObject(object, includeData = true, includeGraphs = true, includeLocalResources = true, uriMappings = new URIMappings(), includeIncomingProperties = false) {
var data;
if (includeData === true) {
data = new QuadSet_1.QuadSet();
}
else if (includeData instanceof QuadSet_1.QuadSet) {
data = includeData;
}
return this.toJsObjectInternal(object, data, includeIncomingProperties, includeGraphs).then((jsObject) => {
if (data && data.size) {
if (!includeLocalResources) {
data = data.filter((quad) => !quad.subject.isTemporaryNode &&
!(quad.object instanceof models_1.NamedNode && quad.object.isTemporaryNode));
}
return N3_js_1.N3.fromQuads(data).then((n3Data) => {
let res = {
__n: jsObject,
__data: n3Data,
};
if (uriMappings) {
res['__map'] = JSON.stringify(uriMappings.map);
}
return res;
});
// return JSONLDWriter.fromQuads(data, true, includeGraphs).then(
// (jsonldData) => {
// let res = {
// __n: jsObject,
// __data: jsonldData,
// };
// if (uriMappings) {
// res['__map'] = JSON.stringify(uriMappings.map);
// }
// return res;
// },
// );
}
return jsObject;
});
}
/**
* Convert any object into a json string. The object can be or include framework native objects like NamedNodes, Instances, Maps and Sets
* The resulting string is meant to be consumed by the JSONParser class
* WARNING: when object is a quadset that contain removed quads will not convert well. Use convertQuadSetNatively for this
* @param object
* @param includeData - data of properties of resources and instances in the object will be included in the resulting string
* @param includeLocalResources - if false, temporary local resources not yet stored in the graph will not be included
* @param mappings
* @param includeIncomingProperties - if true, data of incoming properties of resources and instances will also be included
*/
static stringify(object, includeData = false, includeGraphs = true, includeLocalResources = true, mappings = null, includeIncomingProperties = false) {
return this.toJsObject(object, includeData, includeGraphs, includeLocalResources, mappings, includeIncomingProperties)
.then((jsObject) => {
return JSON.stringify(jsObject);
})
.catch((e) => {
throw new Error('Could not convert object to JSON:' + e.stack);
});
}
/**
* A fast performing native implementation to convert a QuadSet to a plain js object,
* which MAINTAINS extra information about the quad, like whether its removed or not
* (which is not the case if it would be converted to jsonld)
* The result is ready to be stringified by JSON
* Use this for example if you want to send quad CHANGES across environments, which will include both removed and non-removed quads
* @param quadset
* @private
*/
static convertQuadSetToData(quadset) {
var entries = quadset.map((quad) => this.convertQuadToData(quad));
return {
__type: 'qd', //quad data
entries,
};
}
static toJsObjectInternal(object, dataQuads, includeIncomingProperties = false, includeGraphs = true) {
if (typeof object === 'string' ||
typeof object === 'number' ||
typeof object === 'boolean') {
return Promise.resolve(object);
}
else if (object instanceof Date) {
return this.convertDate(object);
}
else if (object instanceof models_1.Graph) {
return this.convertGraph(object, dataQuads, includeIncomingProperties);
}
else if (object instanceof models_1.BlankNode) {
return this.convertBlankNode(object, dataQuads);
}
else if (object instanceof models_1.NamedNode) {
return this.convertNamedNode(object, dataQuads, includeIncomingProperties);
}
else if (object instanceof models_1.Literal) {
return this.convertLiteral(object, dataQuads);
}
else if (object instanceof QuadSet_1.QuadSet) {
return this.convertQuads(object, includeGraphs);
}
else if (object instanceof QuadArray_1.QuadArray) {
return this.convertQuads(object, includeGraphs, 'qa');
}
else if (object instanceof Shape_1.Shape) {
return this.convertShape(object, dataQuads, includeIncomingProperties);
}
else if (object instanceof models_1.Quad) {
return this.convertQuad(object, dataQuads, includeGraphs);
}
else if (object instanceof NodeSet_1.NodeSet) {
return this.convertNodeSet(object, dataQuads, includeIncomingProperties, includeGraphs);
}
else if (object instanceof ShapeSet_1.ShapeSet) {
return this.convertShapeSet(object, dataQuads, includeIncomingProperties, includeGraphs);
}
else if (object instanceof CoreSet_1.CoreSet) {
return this.convertCoreSet(object, dataQuads, 'cs', includeIncomingProperties, includeGraphs);
}
else if (object instanceof CoreMap_1.CoreMap) {
return this.convertCoreMap(object, dataQuads, 'cm', includeIncomingProperties, includeGraphs);
}
else if ((object === null || object === void 0 ? void 0 : object.prototype) instanceof Shape_1.Shape || object === Shape_1.Shape) {
return this.convertShapeClass(object);
}
else if (object instanceof URIMappings) {
return this.convertURIMappings(object);
}
else if (object instanceof CoreMap_1.CoreMap) {
throw new Error('JSON conversion to be implemented');
}
else if ((object instanceof Object && object !== null) ||
object instanceof Array) {
var valuePromises = [];
//clone the object so that we don't overwrite the original
object = Array.isArray(object) ? [...object] : Object.assign({}, object);
var setValue = (k, v) => {
object[k] = v;
};
for (var key in object) {
valuePromises.push(this.toJsObjectInternal(object[key], dataQuads, includeIncomingProperties, includeGraphs).then(setValue.bind(this, key)));
}
return Promise.all(valuePromises).then((valueObjects) => {
return this.convertNativeObject(object);
});
}
else if (typeof object === 'undefined' || object === null) {
return Promise.resolve(object);
}
else {
throw new Error('Unknown type. Trying to convert this to a JS object ' +
typeof object +
' - ' +
object.toString());
}
}
static convertNativeObject(object) {
return Promise.resolve(object);
}
static convertNamedNode(uriResource, dataQuads, includeIncomingProperties = false) {
var res = {
__u: uriResource.uri,
};
if (dataQuads) {
//dont send data about shapes
//TODO: ideally server calls start indicating if the data of the node/args needs to be sent
if (uriResource.has(rdf_1.rdf.type, shacl_1.shacl.NodeShape) ||
uriResource.has(rdf_1.rdf.type, shacl_1.shacl.PropertyShape)) {
return Promise.resolve(res);
}
return this.collectData(uriResource.getAllQuads(includeIncomingProperties), dataQuads).then(() => res);
}
return Promise.resolve(res);
}
static convertBlankNode(uriResource, dataQuads, includeIncomingProperties = true) {
var res = {
__b: uriResource.uri,
};
if (dataQuads) {
return this.collectData(uriResource.getAllQuads(includeIncomingProperties), dataQuads).then(() => res);
}
return Promise.resolve(res);
}
static convertLiteral(literal, dataQuads) {
return Promise.resolve({
__l: literal.toString(),
});
}
static convertDate(date) {
return __awaiter(this, void 0, void 0, function* () {
if (!date)
return Promise.resolve({ __dt: null });
return Promise.resolve({
__dt: date.toISOString(),
});
});
}
static convertGraph(graph_1, dataQuads_1) {
return __awaiter(this, arguments, void 0, function* (graph, dataQuads, includeIncomingProperties = false) {
var res = {
__g: graph.node.uri,
};
if (dataQuads) {
return Promise.all([
this.collectData(graph.node.getAllQuads(includeIncomingProperties), dataQuads),
JSONLDWriter_js_1.JSONLDWriter.fromQuads(graph.getContents()),
]).then(([, jsonldData]) => {
res['content'] = jsonldData;
return res;
});
// return this.collectData(graph.getContents(),dataQuads).then(() => res);
// this.addQuads(graph.getContents(), quads);
}
return Promise.resolve(res);
});
}
static convertCoreSet(coreset, dataQuads, type = 'cs', includeIncomingProperties = false, includeGraphs = true) {
var entryPromises = [];
coreset.forEach((item) => {
entryPromises.push(this.toJsObjectInternal(item, dataQuads, includeIncomingProperties, includeGraphs));
});
return Promise.all(entryPromises)
.then((results) => {
return {
__type: type,
entries: results,
};
})
.catch((err) => {
console.warn('Error during converting CoreSet ' + coreset.toString());
console.warn(err.stack);
// this.convertCoreSet(coreset,dataQuads,type,includeIncomingProperties);
return null;
});
}
static convertShapeSet(coreset, dataQuads, includeIncomingProperties = false, includeGraphs = true) {
// throw new Error('Converting ShapeSets to JSON is not yet supported');
// return Promise.reject();
return this.convertCoreSet(coreset, dataQuads, 'ss', includeIncomingProperties, includeGraphs);
}
static convertURIMappings(mappings) {
return Promise.resolve({
__urimap: mappings.map,
});
}
static convertCoreMap(coremap, dataQuads, type = 'cm', includeIncomingProperties = false, includeGraphs = true) {
var entryPromises = [];
coremap.forEach((item, key) => {
entryPromises.push(this.toJsObjectInternal([key, item], dataQuads, includeIncomingProperties, includeGraphs));
});
return Promise.all(entryPromises)
.then((results) => {
return {
__type: type,
entries: results,
};
})
.catch((err) => {
console.warn('Error during converting CoreMap');
console.warn(err.stack);
return null;
});
}
static convertNodeSet(set, dataQuads, includeIncomingProperties = false, includeGraphs = false) {
return this.convertCoreSet(set, dataQuads, 'ns', includeIncomingProperties, includeGraphs);
}
static convertQuads(quads, includeGraphs = true, type = 'qs') {
// if (quads.some((q) => q.isRemoved)) {
// console.warn(
// 'WARNING: Converting quads to JSON that contain removed quads. You should likely filter these out first. If you want to send information about removed quads, use JSONWriter.convertQuadSetToData instead',
// );
// }
//The JSON writer here depends on the JSONLD writer to convert quads into jsonld
return JSONLDWriter_js_1.JSONLDWriter.fromQuads(quads, true, includeGraphs).then((jsonld) => {
let result = {};
result['__' + type] = jsonld;
return result;
});
}
static convertQuadToData(quad, includeGraphs = true) {
return [
quad.subject.uri,
quad.predicate.uri,
quad.object.toString(),
includeGraphs ? quad.graph.node.toString() : null,
quad.isRemoved,
];
}
static convertQuad(quad_1, dataQuads_1) {
return __awaiter(this, arguments, void 0, function* (quad, dataQuads, includeGraphs = true) {
var res = {
__t: this.convertQuadToData(quad, includeGraphs),
};
if (dataQuads) {
return this.collectData([quad], dataQuads).then(() => res);
}
return Promise.resolve(res);
});
}
static convertShape(shape_1, dataQuads_1) {
return __awaiter(this, arguments, void 0, function* (shape, dataQuads, includeIncomingProperties = false) {
if (!shape.nodeShape) {
console.warn('This shape is not linked and hence cannot be converted to JSON: ' +
shape.toString());
}
var res = {
__s: shape.nodeShape.namedNode.uri,
u: shape.namedNode.uri,
};
if (dataQuads) {
if (dataQuads) {
return this.collectData(shape.getDataQuads(includeIncomingProperties), dataQuads).then(() => res);
}
}
return Promise.resolve(res);
});
}
static convertShapeClass(shapeClass) {
return __awaiter(this, void 0, void 0, function* () {
if (!shapeClass.shape) {
console.warn('This shape class is not linked and hence cannot be converted to JSON: ' +
shapeClass.name);
}
var res = {
__sc: shapeClass.shape.namedNode.uri,
};
return Promise.resolve(res);
});
}
static collectData(quadsToAdd, dataQuads) {
var promises = [];
quadsToAdd === null || quadsToAdd === void 0 ? void 0 : quadsToAdd.forEach((quad) => {
//we allow implementers of getDataQuads send null in between other quads, so we need to check for that
if (!quad)
return;
if (!dataQuads.has(quad)) {
dataQuads.add(quad);
if (quad.object instanceof models_1.BlankNode) {
this.collectData(quad.object.getAllQuads(), dataQuads);
}
else if (quad.object instanceof models_1.NamedNode &&
quad.object.isTemporaryNode) {
this.collectData(quad.object.getAllQuads(), dataQuads);
}
}
});
return Promise.all(promises);
}
};
exports.JSONWriter = JSONWriter;
exports.JSONWriter = JSONWriter = __decorate([
package_js_1.linkedUtil
], JSONWriter);
//# sourceMappingURL=JSONWriter.js.map