yahoo-finance2
Version:
JS API for Yahoo Finance
239 lines (238 loc) • 8.51 kB
JavaScript
;
// Copyright 2018-2025 the Deno authors. MIT license.
// This module is browser compatible.
Object.defineProperty(exports, "__esModule", { value: true });
exports._globToRegExp = _globToRegExp;
const REG_EXP_ESCAPE_CHARS = [
"!",
"$",
"(",
")",
"*",
"+",
".",
"=",
"?",
"[",
"\\",
"^",
"{",
"|",
];
const RANGE_ESCAPE_CHARS = ["-", "\\", "]"];
function _globToRegExp(c, glob, { extended = true, globstar: globstarOption = true,
// os = osType,
caseInsensitive = false, } = {}) {
if (glob === "") {
return /(?!)/;
}
// Remove trailing separators.
let newLength = glob.length;
for (; newLength > 1 && c.seps.includes(glob[newLength - 1]); newLength--)
;
glob = glob.slice(0, newLength);
let regExpString = "";
// Terminates correctly. Trust that `j` is incremented every iteration.
for (let j = 0; j < glob.length;) {
let segment = "";
const groupStack = [];
let inRange = false;
let inEscape = false;
let endsWithSep = false;
let i = j;
// Terminates with `i` at the non-inclusive end of the current segment.
for (; i < glob.length &&
!(c.seps.includes(glob[i]) && groupStack.length === 0); i++) {
if (inEscape) {
inEscape = false;
const escapeChars = (inRange
? RANGE_ESCAPE_CHARS
: REG_EXP_ESCAPE_CHARS);
segment += escapeChars.includes(glob[i])
? `\\${glob[i]}`
: glob[i];
continue;
}
if (glob[i] === c.escapePrefix) {
inEscape = true;
continue;
}
if (glob[i] === "[") {
if (!inRange) {
inRange = true;
segment += "[";
if (glob[i + 1] === "!") {
i++;
segment += "^";
}
else if (glob[i + 1] === "^") {
i++;
segment += "\\^";
}
continue;
}
else if (glob[i + 1] === ":") {
let k = i + 1;
let value = "";
while (glob[k + 1] !== undefined && glob[k + 1] !== ":") {
value += glob[k + 1];
k++;
}
if (glob[k + 1] === ":" && glob[k + 2] === "]") {
i = k + 2;
if (value === "alnum")
segment += "\\dA-Za-z";
else if (value === "alpha")
segment += "A-Za-z";
else if (value === "ascii")
segment += "\x00-\x7F";
else if (value === "blank")
segment += "\t ";
else if (value === "cntrl")
segment += "\x00-\x1F\x7F";
else if (value === "digit")
segment += "\\d";
else if (value === "graph")
segment += "\x21-\x7E";
else if (value === "lower")
segment += "a-z";
else if (value === "print")
segment += "\x20-\x7E";
else if (value === "punct") {
segment += "!\"#$%&'()*+,\\-./:;<=>?@[\\\\\\]^_‘{|}~";
}
else if (value === "space")
segment += "\\s\v";
else if (value === "upper")
segment += "A-Z";
else if (value === "word")
segment += "\\w";
else if (value === "xdigit")
segment += "\\dA-Fa-f";
continue;
}
}
}
if (glob[i] === "]" && inRange) {
inRange = false;
segment += "]";
continue;
}
if (inRange) {
segment += glob[i];
continue;
}
if (glob[i] === ")" && groupStack.length > 0 &&
groupStack[groupStack.length - 1] !== "BRACE") {
segment += ")";
const type = groupStack.pop();
if (type === "!") {
segment += c.wildcard;
}
else if (type !== "@") {
segment += type;
}
continue;
}
if (glob[i] === "|" && groupStack.length > 0 &&
groupStack[groupStack.length - 1] !== "BRACE") {
segment += "|";
continue;
}
if (glob[i] === "+" && extended && glob[i + 1] === "(") {
i++;
groupStack.push("+");
segment += "(?:";
continue;
}
if (glob[i] === "@" && extended && glob[i + 1] === "(") {
i++;
groupStack.push("@");
segment += "(?:";
continue;
}
if (glob[i] === "?") {
if (extended && glob[i + 1] === "(") {
i++;
groupStack.push("?");
segment += "(?:";
}
else {
segment += ".";
}
continue;
}
if (glob[i] === "!" && extended && glob[i + 1] === "(") {
i++;
groupStack.push("!");
segment += "(?!";
continue;
}
if (glob[i] === "{") {
groupStack.push("BRACE");
segment += "(?:";
continue;
}
if (glob[i] === "}" && groupStack[groupStack.length - 1] === "BRACE") {
groupStack.pop();
segment += ")";
continue;
}
if (glob[i] === "," && groupStack[groupStack.length - 1] === "BRACE") {
segment += "|";
continue;
}
if (glob[i] === "*") {
if (extended && glob[i + 1] === "(") {
i++;
groupStack.push("*");
segment += "(?:";
}
else {
const prevChar = glob[i - 1];
let numStars = 1;
while (glob[i + 1] === "*") {
i++;
numStars++;
}
const nextChar = glob[i + 1];
if (globstarOption && numStars === 2 &&
[...c.seps, undefined].includes(prevChar) &&
[...c.seps, undefined].includes(nextChar)) {
segment += c.globstar;
endsWithSep = true;
}
else {
segment += c.wildcard;
}
}
continue;
}
segment += REG_EXP_ESCAPE_CHARS.includes(glob[i])
? `\\${glob[i]}`
: glob[i];
}
// Check for unclosed groups or a dangling backslash.
if (groupStack.length > 0 || inRange || inEscape) {
// Parse failure. Take all characters from this segment literally.
segment = "";
for (const c of glob.slice(j, i)) {
segment += REG_EXP_ESCAPE_CHARS.includes(c)
? `\\${c}`
: c;
endsWithSep = false;
}
}
regExpString += segment;
if (!endsWithSep) {
regExpString += i < glob.length ? c.sep : c.sepMaybe;
endsWithSep = true;
}
// Terminates with `i` at the start of the next segment.
while (c.seps.includes(glob[i]))
i++;
j = i;
}
regExpString = `^${regExpString}$`;
return new RegExp(regExpString, caseInsensitive ? "i" : "");
}