UNPKG

@dsottimano/trendspy-js

Version:

ALPHA VERSION: JavaScript port of trendspy - A library for analyzing Google Trends data

135 lines (121 loc) 6.59 kB
"use strict"; function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } var _require = require('luxon'), DateTime = _require.DateTime; /** * Ensure input is a list/array * @param {*} item Item to convert to array if not already * @returns {Array} */ function ensureList(item) { return Array.isArray(item) ? item : [item]; } /** * Decode escaped text from Google Trends response * @param {string} text Escaped text to decode * @returns {string} */ function decodeEscapeText(text) { return text.replace(/\\x([0-9A-Fa-f]{2})/g, function (_, hex) { return String.fromCharCode(parseInt(hex, 16)); }).replace(/\\u([0-9A-Fa-f]{4})/g, function (_, hex) { return String.fromCharCode(parseInt(hex, 16)); }).replace(/\\(.)/g, '$1'); } /** * Convert timeframe string to standardized format * @param {string} timeframe Timeframe string to convert * @returns {string} */ function convertTimeframe(timeframe) { if (!timeframe) return "today 12-m"; var now = DateTime.local(); var timeframeLower = timeframe.toLowerCase(); // Handle 'all' timeframe if (timeframeLower === 'all') return timeframe; // Handle date range format (YYYY-MM-DD YYYY-MM-DD) if (/^\d{4}-\d{2}-\d{2} \d{4}-\d{2}-\d{2}$/.test(timeframe)) return timeframe; // Handle hourly format (YYYY-MM-DDTHH YYYY-MM-DDTHH) if (/^\d{4}-\d{2}-\d{2}T\d{2} \d{4}-\d{2}-\d{2}T\d{2}$/.test(timeframe)) return timeframe; // Parse 'now' format (e.g., 'now 4-H', 'now 1-d') var nowMatch = timeframeLower.match(/^now (\d+)-([hd])$/i); if (nowMatch) { var _nowMatch = _slicedToArray(nowMatch, 3), _ = _nowMatch[0], value = _nowMatch[1], unit = _nowMatch[2]; var duration = {}; duration[unit.toLowerCase() === 'h' ? 'hours' : 'days'] = parseInt(value); var startDate = now.minus(duration); return "".concat(startDate.toFormat("yyyy-MM-dd'T'HH"), " ").concat(now.toFormat("yyyy-MM-dd'T'HH")); } // Parse 'today' format (e.g., 'today 3-m', 'today 12-m') var todayMatch = timeframeLower.match(/^today (\d+)-([my])$/i); if (todayMatch) { var _todayMatch = _slicedToArray(todayMatch, 3), _2 = _todayMatch[0], _value = _todayMatch[1], _unit = _todayMatch[2]; var _duration = {}; _duration[_unit.toLowerCase() === 'm' ? 'months' : 'years'] = parseInt(_value); return "today ".concat(_value, "-").concat(_unit.toLowerCase()); } // Parse date with offset (e.g., '2024-03-25 5-m') var dateOffsetMatch = timeframe.match(/^(\d{4}-\d{2}-\d{2}) (\d+)-([my])$/i); if (dateOffsetMatch) { var _dateOffsetMatch = _slicedToArray(dateOffsetMatch, 4), _3 = _dateOffsetMatch[0], dateStr = _dateOffsetMatch[1], _value2 = _dateOffsetMatch[2], _unit2 = _dateOffsetMatch[3]; return "".concat(dateStr, " ").concat(_value2, "-").concat(_unit2.toLowerCase()); } return timeframe; } /** * Check if timeframes have compatible resolutions * @param {string|string[]} timeframes Timeframes to check * @throws {Error} If timeframes have incompatible resolutions */ function checkTimeframeResolution(timeframes) { var frames = ensureList(timeframes).map(convertTimeframe); if (frames.length <= 1) return; // Helper function to get resolution in minutes var getResolution = function getResolution(frame) { if (frame === 'all') return 43200; // Monthly resolution (30 days) var isDateRange = /^\d{4}-\d{2}-\d{2}/.test(frame); if (!isDateRange) return 1440; // Daily resolution var dates = frame.split(' ').map(function (d) { return DateTime.fromISO(d.replace('T', ' ')); }); var minutes = dates[1].diff(dates[0], 'minutes').minutes; if (minutes < 300) return 1; // < 5 hours: 1 minute if (minutes < 2160) return 8; // < 36 hours: 8 minutes if (minutes < 4320) return 16; // < 72 hours: 16 minutes if (minutes < 11520) return 60; // < 8 days: 1 hour if (minutes < 388800) return 1440; // < 270 days: 1 day if (minutes < 2736000) return 10080; // < 1900 days: 1 week return 43200; // >= 1900 days: 1 month }; var resolutions = frames.map(getResolution); var maxRes = Math.max.apply(Math, _toConsumableArray(resolutions)); var minRes = Math.min.apply(Math, _toConsumableArray(resolutions)); if (maxRes !== minRes) { throw new Error('All timeframes must have the same resolution. ' + "Current resolutions: ".concat(resolutions.join(', '), " minutes")); } } module.exports = { ensureList: ensureList, decodeEscapeText: decodeEscapeText, convertTimeframe: convertTimeframe, checkTimeframeResolution: checkTimeframeResolution };