UNPKG

semantic-analysis

Version:

Extensible semantic Structured Data analysis library for Microdata and JSON-LD

275 lines 9.64 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JsonExtractor = void 0; var tslib_1 = require("tslib"); require("../../util"); var spec_1 = require("../item/spec"); var util_1 = require("../../util"); /** * Simplified JSON-LD extractor based on Google structured data examples * @see https://developers.google.com/search/docs/guides/intro-structured-data */ var JsonExtractor = /** @class */ (function () { /* Initialization */ function JsonExtractor(doc) { this.doc = doc; this.meta = { type: 'JSON-LD', extractor: this, document: doc, }; } /* Extractor */ JsonExtractor.prototype.extract = function () { console.groupCollapsed('JSON-LD extraction'); console.debug('Initializing...'); var result = this.findItems(); console.groupEnd(); return result; }; JsonExtractor.prototype.findItems = function () { var _this = this; var result = { items: [], logs: [], document: this.doc }; var scripts = this.doc.document.querySelectorAll('script[type="application/ld+json"]'); var _loop_1 = function (script) { var json = void 0; try { json = JSON.parse(script.innerHTML); } catch (e) { var message = 'Contents could not be parsed as JSON'; console.debug(message); result.logs.push({ message: message, sort: 'Error', phase: 'Parsing', element: script, }); return "continue"; } if (typeof json !== 'object' || json === null) { var message = "Invalid type " + (json !== null ? typeof json : 'null') + ", expected non-null object or array"; console.debug(message); result.logs.push({ message: message, sort: 'Error', phase: 'Extraction', element: script, }); return "continue"; } (Array.isArray(json) ? json : [json]) .filter(function (o) { if (typeof o === 'object' && o !== null) { return true; } else { var message = "Skipping " + (o !== null ? typeof o : 'null') + ", expected non-null object"; console.debug(message); result.logs.push({ message: message, sort: 'Warning', phase: 'Extraction', element: script, }); return false; } }) .forEach(function (o) { console.debug('Building item from: ', o); result.items.push(new JsonItem(o, tslib_1.__assign(tslib_1.__assign({}, _this.meta), { element: script, logs: [] }))); }); }; for (var _i = 0, _a = Array.from(scripts); _i < _a.length; _i++) { var script = _a[_i]; _loop_1(script); } console.debug('Extractions finished'); return result; }; ; return JsonExtractor; }()); exports.JsonExtractor = JsonExtractor; // TODO Move classes into a separate package /** * Local implementation of an item */ var JsonItem = /** @class */ (function () { /* Initialization */ function JsonItem(json, meta) { this.builder = new JsonItemBuilder(json, meta); } Object.defineProperty(JsonItem.prototype, "item", { get: function () { if (!this._item) { this._item = this.builder.build(); } return this._item; }, enumerable: false, configurable: true }); ; Object.defineProperty(JsonItem.prototype, "type", { /* Extraction Item */ get: function () { return this.item.type; }, enumerable: false, configurable: true }); Object.defineProperty(JsonItem.prototype, "id", { get: function () { return this.item.id; }, enumerable: false, configurable: true }); Object.defineProperty(JsonItem.prototype, "properties", { get: function () { return this.item.properties; }, enumerable: false, configurable: true }); Object.defineProperty(JsonItem.prototype, "meta", { get: function () { return this.item.meta; }, enumerable: false, configurable: true }); Object.defineProperty(JsonItem.prototype, "propMeta", { get: function () { return this.item.propMeta; }, enumerable: false, configurable: true }); return JsonItem; }()); var JsonItemBuilder = /** @class */ (function () { /* Initialization */ function JsonItemBuilder(json, meta, context) { var _this = this; this.json = json; this.meta = meta; /* Build */ this.build = function () { return ({ type: _this.type, id: _this.id, get properties() { return unwrapProperties(this.propMeta); }, meta: tslib_1.__assign(tslib_1.__assign({}, _this.meta), { logs: [] }), propMeta: util_1.map(_this.propMeta, function (props) { return props.map(function (prop) { return (tslib_1.__assign(tslib_1.__assign({}, prop), { value: prop.value instanceof JsonItemBuilder ? prop.value.build() : prop.value })); }); }), }); }; /* Helpers */ this.parseType = function () { var type = _this.json['@type']; if (!type) { return []; } if (Array.isArray(type)) { return type.map(function (t) { return String(t); }); } else { return [String(type)]; } }; this.applyContext = function (type) { return type.map(function (t) { return spec_1.combine(t, _this.context); }); }; this.findProperties = function () { var properties = {}; util_1.map(util_1.filter(_this.json, (function (value, key) { return !String(key).startsWith('@'); })), function (val, name) { var completeName = spec_1.combine(String(name), _this.context); var values = (Array.isArray(val) ? val : [val]) .filter(function (value) { return value !== null && String(value).trim() !== ''; }) .map(function (value) { return ({ name: completeName, value: typeof value === 'object' ? new JsonItemBuilder(value, _this.meta, _this.context) : String(value).trim(), meta: tslib_1.__assign(tslib_1.__assign({}, _this.meta), { logs: [] }), }); }); properties[completeName] = values; return values; }); return properties; }; if (context) { this.context = context; } else { var c = json['@context']; if (typeof c === 'string') { try { this.context = new URL(c).toString(); } catch (e) { var message = 'Given context is not a valid URL, ignoring'; console.debug(message); meta.logs.push({ message: message, sort: 'Error', element: meta.element, phase: 'Extraction', }); } } else if (c !== undefined) { var message = 'The app cannot inspect non-string contexts yet'; console.error(message); meta.logs.push({ message: message, sort: 'Notice', element: meta.element, phase: 'Extraction', }); } } } Object.defineProperty(JsonItemBuilder.prototype, "type", { /* Item */ get: function () { return this.applyContext(this.parseType()); }, enumerable: false, configurable: true }); Object.defineProperty(JsonItemBuilder.prototype, "id", { get: function () { return typeof this.json['@id'] === 'string' ? this.json['@id'] : undefined; }, enumerable: false, configurable: true }); Object.defineProperty(JsonItemBuilder.prototype, "properties", { get: function () { return unwrapProperties(this.propMeta); }, enumerable: false, configurable: true }); Object.defineProperty(JsonItemBuilder.prototype, "propMeta", { get: function () { return this.findProperties(); }, enumerable: false, configurable: true }); return JsonItemBuilder; }()); var unwrapProperties = function (propMeta) { return util_1.map(propMeta, function (props) { return props.map(function (prop) { return prop.value; }); }); }; //# sourceMappingURL=JsonExtractor.js.map