"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parseFeed = exports.FeedHandler = void 0; var domhandler_1 = __importDefault(require("domhandler")); var DomUtils = __importStar(require("domutils")); var Parser_1 = require("./Parser"); var FeedItemMediaMedium; (function (FeedItemMediaMedium) { FeedItemMediaMedium[FeedItemMediaMedium["image"] = 0] = "image"; FeedItemMediaMedium[FeedItemMediaMedium["audio"] = 1] = "audio"; FeedItemMediaMedium[FeedItemMediaMedium["video"] = 2] = "video"; FeedItemMediaMedium[FeedItemMediaMedium["document"] = 3] = "document"; FeedItemMediaMedium[FeedItemMediaMedium["executable"] = 4] = "executable"; })(FeedItemMediaMedium || (FeedItemMediaMedium = {})); var FeedItemMediaExpression; (function (FeedItemMediaExpression) { FeedItemMediaExpression[FeedItemMediaExpression["sample"] = 0] = "sample"; FeedItemMediaExpression[FeedItemMediaExpression["full"] = 1] = "full"; FeedItemMediaExpression[FeedItemMediaExpression["nonstop"] = 2] = "nonstop"; })(FeedItemMediaExpression || (FeedItemMediaExpression = {})); // TODO: Consume data as it is coming in var FeedHandler = /** @class */ (function (_super) { __extends(FeedHandler, _super); /** * * @param callback * @param options */ function FeedHandler(callback, options) { var _this = this; if (typeof callback === "object") { callback = undefined; options = callback; } _this = _super.call(this, callback, options) || this; return _this; } FeedHandler.prototype.onend = function () { var _a, _b; var feedRoot = getOneElement(isValidFeed, this.dom); if (!feedRoot) { this.handleCallback(new Error("couldn't find root of feed")); return; } var feed = {}; if (feedRoot.name === "feed") { var childs = feedRoot.children; feed.type = "atom"; addConditionally(feed, "id", "id", childs); addConditionally(feed, "title", "title", childs); var href = getAttribute("href", getOneElement("link", childs)); if (href) { feed.link = href; } addConditionally(feed, "description", "subtitle", childs); var updated = fetch("updated", childs); if (updated) { feed.updated = new Date(updated); } addConditionally(feed, "author", "email", childs, true); feed.items = getElements("entry", childs).map(function (item) { var entry = {}; var children = item.children; addConditionally(entry, "id", "id", children); addConditionally(entry, "title", "title", children); var href = getAttribute("href", getOneElement("link", children)); if (href) { entry.link = href; } var description = fetch("summary", children) || fetch("content", children); if (description) { entry.description = description; } var pubDate = fetch("updated", children); if (pubDate) { entry.pubDate = new Date(pubDate); } entry.media = getMediaElements(children); return entry; }); } else { var childs = (_b = (_a = getOneElement("channel", feedRoot.children)) === null || _a === void 0 ? void 0 : _a.children) !== null && _b !== void 0 ? _b : []; feed.type = feedRoot.name.substr(0, 3); feed.id = ""; addConditionally(feed, "title", "title", childs); addConditionally(feed, "link", "link", childs); addConditionally(feed, "description", "description", childs); var updated = fetch("lastBuildDate", childs); if (updated) { feed.updated = new Date(updated); } addConditionally(feed, "author", "managingEditor", childs, true); feed.items = getElements("item", feedRoot.children).map(function (item) { var entry = {}; var children = item.children; addConditionally(entry, "id", "guid", children); addConditionally(entry, "title", "title", children); addConditionally(entry, "link", "link", children); addConditionally(entry, "description", "description", children); var pubDate = fetch("pubDate", children); if (pubDate) entry.pubDate = new Date(pubDate); entry.media = getMediaElements(children); return entry; }); } this.feed = feed; this.handleCallback(null); }; return FeedHandler; }(domhandler_1.default)); exports.FeedHandler = FeedHandler; function getMediaElements(where) { return getElements("media:content", where).map(function (elem) { var media = { medium: elem.attribs.medium, isDefault: !!elem.attribs.isDefault, }; if (elem.attribs.url) { media.url = elem.attribs.url; } if (elem.attribs.fileSize) { media.fileSize = parseInt(elem.attribs.fileSize, 10); } if (elem.attribs.type) { media.type = elem.attribs.type; } if (elem.attribs.expression) { media.expression = elem.attribs .expression; } if (elem.attribs.bitrate) { media.bitrate = parseInt(elem.attribs.bitrate, 10); } if (elem.attribs.framerate) { media.framerate = parseInt(elem.attribs.framerate, 10); } if (elem.attribs.samplingrate) { media.samplingrate = parseInt(elem.attribs.samplingrate, 10); } if (elem.attribs.channels) { media.channels = parseInt(elem.attribs.channels, 10); } if (elem.attribs.duration) { media.duration = parseInt(elem.attribs.duration, 10); } if (elem.attribs.height) { media.height = parseInt(elem.attribs.height, 10); } if (elem.attribs.width) { media.width = parseInt(elem.attribs.width, 10); } if (elem.attribs.lang) { media.lang = elem.attribs.lang; } return media; }); } function getElements(tagName, where) { return DomUtils.getElementsByTagName(tagName, where, true); } function getOneElement(tagName, node) { return DomUtils.getElementsByTagName(tagName, node, true, 1)[0]; } function fetch(tagName, where, recurse) { if (recurse === void 0) { recurse = false; } return DomUtils.getText(DomUtils.getElementsByTagName(tagName, where, recurse, 1)).trim(); } function getAttribute(name, elem) { if (!elem) { return null; } var attribs = elem.attribs; return attribs[name]; } function addConditionally(obj, prop, what, where, recurse) { if (recurse === void 0) { recurse = false; } var tmp = fetch(what, where, recurse); if (tmp) obj[prop] = tmp; } function isValidFeed(value) { return value === "rss" || value === "feed" || value === "rdf:RDF"; } /** * Parse a feed. * * @param feed The feed that should be parsed, as a string. * @param options Optionally, options for parsing. When using this option, you should set `xmlMode` to `true`. */ function parseFeed(feed, options) { if (options === void 0) { options = { xmlMode: true }; } var handler = new FeedHandler(options); new Parser_1.Parser(handler, options).end(feed); return handler.feed; } exports.parseFeed = parseFeed;