diff --git a/docs/_coverpage.md b/docs/_coverpage.md index cba19e0..fcf4e1d 100644 --- a/docs/_coverpage.md +++ b/docs/_coverpage.md @@ -1,4 +1,4 @@ -# Barchart Market Data SDK JavaScript 5.19.0 +# Barchart Market Data SDK JavaScript 5.19.1 > Inject real-time market data into your JavaScript applications diff --git a/example/browser/example.js b/example/browser/example.js index f4dc4a6..072c579 100644 --- a/example/browser/example.js +++ b/example/browser/example.js @@ -5875,7 +5875,7 @@ module.exports = (() => { 'use strict'; return { - version: '5.19.0' + version: '5.19.1' }; })(); @@ -8409,12 +8409,8 @@ module.exports = (() => { } else if (year < 100) { year = Math.floor(currentYear / 100) * 100 + year; - if (year < currentYear) { - const alternateYear = year + 100; - - if (currentYear - year > alternateYear - currentYear) { - year = alternateYear; - } + if (currentYear + 25 < year) { + year = year - 100; } } @@ -17250,7 +17246,7 @@ process.umask = function() { return 0; }; },{"moment":88}],88:[function(require,module,exports){ //! moment.js -//! version : 2.29.1 +//! version : 2.29.3 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com @@ -17327,8 +17323,9 @@ process.umask = function() { return 0; }; function map(arr, fn) { var res = [], - i; - for (i = 0; i < arr.length; ++i) { + i, + arrLen = arr.length; + for (i = 0; i < arrLen; ++i) { res.push(fn(arr[i], i)); } return res; @@ -17457,7 +17454,10 @@ process.umask = function() { return 0; }; updateInProgress = false; function copyConfig(to, from) { - var i, prop, val; + var i, + prop, + val, + momentPropertiesLen = momentProperties.length; if (!isUndefined(from._isAMomentObject)) { to._isAMomentObject = from._isAMomentObject; @@ -17490,8 +17490,8 @@ process.umask = function() { return 0; }; to._locale = from._locale; } - if (momentProperties.length > 0) { - for (i = 0; i < momentProperties.length; i++) { + if (momentPropertiesLen > 0) { + for (i = 0; i < momentPropertiesLen; i++) { prop = momentProperties[i]; val = from[prop]; if (!isUndefined(val)) { @@ -17546,8 +17546,9 @@ process.umask = function() { return 0; }; var args = [], arg, i, - key; - for (i = 0; i < arguments.length; i++) { + key, + argLen = arguments.length; + for (i = 0; i < argLen; i++) { arg = ''; if (typeof arguments[i] === 'object') { arg += '\n[' + i + '] '; @@ -17697,7 +17698,8 @@ process.umask = function() { return 0; }; ); } - var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, + var formattingTokens = + /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, formatFunctions = {}, formatTokenFunctions = {}; @@ -18001,8 +18003,9 @@ process.umask = function() { return 0; }; if (typeof units === 'object') { units = normalizeObjectUnits(units); var prioritized = getPrioritizedUnits(units), - i; - for (i = 0; i < prioritized.length; i++) { + i, + prioritizedLen = prioritized.length; + for (i = 0; i < prioritizedLen; i++) { this[prioritized[i].unit](units[prioritized[i].unit]); } } else { @@ -18032,7 +18035,8 @@ process.umask = function() { return 0; }; matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 // any word (or two) characters or numbers including two/three word month in arabic. // includes scottish gaelic two word and hyphenated months - matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, + matchWord = + /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, regexes; regexes = {}; @@ -18058,15 +18062,12 @@ process.umask = function() { return 0; }; return regexEscape( s .replace('\\', '') - .replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function ( - matched, - p1, - p2, - p3, - p4 - ) { - return p1 || p2 || p3 || p4; - }) + .replace( + /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, + function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + } + ) ); } @@ -18078,7 +18079,8 @@ process.umask = function() { return 0; }; function addParseToken(token, callback) { var i, - func = callback; + func = callback, + tokenLen; if (typeof token === 'string') { token = [token]; } @@ -18087,7 +18089,8 @@ process.umask = function() { return 0; }; array[callback] = toInt(input); }; } - for (i = 0; i < token.length; i++) { + tokenLen = token.length; + for (i = 0; i < tokenLen; i++) { tokens[token[i]] = func; } } @@ -18198,12 +18201,12 @@ process.umask = function() { return 0; }; // LOCALES - var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split( - '_' - ), - defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split( - '_' - ), + var defaultLocaleMonths = + 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + defaultLocaleMonthsShort = + 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/, defaultMonthsShortRegex = matchWord, defaultMonthsRegex = matchWord; @@ -18645,14 +18648,12 @@ process.umask = function() { return 0; }; addRegexToken('W', match1to2); addRegexToken('WW', match1to2, match2); - addWeekParseToken(['w', 'ww', 'W', 'WW'], function ( - input, - week, - config, - token - ) { - week[token.substr(0, 1)] = toInt(input); - }); + addWeekParseToken( + ['w', 'ww', 'W', 'WW'], + function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + } + ); // HELPERS @@ -18777,9 +18778,8 @@ process.umask = function() { return 0; }; return ws.slice(n, 7).concat(ws.slice(0, n)); } - var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( - '_' - ), + var defaultLocaleWeekdays = + 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), defaultWeekdaysRegex = matchWord, @@ -19327,6 +19327,11 @@ process.umask = function() { return 0; }; return globalLocale; } + function isLocaleNameSane(name) { + // Prevent names that look like filesystem paths, i.e contain '/' or '\' + return name.match('^[^/\\\\]*$') != null; + } + function loadLocale(name) { var oldLocale = null, aliasedRequire; @@ -19335,7 +19340,8 @@ process.umask = function() { return 0; }; locales[name] === undefined && typeof module !== 'undefined' && module && - module.exports + module.exports && + isLocaleNameSane(name) ) { try { oldLocale = globalLocale._abbr; @@ -19552,8 +19558,10 @@ process.umask = function() { return 0; }; // iso 8601 regex // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, - basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, + var extendedIsoRegex = + /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, + basicIsoRegex = + /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, tzRegex = /Z|[+-]\d\d(?::?\d\d)?/, isoDates = [ ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], @@ -19584,7 +19592,8 @@ process.umask = function() { return 0; }; ], aspNetJsonRegex = /^\/?Date\((-?\d+)/i, // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 - rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/, + rfc2822 = + /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/, obsOffsets = { UT: 0, GMT: 0, @@ -19607,12 +19616,13 @@ process.umask = function() { return 0; }; allowTime, dateFormat, timeFormat, - tzFormat; + tzFormat, + isoDatesLen = isoDates.length, + isoTimesLen = isoTimes.length; if (match) { getParsingFlags(config).iso = true; - - for (i = 0, l = isoDates.length; i < l; i++) { + for (i = 0, l = isoDatesLen; i < l; i++) { if (isoDates[i][1].exec(match[1])) { dateFormat = isoDates[i][0]; allowTime = isoDates[i][2] !== false; @@ -19624,7 +19634,7 @@ process.umask = function() { return 0; }; return; } if (match[3]) { - for (i = 0, l = isoTimes.length; i < l; i++) { + for (i = 0, l = isoTimesLen; i < l; i++) { if (isoTimes[i][1].exec(match[3])) { // match[2] should be 'T' or space timeFormat = (match[2] || ' ') + isoTimes[i][0]; @@ -20004,12 +20014,13 @@ process.umask = function() { return 0; }; skipped, stringLength = string.length, totalParsedInputLength = 0, - era; + era, + tokenLen; tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; - - for (i = 0; i < tokens.length; i++) { + tokenLen = tokens.length; + for (i = 0; i < tokenLen; i++) { token = tokens[i]; parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; @@ -20104,15 +20115,16 @@ process.umask = function() { return 0; }; i, currentScore, validFormatFound, - bestFormatIsValid = false; + bestFormatIsValid = false, + configfLen = config._f.length; - if (config._f.length === 0) { + if (configfLen === 0) { getParsingFlags(config).invalidFormat = true; config._d = new Date(NaN); return; } - for (i = 0; i < config._f.length; i++) { + for (i = 0; i < configfLen; i++) { currentScore = 0; validFormatFound = false; tempConfig = copyConfig({}, config); @@ -20353,7 +20365,8 @@ process.umask = function() { return 0; }; function isDurationValid(m) { var key, unitHasDecimal = false, - i; + i, + orderLen = ordering.length; for (key in m) { if ( hasOwnProp(m, key) && @@ -20366,7 +20379,7 @@ process.umask = function() { return 0; }; } } - for (i = 0; i < ordering.length; ++i) { + for (i = 0; i < orderLen; ++i) { if (m[ordering[i]]) { if (unitHasDecimal) { return false; // only allow non-integers for smallest unit @@ -20691,7 +20704,8 @@ process.umask = function() { return 0; }; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere // and further modified to allow for strings containing both week and day - isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + isoRegex = + /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; function createDuration(input, key) { var duration = input, @@ -20912,9 +20926,10 @@ process.umask = function() { return 0; }; 'ms', ], i, - property; + property, + propertyLen = properties.length; - for (i = 0; i < properties.length; i += 1) { + for (i = 0; i < propertyLen; i += 1) { property = properties[i]; propertyTest = propertyTest || hasOwnProp(input, property); } @@ -21537,19 +21552,17 @@ process.umask = function() { return 0; }; addRegexToken('NNNN', matchEraName); addRegexToken('NNNNN', matchEraNarrow); - addParseToken(['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], function ( - input, - array, - config, - token - ) { - var era = config._locale.erasParse(input, token, config._strict); - if (era) { - getParsingFlags(config).era = era; - } else { - getParsingFlags(config).invalidEra = input; + addParseToken( + ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], + function (input, array, config, token) { + var era = config._locale.erasParse(input, token, config._strict); + if (era) { + getParsingFlags(config).era = era; + } else { + getParsingFlags(config).invalidEra = input; + } } - }); + ); addRegexToken('y', matchUnsigned); addRegexToken('yy', matchUnsigned); @@ -21841,14 +21854,12 @@ process.umask = function() { return 0; }; addRegexToken('GGGGG', match1to6, match6); addRegexToken('ggggg', match1to6, match6); - addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function ( - input, - week, - config, - token - ) { - week[token.substr(0, 2)] = toInt(input); - }); + addWeekParseToken( + ['gggg', 'ggggg', 'GGGG', 'GGGGG'], + function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); + } + ); addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { week[token] = hooks.parseTwoDigitYear(input); @@ -22871,7 +22882,7 @@ process.umask = function() { return 0; }; //! moment.js - hooks.version = '2.29.1'; + hooks.version = '2.29.3'; setHookCallback(createLocal); diff --git a/lib/meta.js b/lib/meta.js index ae60982..842ce9f 100644 --- a/lib/meta.js +++ b/lib/meta.js @@ -2,6 +2,6 @@ module.exports = (() => { 'use strict'; return { - version: '5.19.0' + version: '5.19.1' }; })(); \ No newline at end of file diff --git a/package.json b/package.json index 4301768..7d1805f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@barchart/marketdata-api-js", - "version": "5.19.0", + "version": "5.19.1", "description": "SDK for streaming market data from Barchart.com", "author": { "name": "Eero Pikat", diff --git a/test/dist/barchart-marketdata-api-tests-5.js b/test/dist/barchart-marketdata-api-tests-5.js index cc3d363..c096fbf 100644 --- a/test/dist/barchart-marketdata-api-tests-5.js +++ b/test/dist/barchart-marketdata-api-tests-5.js @@ -3618,12 +3618,8 @@ module.exports = (() => { } else if (year < 100) { year = Math.floor(currentYear / 100) * 100 + year; - if (year < currentYear) { - const alternateYear = year + 100; - - if (currentYear - year > alternateYear - currentYear) { - year = alternateYear; - } + if (currentYear + 25 < year) { + year = year - 100; } } @@ -9604,7 +9600,7 @@ exports.ParseError = ParseError; },{"moment":46}],46:[function(require,module,exports){ //! moment.js -//! version : 2.29.1 +//! version : 2.29.3 //! authors : Tim Wood, Iskren Chernev, Moment.js contributors //! license : MIT //! momentjs.com @@ -9681,8 +9677,9 @@ exports.ParseError = ParseError; function map(arr, fn) { var res = [], - i; - for (i = 0; i < arr.length; ++i) { + i, + arrLen = arr.length; + for (i = 0; i < arrLen; ++i) { res.push(fn(arr[i], i)); } return res; @@ -9811,7 +9808,10 @@ exports.ParseError = ParseError; updateInProgress = false; function copyConfig(to, from) { - var i, prop, val; + var i, + prop, + val, + momentPropertiesLen = momentProperties.length; if (!isUndefined(from._isAMomentObject)) { to._isAMomentObject = from._isAMomentObject; @@ -9844,8 +9844,8 @@ exports.ParseError = ParseError; to._locale = from._locale; } - if (momentProperties.length > 0) { - for (i = 0; i < momentProperties.length; i++) { + if (momentPropertiesLen > 0) { + for (i = 0; i < momentPropertiesLen; i++) { prop = momentProperties[i]; val = from[prop]; if (!isUndefined(val)) { @@ -9900,8 +9900,9 @@ exports.ParseError = ParseError; var args = [], arg, i, - key; - for (i = 0; i < arguments.length; i++) { + key, + argLen = arguments.length; + for (i = 0; i < argLen; i++) { arg = ''; if (typeof arguments[i] === 'object') { arg += '\n[' + i + '] '; @@ -10051,7 +10052,8 @@ exports.ParseError = ParseError; ); } - var formattingTokens = /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, + var formattingTokens = + /(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|N{1,5}|YYYYYY|YYYYY|YYYY|YY|y{2,4}|yo?|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|kk?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g, localFormattingTokens = /(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g, formatFunctions = {}, formatTokenFunctions = {}; @@ -10355,8 +10357,9 @@ exports.ParseError = ParseError; if (typeof units === 'object') { units = normalizeObjectUnits(units); var prioritized = getPrioritizedUnits(units), - i; - for (i = 0; i < prioritized.length; i++) { + i, + prioritizedLen = prioritized.length; + for (i = 0; i < prioritizedLen; i++) { this[prioritized[i].unit](units[prioritized[i].unit]); } } else { @@ -10386,7 +10389,8 @@ exports.ParseError = ParseError; matchTimestamp = /[+-]?\d+(\.\d{1,3})?/, // 123456789 123456789.123 // any word (or two) characters or numbers including two/three word month in arabic. // includes scottish gaelic two word and hyphenated months - matchWord = /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, + matchWord = + /[0-9]{0,256}['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFF07\uFF10-\uFFEF]{1,256}|[\u0600-\u06FF\/]{1,256}(\s*?[\u0600-\u06FF]{1,256}){1,2}/i, regexes; regexes = {}; @@ -10412,15 +10416,12 @@ exports.ParseError = ParseError; return regexEscape( s .replace('\\', '') - .replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, function ( - matched, - p1, - p2, - p3, - p4 - ) { - return p1 || p2 || p3 || p4; - }) + .replace( + /\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g, + function (matched, p1, p2, p3, p4) { + return p1 || p2 || p3 || p4; + } + ) ); } @@ -10432,7 +10433,8 @@ exports.ParseError = ParseError; function addParseToken(token, callback) { var i, - func = callback; + func = callback, + tokenLen; if (typeof token === 'string') { token = [token]; } @@ -10441,7 +10443,8 @@ exports.ParseError = ParseError; array[callback] = toInt(input); }; } - for (i = 0; i < token.length; i++) { + tokenLen = token.length; + for (i = 0; i < tokenLen; i++) { tokens[token[i]] = func; } } @@ -10552,12 +10555,12 @@ exports.ParseError = ParseError; // LOCALES - var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split( - '_' - ), - defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split( - '_' - ), + var defaultLocaleMonths = + 'January_February_March_April_May_June_July_August_September_October_November_December'.split( + '_' + ), + defaultLocaleMonthsShort = + 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'), MONTHS_IN_FORMAT = /D[oD]?(\[[^\[\]]*\]|\s)+MMMM?/, defaultMonthsShortRegex = matchWord, defaultMonthsRegex = matchWord; @@ -10999,14 +11002,12 @@ exports.ParseError = ParseError; addRegexToken('W', match1to2); addRegexToken('WW', match1to2, match2); - addWeekParseToken(['w', 'ww', 'W', 'WW'], function ( - input, - week, - config, - token - ) { - week[token.substr(0, 1)] = toInt(input); - }); + addWeekParseToken( + ['w', 'ww', 'W', 'WW'], + function (input, week, config, token) { + week[token.substr(0, 1)] = toInt(input); + } + ); // HELPERS @@ -11131,9 +11132,8 @@ exports.ParseError = ParseError; return ws.slice(n, 7).concat(ws.slice(0, n)); } - var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split( - '_' - ), + var defaultLocaleWeekdays = + 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'), defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'), defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'), defaultWeekdaysRegex = matchWord, @@ -11681,6 +11681,11 @@ exports.ParseError = ParseError; return globalLocale; } + function isLocaleNameSane(name) { + // Prevent names that look like filesystem paths, i.e contain '/' or '\' + return name.match('^[^/\\\\]*$') != null; + } + function loadLocale(name) { var oldLocale = null, aliasedRequire; @@ -11689,7 +11694,8 @@ exports.ParseError = ParseError; locales[name] === undefined && typeof module !== 'undefined' && module && - module.exports + module.exports && + isLocaleNameSane(name) ) { try { oldLocale = globalLocale._abbr; @@ -11906,8 +11912,10 @@ exports.ParseError = ParseError; // iso 8601 regex // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00) - var extendedIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, - basicIsoRegex = /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, + var extendedIsoRegex = + /^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, + basicIsoRegex = + /^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d|))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([+-]\d\d(?::?\d\d)?|\s*Z)?)?$/, tzRegex = /Z|[+-]\d\d(?::?\d\d)?/, isoDates = [ ['YYYYYY-MM-DD', /[+-]\d{6}-\d\d-\d\d/], @@ -11938,7 +11946,8 @@ exports.ParseError = ParseError; ], aspNetJsonRegex = /^\/?Date\((-?\d+)/i, // RFC 2822 regex: For details see https://tools.ietf.org/html/rfc2822#section-3.3 - rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/, + rfc2822 = + /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),?\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|([+-]\d{4}))$/, obsOffsets = { UT: 0, GMT: 0, @@ -11961,12 +11970,13 @@ exports.ParseError = ParseError; allowTime, dateFormat, timeFormat, - tzFormat; + tzFormat, + isoDatesLen = isoDates.length, + isoTimesLen = isoTimes.length; if (match) { getParsingFlags(config).iso = true; - - for (i = 0, l = isoDates.length; i < l; i++) { + for (i = 0, l = isoDatesLen; i < l; i++) { if (isoDates[i][1].exec(match[1])) { dateFormat = isoDates[i][0]; allowTime = isoDates[i][2] !== false; @@ -11978,7 +11988,7 @@ exports.ParseError = ParseError; return; } if (match[3]) { - for (i = 0, l = isoTimes.length; i < l; i++) { + for (i = 0, l = isoTimesLen; i < l; i++) { if (isoTimes[i][1].exec(match[3])) { // match[2] should be 'T' or space timeFormat = (match[2] || ' ') + isoTimes[i][0]; @@ -12358,12 +12368,13 @@ exports.ParseError = ParseError; skipped, stringLength = string.length, totalParsedInputLength = 0, - era; + era, + tokenLen; tokens = expandFormat(config._f, config._locale).match(formattingTokens) || []; - - for (i = 0; i < tokens.length; i++) { + tokenLen = tokens.length; + for (i = 0; i < tokenLen; i++) { token = tokens[i]; parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0]; @@ -12458,15 +12469,16 @@ exports.ParseError = ParseError; i, currentScore, validFormatFound, - bestFormatIsValid = false; + bestFormatIsValid = false, + configfLen = config._f.length; - if (config._f.length === 0) { + if (configfLen === 0) { getParsingFlags(config).invalidFormat = true; config._d = new Date(NaN); return; } - for (i = 0; i < config._f.length; i++) { + for (i = 0; i < configfLen; i++) { currentScore = 0; validFormatFound = false; tempConfig = copyConfig({}, config); @@ -12707,7 +12719,8 @@ exports.ParseError = ParseError; function isDurationValid(m) { var key, unitHasDecimal = false, - i; + i, + orderLen = ordering.length; for (key in m) { if ( hasOwnProp(m, key) && @@ -12720,7 +12733,7 @@ exports.ParseError = ParseError; } } - for (i = 0; i < ordering.length; ++i) { + for (i = 0; i < orderLen; ++i) { if (m[ordering[i]]) { if (unitHasDecimal) { return false; // only allow non-integers for smallest unit @@ -13045,7 +13058,8 @@ exports.ParseError = ParseError; // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere // and further modified to allow for strings containing both week and day - isoRegex = /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; + isoRegex = + /^(-|\+)?P(?:([-+]?[0-9,.]*)Y)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)W)?(?:([-+]?[0-9,.]*)D)?(?:T(?:([-+]?[0-9,.]*)H)?(?:([-+]?[0-9,.]*)M)?(?:([-+]?[0-9,.]*)S)?)?$/; function createDuration(input, key) { var duration = input, @@ -13266,9 +13280,10 @@ exports.ParseError = ParseError; 'ms', ], i, - property; + property, + propertyLen = properties.length; - for (i = 0; i < properties.length; i += 1) { + for (i = 0; i < propertyLen; i += 1) { property = properties[i]; propertyTest = propertyTest || hasOwnProp(input, property); } @@ -13891,19 +13906,17 @@ exports.ParseError = ParseError; addRegexToken('NNNN', matchEraName); addRegexToken('NNNNN', matchEraNarrow); - addParseToken(['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], function ( - input, - array, - config, - token - ) { - var era = config._locale.erasParse(input, token, config._strict); - if (era) { - getParsingFlags(config).era = era; - } else { - getParsingFlags(config).invalidEra = input; + addParseToken( + ['N', 'NN', 'NNN', 'NNNN', 'NNNNN'], + function (input, array, config, token) { + var era = config._locale.erasParse(input, token, config._strict); + if (era) { + getParsingFlags(config).era = era; + } else { + getParsingFlags(config).invalidEra = input; + } } - }); + ); addRegexToken('y', matchUnsigned); addRegexToken('yy', matchUnsigned); @@ -14195,14 +14208,12 @@ exports.ParseError = ParseError; addRegexToken('GGGGG', match1to6, match6); addRegexToken('ggggg', match1to6, match6); - addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function ( - input, - week, - config, - token - ) { - week[token.substr(0, 2)] = toInt(input); - }); + addWeekParseToken( + ['gggg', 'ggggg', 'GGGG', 'GGGGG'], + function (input, week, config, token) { + week[token.substr(0, 2)] = toInt(input); + } + ); addWeekParseToken(['gg', 'GG'], function (input, week, config, token) { week[token] = hooks.parseTwoDigitYear(input); @@ -15225,7 +15236,7 @@ exports.ParseError = ParseError; //! moment.js - hooks.version = '2.29.1'; + hooks.version = '2.29.3'; setHookCallback(createLocal); @@ -20390,6 +20401,75 @@ describe('When parsing a symbol for instrument type', () => { }); }); }); +describe('When parsing a symbol for a futures contract', () => { + describe('and the year is 2022', () => { + let getFullYear; + beforeEach(() => { + getFullYear = Date.prototype.getFullYear; + + Date.prototype.getFullYear = () => { + return 2022; + }; + }); + it('the expiration year of "ZCN19" should parse to 2019', () => { + expect(SymbolParser.parseInstrumentType('ZCN19').year).toEqual(2019); + }); + it('the expiration year of "ZCN21" should parse to 2021', () => { + expect(SymbolParser.parseInstrumentType('ZCN21').year).toEqual(2021); + }); + it('the expiration year of "ZCN22" should parse to 2022', () => { + expect(SymbolParser.parseInstrumentType('ZCN22').year).toEqual(2022); + }); + it('the expiration year of "ZCN32" should parse to 2032', () => { + expect(SymbolParser.parseInstrumentType('ZCN32').year).toEqual(2032); + }); + it('the expiration year of "ZCN42" should parse to 2042', () => { + expect(SymbolParser.parseInstrumentType('ZCN42').year).toEqual(2042); + }); + it('the expiration year of "ZCN47" should parse to 2047', () => { + expect(SymbolParser.parseInstrumentType('ZCN47').year).toEqual(2047); + }); + it('the expiration year of "ZCN48" should parse to 1948', () => { + expect(SymbolParser.parseInstrumentType('ZCN48').year).toEqual(1948); + }); + it('the expiration year of "ZCN49" should parse to 1949', () => { + expect(SymbolParser.parseInstrumentType('ZCN49').year).toEqual(1949); + }); + it('the expiration year of "ZCN99" should parse to 1999', () => { + expect(SymbolParser.parseInstrumentType('ZCM99').year).toEqual(1999); + }); + afterEach(() => { + Date.prototype.getFullYear = getFullYear; + }); + }); +}); +describe('When parsing a symbol for a futures option', () => { + describe('and the year is 2022', () => { + let getFullYear; + beforeEach(() => { + getFullYear = Date.prototype.getFullYear; + + Date.prototype.getFullYear = () => { + return 2022; + }; + }); + it('the expiration year of "ZWK18465C" should parse to 2018', () => { + expect(SymbolParser.parseInstrumentType('ZWK18465C').year).toEqual(2018); + }); + it('the expiration year of "ZWK22465C" should parse to 2022', () => { + expect(SymbolParser.parseInstrumentType('ZWK22465C').year).toEqual(2022); + }); + it('the expiration year of "ZWK47465C" should parse to 2047', () => { + expect(SymbolParser.parseInstrumentType('ZWK47465C').year).toEqual(2047); + }); + it('the expiration year of "ZWK48465C" should parse to 2048', () => { + expect(SymbolParser.parseInstrumentType('ZWK48465C').year).toEqual(1948); + }); + afterEach(() => { + Date.prototype.getFullYear = getFullYear; + }); + }); +}); describe('When checking to see if a symbol is a future', () => { it('the symbol "ES*1" should return true', () => { expect(SymbolParser.getIsFuture('ES*1')).toEqual(true); @@ -20861,7 +20941,7 @@ describe('When checking to see if a symbol is crypto', () => { expect(SymbolParser.getIsCrypto('VIC400.CF')).toEqual(false); }); }); -describe('When checking to see if a symbol is a future spread', () => { +describe('When checking to see if a symbol is a futures spread', () => { it('the symbol "ES*1" should return false', () => { expect(SymbolParser.getIsFutureSpread('ES*1')).toEqual(false); }); @@ -20971,7 +21051,7 @@ describe('When checking to see if a symbol is a future spread', () => { expect(SymbolParser.getIsFutureSpread('VIC400.CF')).toEqual(false); }); }); -describe('When checking to see if a symbol is a future option', () => { +describe('When checking to see if a symbol is a futures option', () => { it('the symbol "ES*1" should return false', () => { expect(SymbolParser.getIsFutureOption('ES*1')).toEqual(false); }); @@ -21849,6 +21929,38 @@ describe('When getting a producer symbol', () => { expect(producerSymbol).toEqual('ZWK465X'); }); }); + describe('When testing ZCN22|800P in 2022', () => { + let producerSymbol; + beforeEach(() => { + let getFullYear = Date.prototype.getFullYear; + + Date.prototype.getFullYear = () => { + return 2022; + }; + + producerSymbol = SymbolParser.getProducerSymbol('ZCN22|800P'); + Date.prototype.getFullYear = getFullYear; + }); + it('ZCN22|800P should map to ZCN800P', () => { + expect(producerSymbol).toEqual('ZCN800P'); + }); + }); + describe('When testing ZCN2|800P in 2022', () => { + let producerSymbol; + beforeEach(() => { + let getFullYear = Date.prototype.getFullYear; + + Date.prototype.getFullYear = () => { + return 2022; + }; + + producerSymbol = SymbolParser.getProducerSymbol('ZCN2|800P'); + Date.prototype.getFullYear = getFullYear; + }); + it('ZCN2|800P should map to ZCN800P', () => { + expect(producerSymbol).toEqual('ZCN800P'); + }); + }); }); }); describe('When checking to see if a symbol is expired', () => {