react-email
Version:
A live preview of your emails right in your browser.
1,643 lines • 287 kB
JavaScript
#!/usr/bin/env node
import { createRequire } from "node:module";
import { spawn } from "node:child_process";
import { InvalidArgumentError, Option, program } from "commander";
import * as fs$1 from "node:fs";
import fs, { existsSync, promises, statSync } from "node:fs";
import * as path$2 from "node:path";
import path from "node:path";
import url, { fileURLToPath } from "node:url";
import * as fsp$1 from "node:fs/promises";
import fsp from "node:fs/promises";
import { F_OK } from "node:constants";
import * as nativeFs$1 from "fs";
import nativeFs from "fs";
import path$1, { basename, dirname, normalize, posix, relative, resolve, sep } from "path";
import { fileURLToPath as fileURLToPath$1 } from "url";
import { createRequire as createRequire$1 } from "module";
import logSymbols from "log-symbols";
import { addDevDependency, installDependencies, runScript } from "nypm";
import { createJiti } from "jiti";
import prompts from "prompts";
import { Spinner } from "picospinner";
import { watch } from "chokidar";
import debounce from "debounce";
import { Server } from "socket.io";
import { parse } from "@babel/parser";
import traverseModule from "@babel/traverse";
import { createMatchPath, loadConfig } from "tsconfig-paths";
import http from "node:http";
import os from "node:os";
import Conf from "conf";
import * as nodeUtil from "node:util";
import { lookup } from "mime-types";
import { Worker } from "node:worker_threads";
import { build, stop } from "esbuild";
import { glob } from "glob";
import normalize$1 from "normalize-path";
//#region \0rolldown/runtime.js
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
key = keys[i];
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
get: ((k) => from[k]).bind(null, key),
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
});
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
value: mod,
enumerable: true
}) : target, mod));
var __require$1 = /* @__PURE__ */ createRequire(import.meta.url);
//#endregion
//#region ../../node_modules/.pnpm/fdir@6.5.0_picomatch@4.0.4/node_modules/fdir/dist/index.mjs
var __require = /* @__PURE__ */ createRequire$1(import.meta.url);
function cleanPath(path) {
let normalized = normalize(path);
if (normalized.length > 1 && normalized[normalized.length - 1] === sep) normalized = normalized.substring(0, normalized.length - 1);
return normalized;
}
const SLASHES_REGEX = /[\\/]/g;
function convertSlashes(path, separator) {
return path.replace(SLASHES_REGEX, separator);
}
const WINDOWS_ROOT_DIR_REGEX = /^[a-z]:[\\/]$/i;
function isRootDirectory(path) {
return path === "/" || WINDOWS_ROOT_DIR_REGEX.test(path);
}
function normalizePath(path, options) {
const { resolvePaths, normalizePath: normalizePath$1, pathSeparator } = options;
const pathNeedsCleaning = process.platform === "win32" && path.includes("/") || path.startsWith(".");
if (resolvePaths) path = resolve(path);
if (normalizePath$1 || pathNeedsCleaning) path = cleanPath(path);
if (path === ".") return "";
return convertSlashes(path[path.length - 1] !== pathSeparator ? path + pathSeparator : path, pathSeparator);
}
function joinPathWithBasePath(filename, directoryPath) {
return directoryPath + filename;
}
function joinPathWithRelativePath(root, options) {
return function(filename, directoryPath) {
if (directoryPath.startsWith(root)) return directoryPath.slice(root.length) + filename;
else return convertSlashes(relative(root, directoryPath), options.pathSeparator) + options.pathSeparator + filename;
};
}
function joinPath(filename) {
return filename;
}
function joinDirectoryPath(filename, directoryPath, separator) {
return directoryPath + filename + separator;
}
function build$7(root, options) {
const { relativePaths, includeBasePath } = options;
return relativePaths && root ? joinPathWithRelativePath(root, options) : includeBasePath ? joinPathWithBasePath : joinPath;
}
function pushDirectoryWithRelativePath(root) {
return function(directoryPath, paths) {
paths.push(directoryPath.substring(root.length) || ".");
};
}
function pushDirectoryFilterWithRelativePath(root) {
return function(directoryPath, paths, filters) {
const relativePath = directoryPath.substring(root.length) || ".";
if (filters.every((filter) => filter(relativePath, true))) paths.push(relativePath);
};
}
const pushDirectory = (directoryPath, paths) => {
paths.push(directoryPath || ".");
};
const pushDirectoryFilter = (directoryPath, paths, filters) => {
const path = directoryPath || ".";
if (filters.every((filter) => filter(path, true))) paths.push(path);
};
const empty$2 = () => {};
function build$6(root, options) {
const { includeDirs, filters, relativePaths } = options;
if (!includeDirs) return empty$2;
if (relativePaths) return filters && filters.length ? pushDirectoryFilterWithRelativePath(root) : pushDirectoryWithRelativePath(root);
return filters && filters.length ? pushDirectoryFilter : pushDirectory;
}
const pushFileFilterAndCount = (filename, _paths, counts, filters) => {
if (filters.every((filter) => filter(filename, false))) counts.files++;
};
const pushFileFilter = (filename, paths, _counts, filters) => {
if (filters.every((filter) => filter(filename, false))) paths.push(filename);
};
const pushFileCount = (_filename, _paths, counts, _filters) => {
counts.files++;
};
const pushFile = (filename, paths) => {
paths.push(filename);
};
const empty$1 = () => {};
function build$5(options) {
const { excludeFiles, filters, onlyCounts } = options;
if (excludeFiles) return empty$1;
if (filters && filters.length) return onlyCounts ? pushFileFilterAndCount : pushFileFilter;
else if (onlyCounts) return pushFileCount;
else return pushFile;
}
const getArray = (paths) => {
return paths;
};
const getArrayGroup = () => {
return [""].slice(0, 0);
};
function build$4(options) {
return options.group ? getArrayGroup : getArray;
}
const groupFiles = (groups, directory, files) => {
groups.push({
directory,
files,
dir: directory
});
};
const empty = () => {};
function build$3(options) {
return options.group ? groupFiles : empty;
}
const resolveSymlinksAsync = function(path, state, callback$1) {
const { queue, fs, options: { suppressErrors } } = state;
queue.enqueue();
fs.realpath(path, (error, resolvedPath) => {
if (error) return queue.dequeue(suppressErrors ? null : error, state);
fs.stat(resolvedPath, (error$1, stat) => {
if (error$1) return queue.dequeue(suppressErrors ? null : error$1, state);
if (stat.isDirectory() && isRecursive(path, resolvedPath, state)) return queue.dequeue(null, state);
callback$1(stat, resolvedPath);
queue.dequeue(null, state);
});
});
};
const resolveSymlinks = function(path, state, callback$1) {
const { queue, fs, options: { suppressErrors } } = state;
queue.enqueue();
try {
const resolvedPath = fs.realpathSync(path);
const stat = fs.statSync(resolvedPath);
if (stat.isDirectory() && isRecursive(path, resolvedPath, state)) return;
callback$1(stat, resolvedPath);
} catch (e) {
if (!suppressErrors) throw e;
}
};
function build$2(options, isSynchronous) {
if (!options.resolveSymlinks || options.excludeSymlinks) return null;
return isSynchronous ? resolveSymlinks : resolveSymlinksAsync;
}
function isRecursive(path, resolved, state) {
if (state.options.useRealPaths) return isRecursiveUsingRealPaths(resolved, state);
let parent = dirname(path);
let depth = 1;
while (parent !== state.root && depth < 2) {
const resolvedPath = state.symlinks.get(parent);
if (!!resolvedPath && (resolvedPath === resolved || resolvedPath.startsWith(resolved) || resolved.startsWith(resolvedPath))) depth++;
else parent = dirname(parent);
}
state.symlinks.set(path, resolved);
return depth > 1;
}
function isRecursiveUsingRealPaths(resolved, state) {
return state.visited.includes(resolved + state.options.pathSeparator);
}
const onlyCountsSync = (state) => {
return state.counts;
};
const groupsSync = (state) => {
return state.groups;
};
const defaultSync = (state) => {
return state.paths;
};
const limitFilesSync = (state) => {
return state.paths.slice(0, state.options.maxFiles);
};
const onlyCountsAsync = (state, error, callback$1) => {
report(error, callback$1, state.counts, state.options.suppressErrors);
return null;
};
const defaultAsync = (state, error, callback$1) => {
report(error, callback$1, state.paths, state.options.suppressErrors);
return null;
};
const limitFilesAsync = (state, error, callback$1) => {
report(error, callback$1, state.paths.slice(0, state.options.maxFiles), state.options.suppressErrors);
return null;
};
const groupsAsync = (state, error, callback$1) => {
report(error, callback$1, state.groups, state.options.suppressErrors);
return null;
};
function report(error, callback$1, output, suppressErrors) {
if (error && !suppressErrors) callback$1(error, output);
else callback$1(null, output);
}
function build$1$1(options, isSynchronous) {
const { onlyCounts, group, maxFiles } = options;
if (onlyCounts) return isSynchronous ? onlyCountsSync : onlyCountsAsync;
else if (group) return isSynchronous ? groupsSync : groupsAsync;
else if (maxFiles) return isSynchronous ? limitFilesSync : limitFilesAsync;
else return isSynchronous ? defaultSync : defaultAsync;
}
const readdirOpts = { withFileTypes: true };
const walkAsync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
state.queue.enqueue();
if (currentDepth < 0) return state.queue.dequeue(null, state);
const { fs } = state;
state.visited.push(crawlPath);
state.counts.directories++;
fs.readdir(crawlPath || ".", readdirOpts, (error, entries = []) => {
callback$1(entries, directoryPath, currentDepth);
state.queue.dequeue(state.options.suppressErrors ? null : error, state);
});
};
const walkSync = (state, crawlPath, directoryPath, currentDepth, callback$1) => {
const { fs } = state;
if (currentDepth < 0) return;
state.visited.push(crawlPath);
state.counts.directories++;
let entries = [];
try {
entries = fs.readdirSync(crawlPath || ".", readdirOpts);
} catch (e) {
if (!state.options.suppressErrors) throw e;
}
callback$1(entries, directoryPath, currentDepth);
};
function build$8(isSynchronous) {
return isSynchronous ? walkSync : walkAsync;
}
/**
* This is a custom stateless queue to track concurrent async fs calls.
* It increments a counter whenever a call is queued and decrements it
* as soon as it completes. When the counter hits 0, it calls onQueueEmpty.
*/
var Queue = class {
count = 0;
constructor(onQueueEmpty) {
this.onQueueEmpty = onQueueEmpty;
}
enqueue() {
this.count++;
return this.count;
}
dequeue(error, output) {
if (this.onQueueEmpty && (--this.count <= 0 || error)) {
this.onQueueEmpty(error, output);
if (error) {
output.controller.abort();
this.onQueueEmpty = void 0;
}
}
}
};
var Counter = class {
_files = 0;
_directories = 0;
set files(num) {
this._files = num;
}
get files() {
return this._files;
}
set directories(num) {
this._directories = num;
}
get directories() {
return this._directories;
}
/**
* @deprecated use `directories` instead
*/
/* c8 ignore next 3 */
get dirs() {
return this._directories;
}
};
/**
* AbortController is not supported on Node 14 so we use this until we can drop
* support for Node 14.
*/
var Aborter = class {
aborted = false;
abort() {
this.aborted = true;
}
};
var Walker = class {
root;
isSynchronous;
state;
joinPath;
pushDirectory;
pushFile;
getArray;
groupFiles;
resolveSymlink;
walkDirectory;
callbackInvoker;
constructor(root, options, callback$1) {
this.isSynchronous = !callback$1;
this.callbackInvoker = build$1$1(options, this.isSynchronous);
this.root = normalizePath(root, options);
this.state = {
root: isRootDirectory(this.root) ? this.root : this.root.slice(0, -1),
paths: [""].slice(0, 0),
groups: [],
counts: new Counter(),
options,
queue: new Queue((error, state) => this.callbackInvoker(state, error, callback$1)),
symlinks: /* @__PURE__ */ new Map(),
visited: [""].slice(0, 0),
controller: new Aborter(),
fs: options.fs || nativeFs$1
};
this.joinPath = build$7(this.root, options);
this.pushDirectory = build$6(this.root, options);
this.pushFile = build$5(options);
this.getArray = build$4(options);
this.groupFiles = build$3(options);
this.resolveSymlink = build$2(options, this.isSynchronous);
this.walkDirectory = build$8(this.isSynchronous);
}
start() {
this.pushDirectory(this.root, this.state.paths, this.state.options.filters);
this.walkDirectory(this.state, this.root, this.root, this.state.options.maxDepth, this.walk);
return this.isSynchronous ? this.callbackInvoker(this.state, null) : null;
}
walk = (entries, directoryPath, depth) => {
const { paths, options: { filters, resolveSymlinks: resolveSymlinks$1, excludeSymlinks, exclude, maxFiles, signal, useRealPaths, pathSeparator }, controller } = this.state;
if (controller.aborted || signal && signal.aborted || maxFiles && paths.length > maxFiles) return;
const files = this.getArray(this.state.paths);
for (let i = 0; i < entries.length; ++i) {
const entry = entries[i];
if (entry.isFile() || entry.isSymbolicLink() && !resolveSymlinks$1 && !excludeSymlinks) {
const filename = this.joinPath(entry.name, directoryPath);
this.pushFile(filename, files, this.state.counts, filters);
} else if (entry.isDirectory()) {
let path = joinDirectoryPath(entry.name, directoryPath, this.state.options.pathSeparator);
if (exclude && exclude(entry.name, path)) continue;
this.pushDirectory(path, paths, filters);
this.walkDirectory(this.state, path, path, depth - 1, this.walk);
} else if (this.resolveSymlink && entry.isSymbolicLink()) {
let path = joinPathWithBasePath(entry.name, directoryPath);
this.resolveSymlink(path, this.state, (stat, resolvedPath) => {
if (stat.isDirectory()) {
resolvedPath = normalizePath(resolvedPath, this.state.options);
if (exclude && exclude(entry.name, useRealPaths ? resolvedPath : path + pathSeparator)) return;
this.walkDirectory(this.state, resolvedPath, useRealPaths ? resolvedPath : path + pathSeparator, depth - 1, this.walk);
} else {
resolvedPath = useRealPaths ? resolvedPath : path;
const filename = basename(resolvedPath);
const directoryPath$1 = normalizePath(dirname(resolvedPath), this.state.options);
resolvedPath = this.joinPath(filename, directoryPath$1);
this.pushFile(resolvedPath, files, this.state.counts, filters);
}
});
}
}
this.groupFiles(this.state.groups, directoryPath, files);
};
};
function promise(root, options) {
return new Promise((resolve$1, reject) => {
callback(root, options, (err, output) => {
if (err) return reject(err);
resolve$1(output);
});
});
}
function callback(root, options, callback$1) {
new Walker(root, options, callback$1).start();
}
function sync(root, options) {
return new Walker(root, options).start();
}
var APIBuilder = class {
constructor(root, options) {
this.root = root;
this.options = options;
}
withPromise() {
return promise(this.root, this.options);
}
withCallback(cb) {
callback(this.root, this.options, cb);
}
sync() {
return sync(this.root, this.options);
}
};
let pm = null;
/* c8 ignore next 6 */
try {
__require.resolve("picomatch");
pm = __require("picomatch");
} catch {}
var Builder = class {
globCache = {};
options = {
maxDepth: Infinity,
suppressErrors: true,
pathSeparator: sep,
filters: []
};
globFunction;
constructor(options) {
this.options = {
...this.options,
...options
};
this.globFunction = this.options.globFunction;
}
group() {
this.options.group = true;
return this;
}
withPathSeparator(separator) {
this.options.pathSeparator = separator;
return this;
}
withBasePath() {
this.options.includeBasePath = true;
return this;
}
withRelativePaths() {
this.options.relativePaths = true;
return this;
}
withDirs() {
this.options.includeDirs = true;
return this;
}
withMaxDepth(depth) {
this.options.maxDepth = depth;
return this;
}
withMaxFiles(limit) {
this.options.maxFiles = limit;
return this;
}
withFullPaths() {
this.options.resolvePaths = true;
this.options.includeBasePath = true;
return this;
}
withErrors() {
this.options.suppressErrors = false;
return this;
}
withSymlinks({ resolvePaths = true } = {}) {
this.options.resolveSymlinks = true;
this.options.useRealPaths = resolvePaths;
return this.withFullPaths();
}
withAbortSignal(signal) {
this.options.signal = signal;
return this;
}
normalize() {
this.options.normalizePath = true;
return this;
}
filter(predicate) {
this.options.filters.push(predicate);
return this;
}
onlyDirs() {
this.options.excludeFiles = true;
this.options.includeDirs = true;
return this;
}
exclude(predicate) {
this.options.exclude = predicate;
return this;
}
onlyCounts() {
this.options.onlyCounts = true;
return this;
}
crawl(root) {
return new APIBuilder(root || ".", this.options);
}
withGlobFunction(fn) {
this.globFunction = fn;
return this;
}
/**
* @deprecated Pass options using the constructor instead:
* ```ts
* new fdir(options).crawl("/path/to/root");
* ```
* This method will be removed in v7.0
*/
/* c8 ignore next 4 */
crawlWithOptions(root, options) {
this.options = {
...this.options,
...options
};
return new APIBuilder(root || ".", this.options);
}
glob(...patterns) {
if (this.globFunction) return this.globWithOptions(patterns);
return this.globWithOptions(patterns, ...[{ dot: true }]);
}
globWithOptions(patterns, ...options) {
const globFn = this.globFunction || pm;
/* c8 ignore next 5 */
if (!globFn) throw new Error("Please specify a glob function to use glob matching.");
var isMatch = this.globCache[patterns.join("\0")];
if (!isMatch) {
isMatch = globFn(patterns, ...options);
this.globCache[patterns.join("\0")] = isMatch;
}
this.options.filters.push((path) => isMatch(path));
return this;
}
};
//#endregion
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/constants.js
var require_constants = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const WIN_SLASH = "\\\\/";
const WIN_NO_SLASH = `[^${WIN_SLASH}]`;
const DEFAULT_MAX_EXTGLOB_RECURSION = 0;
/**
* Posix glob regex
*/
const DOT_LITERAL = "\\.";
const PLUS_LITERAL = "\\+";
const QMARK_LITERAL = "\\?";
const SLASH_LITERAL = "\\/";
const ONE_CHAR = "(?=.)";
const QMARK = "[^/]";
const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`;
const START_ANCHOR = `(?:^|${SLASH_LITERAL})`;
const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`;
const POSIX_CHARS = {
DOT_LITERAL,
PLUS_LITERAL,
QMARK_LITERAL,
SLASH_LITERAL,
ONE_CHAR,
QMARK,
END_ANCHOR,
DOTS_SLASH,
NO_DOT: `(?!${DOT_LITERAL})`,
NO_DOTS: `(?!${START_ANCHOR}${DOTS_SLASH})`,
NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`,
NO_DOTS_SLASH: `(?!${DOTS_SLASH})`,
QMARK_NO_DOT: `[^.${SLASH_LITERAL}]`,
STAR: `${QMARK}*?`,
START_ANCHOR,
SEP: "/"
};
/**
* Windows glob regex
*/
const WINDOWS_CHARS = {
...POSIX_CHARS,
SLASH_LITERAL: `[${WIN_SLASH}]`,
QMARK: WIN_NO_SLASH,
STAR: `${WIN_NO_SLASH}*?`,
DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,
NO_DOT: `(?!${DOT_LITERAL})`,
NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,
NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,
QMARK_NO_DOT: `[^.${WIN_SLASH}]`,
START_ANCHOR: `(?:^|[${WIN_SLASH}])`,
END_ANCHOR: `(?:[${WIN_SLASH}]|$)`,
SEP: "\\"
};
module.exports = {
DEFAULT_MAX_EXTGLOB_RECURSION,
MAX_LENGTH: 1024 * 64,
POSIX_REGEX_SOURCE: {
__proto__: null,
alnum: "a-zA-Z0-9",
alpha: "a-zA-Z",
ascii: "\\x00-\\x7F",
blank: " \\t",
cntrl: "\\x00-\\x1F\\x7F",
digit: "0-9",
graph: "\\x21-\\x7E",
lower: "a-z",
print: "\\x20-\\x7E ",
punct: "\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",
space: " \\t\\r\\n\\v\\f",
upper: "A-Z",
word: "A-Za-z0-9_",
xdigit: "A-Fa-f0-9"
},
REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,
REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,
REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,
REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,
REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,
REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,
REPLACEMENTS: {
__proto__: null,
"***": "*",
"**/**": "**",
"**/**/**": "**"
},
CHAR_0: 48,
CHAR_9: 57,
CHAR_UPPERCASE_A: 65,
CHAR_LOWERCASE_A: 97,
CHAR_UPPERCASE_Z: 90,
CHAR_LOWERCASE_Z: 122,
CHAR_LEFT_PARENTHESES: 40,
CHAR_RIGHT_PARENTHESES: 41,
CHAR_ASTERISK: 42,
CHAR_AMPERSAND: 38,
CHAR_AT: 64,
CHAR_BACKWARD_SLASH: 92,
CHAR_CARRIAGE_RETURN: 13,
CHAR_CIRCUMFLEX_ACCENT: 94,
CHAR_COLON: 58,
CHAR_COMMA: 44,
CHAR_DOT: 46,
CHAR_DOUBLE_QUOTE: 34,
CHAR_EQUAL: 61,
CHAR_EXCLAMATION_MARK: 33,
CHAR_FORM_FEED: 12,
CHAR_FORWARD_SLASH: 47,
CHAR_GRAVE_ACCENT: 96,
CHAR_HASH: 35,
CHAR_HYPHEN_MINUS: 45,
CHAR_LEFT_ANGLE_BRACKET: 60,
CHAR_LEFT_CURLY_BRACE: 123,
CHAR_LEFT_SQUARE_BRACKET: 91,
CHAR_LINE_FEED: 10,
CHAR_NO_BREAK_SPACE: 160,
CHAR_PERCENT: 37,
CHAR_PLUS: 43,
CHAR_QUESTION_MARK: 63,
CHAR_RIGHT_ANGLE_BRACKET: 62,
CHAR_RIGHT_CURLY_BRACE: 125,
CHAR_RIGHT_SQUARE_BRACKET: 93,
CHAR_SEMICOLON: 59,
CHAR_SINGLE_QUOTE: 39,
CHAR_SPACE: 32,
CHAR_TAB: 9,
CHAR_UNDERSCORE: 95,
CHAR_VERTICAL_LINE: 124,
CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279,
extglobChars(chars) {
return {
"!": {
type: "negate",
open: "(?:(?!(?:",
close: `))${chars.STAR})`
},
"?": {
type: "qmark",
open: "(?:",
close: ")?"
},
"+": {
type: "plus",
open: "(?:",
close: ")+"
},
"*": {
type: "star",
open: "(?:",
close: ")*"
},
"@": {
type: "at",
open: "(?:",
close: ")"
}
};
},
globChars(win32) {
return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;
}
};
}));
//#endregion
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/utils.js
var require_utils$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
const { REGEX_BACKSLASH, REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL } = require_constants();
exports.isObject = (val) => val !== null && typeof val === "object" && !Array.isArray(val);
exports.hasRegexChars = (str) => REGEX_SPECIAL_CHARS.test(str);
exports.isRegexChar = (str) => str.length === 1 && exports.hasRegexChars(str);
exports.escapeRegex = (str) => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, "\\$1");
exports.toPosixSlashes = (str) => str.replace(REGEX_BACKSLASH, "/");
exports.isWindows = () => {
if (typeof navigator !== "undefined" && navigator.platform) {
const platform = navigator.platform.toLowerCase();
return platform === "win32" || platform === "windows";
}
if (typeof process !== "undefined" && process.platform) return process.platform === "win32";
return false;
};
exports.removeBackslashes = (str) => {
return str.replace(REGEX_REMOVE_BACKSLASH, (match) => {
return match === "\\" ? "" : match;
});
};
exports.escapeLast = (input, char, lastIdx) => {
const idx = input.lastIndexOf(char, lastIdx);
if (idx === -1) return input;
if (input[idx - 1] === "\\") return exports.escapeLast(input, char, idx - 1);
return `${input.slice(0, idx)}\\${input.slice(idx)}`;
};
exports.removePrefix = (input, state = {}) => {
let output = input;
if (output.startsWith("./")) {
output = output.slice(2);
state.prefix = "./";
}
return output;
};
exports.wrapOutput = (input, state = {}, options = {}) => {
let output = `${options.contains ? "" : "^"}(?:${input})${options.contains ? "" : "$"}`;
if (state.negated === true) output = `(?:^(?!${output}).*$)`;
return output;
};
exports.basename = (path, { windows } = {}) => {
const segs = path.split(windows ? /[\\/]/ : "/");
const last = segs[segs.length - 1];
if (last === "") return segs[segs.length - 2];
return last;
};
}));
//#endregion
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/scan.js
var require_scan = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const utils = require_utils$1();
const { CHAR_ASTERISK, CHAR_AT, CHAR_BACKWARD_SLASH, CHAR_COMMA, CHAR_DOT, CHAR_EXCLAMATION_MARK, CHAR_FORWARD_SLASH, CHAR_LEFT_CURLY_BRACE, CHAR_LEFT_PARENTHESES, CHAR_LEFT_SQUARE_BRACKET, CHAR_PLUS, CHAR_QUESTION_MARK, CHAR_RIGHT_CURLY_BRACE, CHAR_RIGHT_PARENTHESES, CHAR_RIGHT_SQUARE_BRACKET } = require_constants();
const isPathSeparator = (code) => {
return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;
};
const depth = (token) => {
if (token.isPrefix !== true) token.depth = token.isGlobstar ? Infinity : 1;
};
/**
* Quickly scans a glob pattern and returns an object with a handful of
* useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),
* `glob` (the actual pattern), `negated` (true if the path starts with `!` but not
* with `!(`) and `negatedExtglob` (true if the path starts with `!(`).
*
* ```js
* const pm = require('picomatch');
* console.log(pm.scan('foo/bar/*.js'));
* { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }
* ```
* @param {String} `str`
* @param {Object} `options`
* @return {Object} Returns an object with tokens and regex source string.
* @api public
*/
const scan = (input, options) => {
const opts = options || {};
const length = input.length - 1;
const scanToEnd = opts.parts === true || opts.scanToEnd === true;
const slashes = [];
const tokens = [];
const parts = [];
let str = input;
let index = -1;
let start = 0;
let lastIndex = 0;
let isBrace = false;
let isBracket = false;
let isGlob = false;
let isExtglob = false;
let isGlobstar = false;
let braceEscaped = false;
let backslashes = false;
let negated = false;
let negatedExtglob = false;
let finished = false;
let braces = 0;
let prev;
let code;
let token = {
value: "",
depth: 0,
isGlob: false
};
const eos = () => index >= length;
const peek = () => str.charCodeAt(index + 1);
const advance = () => {
prev = code;
return str.charCodeAt(++index);
};
while (index < length) {
code = advance();
let next;
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
code = advance();
if (code === CHAR_LEFT_CURLY_BRACE) braceEscaped = true;
continue;
}
if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {
braces++;
while (eos() !== true && (code = advance())) {
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
advance();
continue;
}
if (code === CHAR_LEFT_CURLY_BRACE) {
braces++;
continue;
}
if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {
isBrace = token.isBrace = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) continue;
break;
}
if (braceEscaped !== true && code === CHAR_COMMA) {
isBrace = token.isBrace = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) continue;
break;
}
if (code === CHAR_RIGHT_CURLY_BRACE) {
braces--;
if (braces === 0) {
braceEscaped = false;
isBrace = token.isBrace = true;
finished = true;
break;
}
}
}
if (scanToEnd === true) continue;
break;
}
if (code === CHAR_FORWARD_SLASH) {
slashes.push(index);
tokens.push(token);
token = {
value: "",
depth: 0,
isGlob: false
};
if (finished === true) continue;
if (prev === CHAR_DOT && index === start + 1) {
start += 2;
continue;
}
lastIndex = index + 1;
continue;
}
if (opts.noext !== true) {
if ((code === CHAR_PLUS || code === CHAR_AT || code === CHAR_ASTERISK || code === CHAR_QUESTION_MARK || code === CHAR_EXCLAMATION_MARK) === true && peek() === CHAR_LEFT_PARENTHESES) {
isGlob = token.isGlob = true;
isExtglob = token.isExtglob = true;
finished = true;
if (code === CHAR_EXCLAMATION_MARK && index === start) negatedExtglob = true;
if (scanToEnd === true) {
while (eos() !== true && (code = advance())) {
if (code === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
code = advance();
continue;
}
if (code === CHAR_RIGHT_PARENTHESES) {
isGlob = token.isGlob = true;
finished = true;
break;
}
}
continue;
}
break;
}
}
if (code === CHAR_ASTERISK) {
if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) continue;
break;
}
if (code === CHAR_QUESTION_MARK) {
isGlob = token.isGlob = true;
finished = true;
if (scanToEnd === true) continue;
break;
}
if (code === CHAR_LEFT_SQUARE_BRACKET) {
while (eos() !== true && (next = advance())) {
if (next === CHAR_BACKWARD_SLASH) {
backslashes = token.backslashes = true;
advance();
continue;
}
if (next === CHAR_RIGHT_SQUARE_BRACKET) {
isBracket = token.isBracket = true;
isGlob = token.isGlob = true;
finished = true;
break;
}
}
if (scanToEnd === true) continue;
break;
}
if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {
negated = token.negated = true;
start++;
continue;
}
if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {
isGlob = token.isGlob = true;
if (scanToEnd === true) {
while (eos() !== true && (code = advance())) {
if (code === CHAR_LEFT_PARENTHESES) {
backslashes = token.backslashes = true;
code = advance();
continue;
}
if (code === CHAR_RIGHT_PARENTHESES) {
finished = true;
break;
}
}
continue;
}
break;
}
if (isGlob === true) {
finished = true;
if (scanToEnd === true) continue;
break;
}
}
if (opts.noext === true) {
isExtglob = false;
isGlob = false;
}
let base = str;
let prefix = "";
let glob = "";
if (start > 0) {
prefix = str.slice(0, start);
str = str.slice(start);
lastIndex -= start;
}
if (base && isGlob === true && lastIndex > 0) {
base = str.slice(0, lastIndex);
glob = str.slice(lastIndex);
} else if (isGlob === true) {
base = "";
glob = str;
} else base = str;
if (base && base !== "" && base !== "/" && base !== str) {
if (isPathSeparator(base.charCodeAt(base.length - 1))) base = base.slice(0, -1);
}
if (opts.unescape === true) {
if (glob) glob = utils.removeBackslashes(glob);
if (base && backslashes === true) base = utils.removeBackslashes(base);
}
const state = {
prefix,
input,
start,
base,
glob,
isBrace,
isBracket,
isGlob,
isExtglob,
isGlobstar,
negated,
negatedExtglob
};
if (opts.tokens === true) {
state.maxDepth = 0;
if (!isPathSeparator(code)) tokens.push(token);
state.tokens = tokens;
}
if (opts.parts === true || opts.tokens === true) {
let prevIndex;
for (let idx = 0; idx < slashes.length; idx++) {
const n = prevIndex ? prevIndex + 1 : start;
const i = slashes[idx];
const value = input.slice(n, i);
if (opts.tokens) {
if (idx === 0 && start !== 0) {
tokens[idx].isPrefix = true;
tokens[idx].value = prefix;
} else tokens[idx].value = value;
depth(tokens[idx]);
state.maxDepth += tokens[idx].depth;
}
if (idx !== 0 || value !== "") parts.push(value);
prevIndex = i;
}
if (prevIndex && prevIndex + 1 < input.length) {
const value = input.slice(prevIndex + 1);
parts.push(value);
if (opts.tokens) {
tokens[tokens.length - 1].value = value;
depth(tokens[tokens.length - 1]);
state.maxDepth += tokens[tokens.length - 1].depth;
}
}
state.slashes = slashes;
state.parts = parts;
}
return state;
};
module.exports = scan;
}));
//#endregion
//#region ../../node_modules/.pnpm/picomatch@4.0.4/node_modules/picomatch/lib/parse.js
var require_parse$1 = /* @__PURE__ */ __commonJSMin(((exports, module) => {
const constants = require_constants();
const utils = require_utils$1();
/**
* Constants
*/
const { MAX_LENGTH, POSIX_REGEX_SOURCE, REGEX_NON_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_BACKREF, REPLACEMENTS } = constants;
/**
* Helpers
*/
const expandRange = (args, options) => {
if (typeof options.expandRange === "function") return options.expandRange(...args, options);
args.sort();
const value = `[${args.join("-")}]`;
try {
new RegExp(value);
} catch (ex) {
return args.map((v) => utils.escapeRegex(v)).join("..");
}
return value;
};
/**
* Create the message for a syntax error
*/
const syntaxError = (type, char) => {
return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;
};
const splitTopLevel = (input) => {
const parts = [];
let bracket = 0;
let paren = 0;
let quote = 0;
let value = "";
let escaped = false;
for (const ch of input) {
if (escaped === true) {
value += ch;
escaped = false;
continue;
}
if (ch === "\\") {
value += ch;
escaped = true;
continue;
}
if (ch === "\"") {
quote = quote === 1 ? 0 : 1;
value += ch;
continue;
}
if (quote === 0) {
if (ch === "[") bracket++;
else if (ch === "]" && bracket > 0) bracket--;
else if (bracket === 0) {
if (ch === "(") paren++;
else if (ch === ")" && paren > 0) paren--;
else if (ch === "|" && paren === 0) {
parts.push(value);
value = "";
continue;
}
}
}
value += ch;
}
parts.push(value);
return parts;
};
const isPlainBranch = (branch) => {
let escaped = false;
for (const ch of branch) {
if (escaped === true) {
escaped = false;
continue;
}
if (ch === "\\") {
escaped = true;
continue;
}
if (/[?*+@!()[\]{}]/.test(ch)) return false;
}
return true;
};
const normalizeSimpleBranch = (branch) => {
let value = branch.trim();
let changed = true;
while (changed === true) {
changed = false;
if (/^@\([^\\()[\]{}|]+\)$/.test(value)) {
value = value.slice(2, -1);
changed = true;
}
}
if (!isPlainBranch(value)) return;
return value.replace(/\\(.)/g, "$1");
};
const hasRepeatedCharPrefixOverlap = (branches) => {
const values = branches.map(normalizeSimpleBranch).filter(Boolean);
for (let i = 0; i < values.length; i++) for (let j = i + 1; j < values.length; j++) {
const a = values[i];
const b = values[j];
const char = a[0];
if (!char || a !== char.repeat(a.length) || b !== char.repeat(b.length)) continue;
if (a === b || a.startsWith(b) || b.startsWith(a)) return true;
}
return false;
};
const parseRepeatedExtglob = (pattern, requireEnd = true) => {
if (pattern[0] !== "+" && pattern[0] !== "*" || pattern[1] !== "(") return;
let bracket = 0;
let paren = 0;
let quote = 0;
let escaped = false;
for (let i = 1; i < pattern.length; i++) {
const ch = pattern[i];
if (escaped === true) {
escaped = false;
continue;
}
if (ch === "\\") {
escaped = true;
continue;
}
if (ch === "\"") {
quote = quote === 1 ? 0 : 1;
continue;
}
if (quote === 1) continue;
if (ch === "[") {
bracket++;
continue;
}
if (ch === "]" && bracket > 0) {
bracket--;
continue;
}
if (bracket > 0) continue;
if (ch === "(") {
paren++;
continue;
}
if (ch === ")") {
paren--;
if (paren === 0) {
if (requireEnd === true && i !== pattern.length - 1) return;
return {
type: pattern[0],
body: pattern.slice(2, i),
end: i
};
}
}
}
};
const getStarExtglobSequenceOutput = (pattern) => {
let index = 0;
const chars = [];
while (index < pattern.length) {
const match = parseRepeatedExtglob(pattern.slice(index), false);
if (!match || match.type !== "*") return;
const branches = splitTopLevel(match.body).map((branch) => branch.trim());
if (branches.length !== 1) return;
const branch = normalizeSimpleBranch(branches[0]);
if (!branch || branch.length !== 1) return;
chars.push(branch);
index += match.end + 1;
}
if (chars.length < 1) return;
return `${chars.length === 1 ? utils.escapeRegex(chars[0]) : `[${chars.map((ch) => utils.escapeRegex(ch)).join("")}]`}*`;
};
const repeatedExtglobRecursion = (pattern) => {
let depth = 0;
let value = pattern.trim();
let match = parseRepeatedExtglob(value);
while (match) {
depth++;
value = match.body.trim();
match = parseRepeatedExtglob(value);
}
return depth;
};
const analyzeRepeatedExtglob = (body, options) => {
if (options.maxExtglobRecursion === false) return { risky: false };
const max = typeof options.maxExtglobRecursion === "number" ? options.maxExtglobRecursion : constants.DEFAULT_MAX_EXTGLOB_RECURSION;
const branches = splitTopLevel(body).map((branch) => branch.trim());
if (branches.length > 1) {
if (branches.some((branch) => branch === "") || branches.some((branch) => /^[*?]+$/.test(branch)) || hasRepeatedCharPrefixOverlap(branches)) return { risky: true };
}
for (const branch of branches) {
const safeOutput = getStarExtglobSequenceOutput(branch);
if (safeOutput) return {
risky: true,
safeOutput
};
if (repeatedExtglobRecursion(branch) > max) return { risky: true };
}
return { risky: false };
};
/**
* Parse the given input string.
* @param {String} input
* @param {Object} options
* @return {Object}
*/
const parse = (input, options) => {
if (typeof input !== "string") throw new TypeError("Expected a string");
input = REPLACEMENTS[input] || input;
const opts = { ...options };
const max = typeof opts.maxLength === "number" ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;
let len = input.length;
if (len > max) throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);
const bos = {
type: "bos",
value: "",
output: opts.prepend || ""
};
const tokens = [bos];
const capture = opts.capture ? "" : "?:";
const PLATFORM_CHARS = constants.globChars(opts.windows);
const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS);
const { DOT_LITERAL, PLUS_LITERAL, SLASH_LITERAL, ONE_CHAR, DOTS_SLASH, NO_DOT, NO_DOT_SLASH, NO_DOTS_SLASH, QMARK, QMARK_NO_DOT, STAR, START_ANCHOR } = PLATFORM_CHARS;
const globstar = (opts) => {
return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;
};
const nodot = opts.dot ? "" : NO_DOT;
const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;
let star = opts.bash === true ? globstar(opts) : STAR;
if (opts.capture) star = `(${star})`;
if (typeof opts.noext === "boolean") opts.noextglob = opts.noext;
const state = {
input,
index: -1,
start: 0,
dot: opts.dot === true,
consumed: "",
output: "",
prefix: "",
backtrack: false,
negated: false,
brackets: 0,
braces: 0,
parens: 0,
quotes: 0,
globstar: false,
tokens
};
input = utils.removePrefix(input, state);
len = input.length;
const extglobs = [];
const braces = [];
const stack = [];
let prev = bos;
let value;
/**
* Tokenizing helpers
*/
const eos = () => state.index === len - 1;
const peek = state.peek = (n = 1) => input[state.index + n];
const advance = state.advance = () => input[++state.index] || "";
const remaining = () => input.slice(state.index + 1);
const consume = (value = "", num = 0) => {
state.consumed += value;
state.index += num;
};
const append = (token) => {
state.output += token.output != null ? token.output : token.value;
consume(token.value);
};
const negate = () => {
let count = 1;
while (peek() === "!" && (peek(2) !== "(" || peek(3) === "?")) {
advance();
state.start++;
count++;
}
if (count % 2 === 0) return false;
state.negated = true;
state.start++;
return true;
};
const increment = (type) => {
state[type]++;
stack.push(type);
};
const decrement = (type) => {
state[type]--;
stack.pop();
};
/**
* Push tokens onto the tokens array. This helper speeds up
* tokenizing by 1) helping us avoid backtracking as much as possible,
* and 2) helping us avoid creating extra tokens when consecutive
* characters are plain text. This improves performance and simplifies
* lookbehinds.
*/
const push = (tok) => {
if (prev.type === "globstar") {
const isBrace = state.braces > 0 && (tok.type === "comma" || tok.type === "brace");
const isExtglob = tok.extglob === true || extglobs.length && (tok.type === "pipe" || tok.type === "paren");
if (tok.type !== "slash" && tok.type !== "paren" && !isBrace && !isExtglob) {
state.output = state.output.slice(0, -prev.output.length);
prev.type = "star";
prev.value = "*";
prev.output = star;
state.output += prev.output;
}
}
if (extglobs.length && tok.type !== "paren") extglobs[extglobs.length - 1].inner += tok.value;
if (tok.value || tok.output) append(tok);
if (prev && prev.type === "text" && tok.type === "text") {
prev.output = (prev.output || prev.value) + tok.value;
prev.value += tok.value;
return;
}
tok.prev = prev;
tokens.push(tok);
prev = tok;
};
const extglobOpen = (type, value) => {
const token = {
...EXTGLOB_CHARS[value],
conditions: 1,
inner: ""
};
token.prev = prev;
token.parens = state.parens;
token.output = state.output;
token.startIndex = state.index;
token.tokensIndex = tokens.length;
const output = (opts.capture ? "(" : "") + token.open;
increment("parens");
push({
type,
value,
output: state.output ? "" : ONE_CHAR
});
push({
type: "paren",
extglob: true,
value: advance(),
output
});
extglobs.push(token);
};
const extglobClose = (token) => {
const literal = input.slice(token.startIndex, state.index + 1);
const analysis = analyzeRepeatedExtglob(input.slice(token.startIndex + 2, state.index), opts);
if ((token.type === "plus" || token.type === "star") && analysis.risky) {
const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : void 0;
const open = tokens[token.tokensIndex];
open.type = "text";
open.value = literal;
open.output = safeOutput || utils.escapeRegex(literal);
for (let i = token.tokensIndex + 1; i < tokens.length; i++) {
tokens[i].value = "";
tokens[i].output = "";
delete tokens[i].suffix;
}
state.output = token.output + open.output;
state.backtrack = true;
push({
type: "paren",
extglob: true,
value,
output: ""
});
decrement("parens");
return;
}
let output = token.close + (opts.capture ? ")" : "");
let rest;
if (token.type === "negate") {
let extglobStar = star;
if (token.inner && token.inner.length > 1 && token.inner.includes("/")) extglobStar = globstar(opts);
if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) output = token.close = `)$))${extglobStar}`;
if (token.inner.includes("*") && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) output = token.close = `)${parse(rest, {
...options,
fastpaths: false
}).output})${extglobStar})`;
if (token.prev.type === "bos") state.negatedExtglob = true;
}
push({
type: "paren",
extglob: true,
value,
output
});
decrement("parens");
};
/**
* Fast paths
*/
if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {
let backslashes = false;
let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {
if (first === "\\") {
backslashes = true;
return m;
}
if (first === "?") {
if (esc) return esc + first + (rest ? QMARK.repeat(rest.length) : "");
if (index === 0) return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : "");
return QMARK.repeat(chars.length);
}
if (first === ".") return DOT_LITERAL.repeat(chars.length);
if (first === "*") {
if (esc) return esc + first + (rest ? star : "");
return star;
}
return esc ? m : `\\${m}`;
});
if (backslashes === true) if (opts.unescape === true) output = output.replace(/\\/g, "");
else output = output.replace(/\\+/g, (m) => {
return m.length % 2 === 0 ? "\\\\" : m ? "\\" : "";
});
if (output === input && opts.contains === true) {
state.output = input;
return state;
}
state.output = utils.wrapOutput(output, state, options);
return state;
}
/**
* Tokenize input until we reach end-of-string
*/
while (!eos()) {
value = advance();
if (value === "\0") continue;
/**
* Escaped characters
*/
if (value === "\\") {
const next = peek();
if (next === "/" && opts.bash !== true) continue;
if (next === "." || next === ";") continue;
if (!next) {
value += "\\";
push({
type: "text",
value
});
continue;
}
const match = /^\\+/.exec(remaining());
let slashes = 0;
if (match && match[0].length > 2) {
slashes = match[0].length;
state.index += slashes;
if (slashes % 2 !== 0) value += "\\";
}
if (opts.unescape === true) value = advance();
else value += advance();
if (state.brackets === 0) {
push({
type: "text",
value
});
continue;
}
}
/**
* If we're inside a regex character class, continue
* until we reach the closing bracket.
*/
if (state.brackets > 0 && (value !== "]" || prev.value === "[" || prev.value === "[^")) {
if (opts.posix !== false && value === ":") {
const inner = prev.value.slice(1);
if (inner.includes("[")) {
prev.posix = true;
if (inner.includes(":")) {
const idx = prev.value.lastIndexOf("[");
const pre = prev.value.slice(0, idx);
const posix = POSIX_REGEX_SOURCE[prev.value.slice(idx + 2)];
if (posix) {
prev.value = pre + posix;
state.backtrack = true;
advance();
if (!bos.output && tokens.indexOf(prev) === 1) bos.output = ONE_CHAR;
continue;
}
}
}
}
if (value === "[" && peek() !== ":" || value === "-" && peek() === "]") value = `\\${value}`;
if (value === "]" && (prev.value === "[" || prev.value === "[^")) value = `\\${value}`;
if (opts.posix === true && value === "!" && prev.value === "[") value = "^";
prev.value += value;
append({ value });
continue;
}
/**
* If we're inside a quoted string, continue
* until we reach the closing double quote.
*/
if (state.quotes === 1 && value !== "\"") {
value = utils.escapeRegex(value);
prev.value += value;
append({ value });
continue;
}
/**
* Double quotes
*/
if (value === "\"") {
state.quotes = state.quotes === 1 ? 0 : 1;
if (opts.keepQuotes === true) push({
type: "text",
value
});
continue;
}
/**
* Parentheses
*/
if (value === "(") {
increment("parens");
push({
type: "paren",
value
});
continue;
}
if (value === ")") {
if (state.parens === 0 && opts.strictBrackets === true) throw new SyntaxError(syntaxError("opening", "("));
const extglob = extglobs[extglobs.length - 1];
if (extglob && state.parens === extglob.parens + 1) {
extglobClose(extglobs.pop());
continue;
}
push({
type: "paren",
value,
output: state.parens ? ")" : "\\)"
});
decrement("parens");
continue;
}
/**
* Square brackets
*/
if (value === "[") {
if (opts.nobracket === true || !remaining().includes("]")) {
if (opts.nobracket !== true && opts.strictBrackets === true) throw new SyntaxError(syntaxError("closing", "]"));
value = `\\${value}`;
} else increment("brackets");
push({
type: "bracket",
value
});
continue;
}
if (value === "]") {
if (opts.nobracket === true || prev && prev.type === "bracket" && prev.value.length === 1) {
push({
type: "text",
value,
output: `\\${value}`
});
continue;
}
if (state.brackets === 0) {
if (opts.strictBrackets === true) throw new SyntaxError(syntaxError("opening", "["));
push({
type: "text",
value,
output: `\\${value}`
});
continue;
}
decrement("brackets");
const prevValue = prev.value.slice(1);
if (prev.posix !== true && prevValue[0] === "^" && !prevValue.includes("/")) value = `/${value}`;
prev.value += value;
append({ value });
if (opts.literalBrackets === false || utils.hasRegexChar