UNPKG

lincd-jsonld

Version:

Utilities to parse and write JSON-LD for the LINCD library

405 lines 18.4 kB
"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