Changeset 0c6b92a for imaps-frontend/node_modules/rollup/dist/shared
- Timestamp:
- 12/12/24 17:06:06 (5 weeks ago)
- Branches:
- main
- Parents:
- d565449
- Location:
- imaps-frontend/node_modules/rollup/dist/shared
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
imaps-frontend/node_modules/rollup/dist/shared/fsevents-importer.js
rd565449 r0c6b92a 1 1 /* 2 2 @license 3 Rollup.js v4.2 0.04 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d53 Rollup.js v4.27.4 4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 5 5 6 6 https://github.com/rollup/rollup -
imaps-frontend/node_modules/rollup/dist/shared/index.js
rd565449 r0c6b92a 1 1 /* 2 2 @license 3 Rollup.js v4.2 0.04 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d53 Rollup.js v4.27.4 4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 5 5 6 6 https://github.com/rollup/rollup … … 11 11 12 12 const rollup = require('./rollup.js'); 13 const require$$0$1 = require('fs'); 13 const require$$0$1 = require('path'); 14 const require$$0$2 = require('fs'); 14 15 const require$$2 = require('util'); 15 16 const require$$1 = require('stream'); 16 const require$$0$2 = require('path');17 17 const require$$2$1 = require('os'); 18 18 const fseventsImporter = require('./fsevents-importer.js'); 19 19 const require$$0$3 = require('events'); 20 20 21 var chokidar = {}; 22 23 const fs$3 = require$$0$1; 24 const { Readable } = require$$1; 25 const sysPath$3 = require$$0$2; 26 const { promisify: promisify$3 } = require$$2; 27 const picomatch$1 = rollup.picomatch; 28 29 const readdir$1 = promisify$3(fs$3.readdir); 30 const stat$3 = promisify$3(fs$3.stat); 31 const lstat$2 = promisify$3(fs$3.lstat); 32 const realpath$1 = promisify$3(fs$3.realpath); 33 34 /** 35 * @typedef {Object} EntryInfo 36 * @property {String} path 37 * @property {String} fullPath 38 * @property {fs.Stats=} stats 39 * @property {fs.Dirent=} dirent 40 * @property {String} basename 41 */ 42 43 const BANG$2 = '!'; 44 const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR'; 45 const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]); 46 const FILE_TYPE = 'files'; 47 const DIR_TYPE = 'directories'; 48 const FILE_DIR_TYPE = 'files_directories'; 49 const EVERYTHING_TYPE = 'all'; 50 const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]; 51 52 const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code); 53 const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10)); 54 const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5)); 55 56 const normalizeFilter = filter => { 57 if (filter === undefined) return; 58 if (typeof filter === 'function') return filter; 59 60 if (typeof filter === 'string') { 61 const glob = picomatch$1(filter.trim()); 62 return entry => glob(entry.basename); 63 } 64 65 if (Array.isArray(filter)) { 66 const positive = []; 67 const negative = []; 68 for (const item of filter) { 69 const trimmed = item.trim(); 70 if (trimmed.charAt(0) === BANG$2) { 71 negative.push(picomatch$1(trimmed.slice(1))); 72 } else { 73 positive.push(picomatch$1(trimmed)); 74 } 75 } 76 77 if (negative.length > 0) { 78 if (positive.length > 0) { 79 return entry => 80 positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename)); 81 } 82 return entry => !negative.some(f => f(entry.basename)); 83 } 84 return entry => positive.some(f => f(entry.basename)); 85 } 86 }; 87 88 class ReaddirpStream extends Readable { 89 static get defaultOptions() { 90 return { 91 root: '.', 92 /* eslint-disable no-unused-vars */ 93 fileFilter: (path) => true, 94 directoryFilter: (path) => true, 95 /* eslint-enable no-unused-vars */ 96 type: FILE_TYPE, 97 lstat: false, 98 depth: 2147483648, 99 alwaysStat: false 100 }; 101 } 102 103 constructor(options = {}) { 104 super({ 105 objectMode: true, 106 autoDestroy: true, 107 highWaterMark: options.highWaterMark || 4096 108 }); 109 const opts = { ...ReaddirpStream.defaultOptions, ...options }; 110 const { root, type } = opts; 111 112 this._fileFilter = normalizeFilter(opts.fileFilter); 113 this._directoryFilter = normalizeFilter(opts.directoryFilter); 114 115 const statMethod = opts.lstat ? lstat$2 : stat$3; 116 // Use bigint stats if it's windows and stat() supports options (node 10+). 117 if (wantBigintFsStats) { 118 this._stat = path => statMethod(path, { bigint: true }); 119 } else { 120 this._stat = statMethod; 121 } 122 123 this._maxDepth = opts.depth; 124 this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); 125 this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); 126 this._wantsEverything = type === EVERYTHING_TYPE; 127 this._root = sysPath$3.resolve(root); 128 this._isDirent = ('Dirent' in fs$3) && !opts.alwaysStat; 129 this._statsProp = this._isDirent ? 'dirent' : 'stats'; 130 this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent }; 131 132 // Launch stream with one parent, the root dir. 133 this.parents = [this._exploreDir(root, 1)]; 134 this.reading = false; 135 this.parent = undefined; 136 } 137 138 async _read(batch) { 139 if (this.reading) return; 140 this.reading = true; 141 142 try { 143 while (!this.destroyed && batch > 0) { 144 const { path, depth, files = [] } = this.parent || {}; 145 146 if (files.length > 0) { 147 const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path)); 148 for (const entry of await Promise.all(slice)) { 149 if (this.destroyed) return; 150 151 const entryType = await this._getEntryType(entry); 152 if (entryType === 'directory' && this._directoryFilter(entry)) { 153 if (depth <= this._maxDepth) { 154 this.parents.push(this._exploreDir(entry.fullPath, depth + 1)); 155 } 156 157 if (this._wantsDir) { 158 this.push(entry); 159 batch--; 160 } 161 } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) { 162 if (this._wantsFile) { 163 this.push(entry); 164 batch--; 165 } 166 } 167 } 168 } else { 169 const parent = this.parents.pop(); 170 if (!parent) { 171 this.push(null); 172 break; 173 } 174 this.parent = await parent; 175 if (this.destroyed) return; 176 } 177 } 178 } catch (error) { 179 this.destroy(error); 180 } finally { 181 this.reading = false; 182 } 183 } 184 185 async _exploreDir(path, depth) { 186 let files; 187 try { 188 files = await readdir$1(path, this._rdOptions); 189 } catch (error) { 190 this._onError(error); 191 } 192 return { files, depth, path }; 193 } 194 195 async _formatEntry(dirent, path) { 196 let entry; 197 try { 198 const basename = this._isDirent ? dirent.name : dirent; 199 const fullPath = sysPath$3.resolve(sysPath$3.join(path, basename)); 200 entry = { path: sysPath$3.relative(this._root, fullPath), fullPath, basename }; 201 entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath); 202 } catch (err) { 203 this._onError(err); 204 } 205 return entry; 206 } 207 208 _onError(err) { 209 if (isNormalFlowError(err) && !this.destroyed) { 210 this.emit('warn', err); 211 } else { 212 this.destroy(err); 213 } 214 } 215 216 async _getEntryType(entry) { 217 // entry may be undefined, because a warning or an error were emitted 218 // and the statsProp is undefined 219 const stats = entry && entry[this._statsProp]; 220 if (!stats) { 221 return; 222 } 223 if (stats.isFile()) { 224 return 'file'; 225 } 226 if (stats.isDirectory()) { 227 return 'directory'; 228 } 229 if (stats && stats.isSymbolicLink()) { 230 const full = entry.fullPath; 231 try { 232 const entryRealPath = await realpath$1(full); 233 const entryRealPathStats = await lstat$2(entryRealPath); 234 if (entryRealPathStats.isFile()) { 235 return 'file'; 236 } 237 if (entryRealPathStats.isDirectory()) { 238 const len = entryRealPath.length; 239 if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath$3.sep) { 240 const recursiveError = new Error( 241 `Circular symlink detected: "${full}" points to "${entryRealPath}"` 242 ); 243 recursiveError.code = RECURSIVE_ERROR_CODE; 244 return this._onError(recursiveError); 245 } 246 return 'directory'; 247 } 248 } catch (error) { 249 this._onError(error); 250 } 251 } 252 } 253 254 _includeAsFile(entry) { 255 const stats = entry && entry[this._statsProp]; 256 257 return stats && this._wantsEverything && !stats.isDirectory(); 258 } 21 var chokidar$1 = {}; 22 23 var utils$2 = {}; 24 25 var constants$3; 26 var hasRequiredConstants$3; 27 28 function requireConstants$3 () { 29 if (hasRequiredConstants$3) return constants$3; 30 hasRequiredConstants$3 = 1; 31 32 const path = require$$0$1; 33 const WIN_SLASH = '\\\\/'; 34 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 35 36 /** 37 * Posix glob regex 38 */ 39 40 const DOT_LITERAL = '\\.'; 41 const PLUS_LITERAL = '\\+'; 42 const QMARK_LITERAL = '\\?'; 43 const SLASH_LITERAL = '\\/'; 44 const ONE_CHAR = '(?=.)'; 45 const QMARK = '[^/]'; 46 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 47 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 48 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 49 const NO_DOT = `(?!${DOT_LITERAL})`; 50 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 51 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 52 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 53 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 54 const STAR = `${QMARK}*?`; 55 56 const POSIX_CHARS = { 57 DOT_LITERAL, 58 PLUS_LITERAL, 59 QMARK_LITERAL, 60 SLASH_LITERAL, 61 ONE_CHAR, 62 QMARK, 63 END_ANCHOR, 64 DOTS_SLASH, 65 NO_DOT, 66 NO_DOTS, 67 NO_DOT_SLASH, 68 NO_DOTS_SLASH, 69 QMARK_NO_DOT, 70 STAR, 71 START_ANCHOR 72 }; 73 74 /** 75 * Windows glob regex 76 */ 77 78 const WINDOWS_CHARS = { 79 ...POSIX_CHARS, 80 81 SLASH_LITERAL: `[${WIN_SLASH}]`, 82 QMARK: WIN_NO_SLASH, 83 STAR: `${WIN_NO_SLASH}*?`, 84 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, 85 NO_DOT: `(?!${DOT_LITERAL})`, 86 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 87 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, 88 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 89 QMARK_NO_DOT: `[^.${WIN_SLASH}]`, 90 START_ANCHOR: `(?:^|[${WIN_SLASH}])`, 91 END_ANCHOR: `(?:[${WIN_SLASH}]|$)` 92 }; 93 94 /** 95 * POSIX Bracket Regex 96 */ 97 98 const POSIX_REGEX_SOURCE = { 99 alnum: 'a-zA-Z0-9', 100 alpha: 'a-zA-Z', 101 ascii: '\\x00-\\x7F', 102 blank: ' \\t', 103 cntrl: '\\x00-\\x1F\\x7F', 104 digit: '0-9', 105 graph: '\\x21-\\x7E', 106 lower: 'a-z', 107 print: '\\x20-\\x7E ', 108 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', 109 space: ' \\t\\r\\n\\v\\f', 110 upper: 'A-Z', 111 word: 'A-Za-z0-9_', 112 xdigit: 'A-Fa-f0-9' 113 }; 114 115 constants$3 = { 116 MAX_LENGTH: 1024 * 64, 117 POSIX_REGEX_SOURCE, 118 119 // regular expressions 120 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, 121 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, 122 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, 123 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, 124 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, 125 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, 126 127 // Replace globs with equivalent patterns to reduce parsing time. 128 REPLACEMENTS: { 129 '***': '*', 130 '**/**': '**', 131 '**/**/**': '**' 132 }, 133 134 // Digits 135 CHAR_0: 48, /* 0 */ 136 CHAR_9: 57, /* 9 */ 137 138 // Alphabet chars. 139 CHAR_UPPERCASE_A: 65, /* A */ 140 CHAR_LOWERCASE_A: 97, /* a */ 141 CHAR_UPPERCASE_Z: 90, /* Z */ 142 CHAR_LOWERCASE_Z: 122, /* z */ 143 144 CHAR_LEFT_PARENTHESES: 40, /* ( */ 145 CHAR_RIGHT_PARENTHESES: 41, /* ) */ 146 147 CHAR_ASTERISK: 42, /* * */ 148 149 // Non-alphabetic chars. 150 CHAR_AMPERSAND: 38, /* & */ 151 CHAR_AT: 64, /* @ */ 152 CHAR_BACKWARD_SLASH: 92, /* \ */ 153 CHAR_CARRIAGE_RETURN: 13, /* \r */ 154 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ 155 CHAR_COLON: 58, /* : */ 156 CHAR_COMMA: 44, /* , */ 157 CHAR_DOT: 46, /* . */ 158 CHAR_DOUBLE_QUOTE: 34, /* " */ 159 CHAR_EQUAL: 61, /* = */ 160 CHAR_EXCLAMATION_MARK: 33, /* ! */ 161 CHAR_FORM_FEED: 12, /* \f */ 162 CHAR_FORWARD_SLASH: 47, /* / */ 163 CHAR_GRAVE_ACCENT: 96, /* ` */ 164 CHAR_HASH: 35, /* # */ 165 CHAR_HYPHEN_MINUS: 45, /* - */ 166 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ 167 CHAR_LEFT_CURLY_BRACE: 123, /* { */ 168 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ 169 CHAR_LINE_FEED: 10, /* \n */ 170 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ 171 CHAR_PERCENT: 37, /* % */ 172 CHAR_PLUS: 43, /* + */ 173 CHAR_QUESTION_MARK: 63, /* ? */ 174 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ 175 CHAR_RIGHT_CURLY_BRACE: 125, /* } */ 176 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ 177 CHAR_SEMICOLON: 59, /* ; */ 178 CHAR_SINGLE_QUOTE: 39, /* ' */ 179 CHAR_SPACE: 32, /* */ 180 CHAR_TAB: 9, /* \t */ 181 CHAR_UNDERSCORE: 95, /* _ */ 182 CHAR_VERTICAL_LINE: 124, /* | */ 183 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ 184 185 SEP: path.sep, 186 187 /** 188 * Create EXTGLOB_CHARS 189 */ 190 191 extglobChars(chars) { 192 return { 193 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, 194 '?': { type: 'qmark', open: '(?:', close: ')?' }, 195 '+': { type: 'plus', open: '(?:', close: ')+' }, 196 '*': { type: 'star', open: '(?:', close: ')*' }, 197 '@': { type: 'at', open: '(?:', close: ')' } 198 }; 199 }, 200 201 /** 202 * Create GLOB_CHARS 203 */ 204 205 globChars(win32) { 206 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; 207 } 208 }; 209 return constants$3; 259 210 } 260 211 261 /** 262 * @typedef {Object} ReaddirpArguments 263 * @property {Function=} fileFilter 264 * @property {Function=} directoryFilter 265 * @property {String=} type 266 * @property {Number=} depth 267 * @property {String=} root 268 * @property {Boolean=} lstat 269 * @property {Boolean=} bigint 270 */ 271 272 /** 273 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively. 274 * @param {String} root Root directory 275 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth 276 */ 277 const readdirp$1 = (root, options = {}) => { 278 let type = options.entryType || options.type; 279 if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility 280 if (type) options.type = type; 281 if (!root) { 282 throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)'); 283 } else if (typeof root !== 'string') { 284 throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)'); 285 } else if (type && !ALL_TYPES.includes(type)) { 286 throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`); 287 } 288 289 options.root = root; 290 return new ReaddirpStream(options); 291 }; 292 293 const readdirpPromise = (root, options = {}) => { 294 return new Promise((resolve, reject) => { 295 const files = []; 296 readdirp$1(root, options) 297 .on('data', entry => files.push(entry)) 298 .on('end', () => resolve(files)) 299 .on('error', error => reject(error)); 300 }); 301 }; 302 303 readdirp$1.promise = readdirpPromise; 304 readdirp$1.ReaddirpStream = ReaddirpStream; 305 readdirp$1.default = readdirp$1; 306 307 var readdirp_1 = readdirp$1; 308 309 var anymatch$2 = {exports: {}}; 212 var hasRequiredUtils$2; 213 214 function requireUtils$2 () { 215 if (hasRequiredUtils$2) return utils$2; 216 hasRequiredUtils$2 = 1; 217 (function (exports) { 218 219 const path = require$$0$1; 220 const win32 = process.platform === 'win32'; 221 const { 222 REGEX_BACKSLASH, 223 REGEX_REMOVE_BACKSLASH, 224 REGEX_SPECIAL_CHARS, 225 REGEX_SPECIAL_CHARS_GLOBAL 226 } = /*@__PURE__*/ requireConstants$3(); 227 228 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 229 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); 230 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); 231 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); 232 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); 233 234 exports.removeBackslashes = str => { 235 return str.replace(REGEX_REMOVE_BACKSLASH, match => { 236 return match === '\\' ? '' : match; 237 }); 238 }; 239 240 exports.supportsLookbehinds = () => { 241 const segs = process.version.slice(1).split('.').map(Number); 242 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { 243 return true; 244 } 245 return false; 246 }; 247 248 exports.isWindows = options => { 249 if (options && typeof options.windows === 'boolean') { 250 return options.windows; 251 } 252 return win32 === true || path.sep === '\\'; 253 }; 254 255 exports.escapeLast = (input, char, lastIdx) => { 256 const idx = input.lastIndexOf(char, lastIdx); 257 if (idx === -1) return input; 258 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); 259 return `${input.slice(0, idx)}\\${input.slice(idx)}`; 260 }; 261 262 exports.removePrefix = (input, state = {}) => { 263 let output = input; 264 if (output.startsWith('./')) { 265 output = output.slice(2); 266 state.prefix = './'; 267 } 268 return output; 269 }; 270 271 exports.wrapOutput = (input, state = {}, options = {}) => { 272 const prepend = options.contains ? '' : '^'; 273 const append = options.contains ? '' : '$'; 274 275 let output = `${prepend}(?:${input})${append}`; 276 if (state.negated === true) { 277 output = `(?:^(?!${output}).*$)`; 278 } 279 return output; 280 }; 281 } (utils$2)); 282 return utils$2; 283 } 284 285 var scan_1$1; 286 var hasRequiredScan$1; 287 288 function requireScan$1 () { 289 if (hasRequiredScan$1) return scan_1$1; 290 hasRequiredScan$1 = 1; 291 292 const utils = /*@__PURE__*/ requireUtils$2(); 293 const { 294 CHAR_ASTERISK, /* * */ 295 CHAR_AT, /* @ */ 296 CHAR_BACKWARD_SLASH, /* \ */ 297 CHAR_COMMA, /* , */ 298 CHAR_DOT, /* . */ 299 CHAR_EXCLAMATION_MARK, /* ! */ 300 CHAR_FORWARD_SLASH, /* / */ 301 CHAR_LEFT_CURLY_BRACE, /* { */ 302 CHAR_LEFT_PARENTHESES, /* ( */ 303 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 304 CHAR_PLUS, /* + */ 305 CHAR_QUESTION_MARK, /* ? */ 306 CHAR_RIGHT_CURLY_BRACE, /* } */ 307 CHAR_RIGHT_PARENTHESES, /* ) */ 308 CHAR_RIGHT_SQUARE_BRACKET /* ] */ 309 } = /*@__PURE__*/ requireConstants$3(); 310 311 const isPathSeparator = code => { 312 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; 313 }; 314 315 const depth = token => { 316 if (token.isPrefix !== true) { 317 token.depth = token.isGlobstar ? Infinity : 1; 318 } 319 }; 320 321 /** 322 * Quickly scans a glob pattern and returns an object with a handful of 323 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), 324 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not 325 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). 326 * 327 * ```js 328 * const pm = require('picomatch'); 329 * console.log(pm.scan('foo/bar/*.js')); 330 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } 331 * ``` 332 * @param {String} `str` 333 * @param {Object} `options` 334 * @return {Object} Returns an object with tokens and regex source string. 335 * @api public 336 */ 337 338 const scan = (input, options) => { 339 const opts = options || {}; 340 341 const length = input.length - 1; 342 const scanToEnd = opts.parts === true || opts.scanToEnd === true; 343 const slashes = []; 344 const tokens = []; 345 const parts = []; 346 347 let str = input; 348 let index = -1; 349 let start = 0; 350 let lastIndex = 0; 351 let isBrace = false; 352 let isBracket = false; 353 let isGlob = false; 354 let isExtglob = false; 355 let isGlobstar = false; 356 let braceEscaped = false; 357 let backslashes = false; 358 let negated = false; 359 let negatedExtglob = false; 360 let finished = false; 361 let braces = 0; 362 let prev; 363 let code; 364 let token = { value: '', depth: 0, isGlob: false }; 365 366 const eos = () => index >= length; 367 const peek = () => str.charCodeAt(index + 1); 368 const advance = () => { 369 prev = code; 370 return str.charCodeAt(++index); 371 }; 372 373 while (index < length) { 374 code = advance(); 375 let next; 376 377 if (code === CHAR_BACKWARD_SLASH) { 378 backslashes = token.backslashes = true; 379 code = advance(); 380 381 if (code === CHAR_LEFT_CURLY_BRACE) { 382 braceEscaped = true; 383 } 384 continue; 385 } 386 387 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { 388 braces++; 389 390 while (eos() !== true && (code = advance())) { 391 if (code === CHAR_BACKWARD_SLASH) { 392 backslashes = token.backslashes = true; 393 advance(); 394 continue; 395 } 396 397 if (code === CHAR_LEFT_CURLY_BRACE) { 398 braces++; 399 continue; 400 } 401 402 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { 403 isBrace = token.isBrace = true; 404 isGlob = token.isGlob = true; 405 finished = true; 406 407 if (scanToEnd === true) { 408 continue; 409 } 410 411 break; 412 } 413 414 if (braceEscaped !== true && code === CHAR_COMMA) { 415 isBrace = token.isBrace = true; 416 isGlob = token.isGlob = true; 417 finished = true; 418 419 if (scanToEnd === true) { 420 continue; 421 } 422 423 break; 424 } 425 426 if (code === CHAR_RIGHT_CURLY_BRACE) { 427 braces--; 428 429 if (braces === 0) { 430 braceEscaped = false; 431 isBrace = token.isBrace = true; 432 finished = true; 433 break; 434 } 435 } 436 } 437 438 if (scanToEnd === true) { 439 continue; 440 } 441 442 break; 443 } 444 445 if (code === CHAR_FORWARD_SLASH) { 446 slashes.push(index); 447 tokens.push(token); 448 token = { value: '', depth: 0, isGlob: false }; 449 450 if (finished === true) continue; 451 if (prev === CHAR_DOT && index === (start + 1)) { 452 start += 2; 453 continue; 454 } 455 456 lastIndex = index + 1; 457 continue; 458 } 459 460 if (opts.noext !== true) { 461 const isExtglobChar = code === CHAR_PLUS 462 || code === CHAR_AT 463 || code === CHAR_ASTERISK 464 || code === CHAR_QUESTION_MARK 465 || code === CHAR_EXCLAMATION_MARK; 466 467 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { 468 isGlob = token.isGlob = true; 469 isExtglob = token.isExtglob = true; 470 finished = true; 471 if (code === CHAR_EXCLAMATION_MARK && index === start) { 472 negatedExtglob = true; 473 } 474 475 if (scanToEnd === true) { 476 while (eos() !== true && (code = advance())) { 477 if (code === CHAR_BACKWARD_SLASH) { 478 backslashes = token.backslashes = true; 479 code = advance(); 480 continue; 481 } 482 483 if (code === CHAR_RIGHT_PARENTHESES) { 484 isGlob = token.isGlob = true; 485 finished = true; 486 break; 487 } 488 } 489 continue; 490 } 491 break; 492 } 493 } 494 495 if (code === CHAR_ASTERISK) { 496 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; 497 isGlob = token.isGlob = true; 498 finished = true; 499 500 if (scanToEnd === true) { 501 continue; 502 } 503 break; 504 } 505 506 if (code === CHAR_QUESTION_MARK) { 507 isGlob = token.isGlob = true; 508 finished = true; 509 510 if (scanToEnd === true) { 511 continue; 512 } 513 break; 514 } 515 516 if (code === CHAR_LEFT_SQUARE_BRACKET) { 517 while (eos() !== true && (next = advance())) { 518 if (next === CHAR_BACKWARD_SLASH) { 519 backslashes = token.backslashes = true; 520 advance(); 521 continue; 522 } 523 524 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 525 isBracket = token.isBracket = true; 526 isGlob = token.isGlob = true; 527 finished = true; 528 break; 529 } 530 } 531 532 if (scanToEnd === true) { 533 continue; 534 } 535 536 break; 537 } 538 539 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { 540 negated = token.negated = true; 541 start++; 542 continue; 543 } 544 545 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { 546 isGlob = token.isGlob = true; 547 548 if (scanToEnd === true) { 549 while (eos() !== true && (code = advance())) { 550 if (code === CHAR_LEFT_PARENTHESES) { 551 backslashes = token.backslashes = true; 552 code = advance(); 553 continue; 554 } 555 556 if (code === CHAR_RIGHT_PARENTHESES) { 557 finished = true; 558 break; 559 } 560 } 561 continue; 562 } 563 break; 564 } 565 566 if (isGlob === true) { 567 finished = true; 568 569 if (scanToEnd === true) { 570 continue; 571 } 572 573 break; 574 } 575 } 576 577 if (opts.noext === true) { 578 isExtglob = false; 579 isGlob = false; 580 } 581 582 let base = str; 583 let prefix = ''; 584 let glob = ''; 585 586 if (start > 0) { 587 prefix = str.slice(0, start); 588 str = str.slice(start); 589 lastIndex -= start; 590 } 591 592 if (base && isGlob === true && lastIndex > 0) { 593 base = str.slice(0, lastIndex); 594 glob = str.slice(lastIndex); 595 } else if (isGlob === true) { 596 base = ''; 597 glob = str; 598 } else { 599 base = str; 600 } 601 602 if (base && base !== '' && base !== '/' && base !== str) { 603 if (isPathSeparator(base.charCodeAt(base.length - 1))) { 604 base = base.slice(0, -1); 605 } 606 } 607 608 if (opts.unescape === true) { 609 if (glob) glob = utils.removeBackslashes(glob); 610 611 if (base && backslashes === true) { 612 base = utils.removeBackslashes(base); 613 } 614 } 615 616 const state = { 617 prefix, 618 input, 619 start, 620 base, 621 glob, 622 isBrace, 623 isBracket, 624 isGlob, 625 isExtglob, 626 isGlobstar, 627 negated, 628 negatedExtglob 629 }; 630 631 if (opts.tokens === true) { 632 state.maxDepth = 0; 633 if (!isPathSeparator(code)) { 634 tokens.push(token); 635 } 636 state.tokens = tokens; 637 } 638 639 if (opts.parts === true || opts.tokens === true) { 640 let prevIndex; 641 642 for (let idx = 0; idx < slashes.length; idx++) { 643 const n = prevIndex ? prevIndex + 1 : start; 644 const i = slashes[idx]; 645 const value = input.slice(n, i); 646 if (opts.tokens) { 647 if (idx === 0 && start !== 0) { 648 tokens[idx].isPrefix = true; 649 tokens[idx].value = prefix; 650 } else { 651 tokens[idx].value = value; 652 } 653 depth(tokens[idx]); 654 state.maxDepth += tokens[idx].depth; 655 } 656 if (idx !== 0 || value !== '') { 657 parts.push(value); 658 } 659 prevIndex = i; 660 } 661 662 if (prevIndex && prevIndex + 1 < input.length) { 663 const value = input.slice(prevIndex + 1); 664 parts.push(value); 665 666 if (opts.tokens) { 667 tokens[tokens.length - 1].value = value; 668 depth(tokens[tokens.length - 1]); 669 state.maxDepth += tokens[tokens.length - 1].depth; 670 } 671 } 672 673 state.slashes = slashes; 674 state.parts = parts; 675 } 676 677 return state; 678 }; 679 680 scan_1$1 = scan; 681 return scan_1$1; 682 } 683 684 var parse_1$2; 685 var hasRequiredParse$2; 686 687 function requireParse$2 () { 688 if (hasRequiredParse$2) return parse_1$2; 689 hasRequiredParse$2 = 1; 690 691 const constants = /*@__PURE__*/ requireConstants$3(); 692 const utils = /*@__PURE__*/ requireUtils$2(); 693 694 /** 695 * Constants 696 */ 697 698 const { 699 MAX_LENGTH, 700 POSIX_REGEX_SOURCE, 701 REGEX_NON_SPECIAL_CHARS, 702 REGEX_SPECIAL_CHARS_BACKREF, 703 REPLACEMENTS 704 } = constants; 705 706 /** 707 * Helpers 708 */ 709 710 const expandRange = (args, options) => { 711 if (typeof options.expandRange === 'function') { 712 return options.expandRange(...args, options); 713 } 714 715 args.sort(); 716 const value = `[${args.join('-')}]`; 717 718 return value; 719 }; 720 721 /** 722 * Create the message for a syntax error 723 */ 724 725 const syntaxError = (type, char) => { 726 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; 727 }; 728 729 /** 730 * Parse the given input string. 731 * @param {String} input 732 * @param {Object} options 733 * @return {Object} 734 */ 735 736 const parse = (input, options) => { 737 if (typeof input !== 'string') { 738 throw new TypeError('Expected a string'); 739 } 740 741 input = REPLACEMENTS[input] || input; 742 743 const opts = { ...options }; 744 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 745 746 let len = input.length; 747 if (len > max) { 748 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 749 } 750 751 const bos = { type: 'bos', value: '', output: opts.prepend || '' }; 752 const tokens = [bos]; 753 754 const capture = opts.capture ? '' : '?:'; 755 const win32 = utils.isWindows(options); 756 757 // create constants based on platform, for windows or posix 758 const PLATFORM_CHARS = constants.globChars(win32); 759 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); 760 761 const { 762 DOT_LITERAL, 763 PLUS_LITERAL, 764 SLASH_LITERAL, 765 ONE_CHAR, 766 DOTS_SLASH, 767 NO_DOT, 768 NO_DOT_SLASH, 769 NO_DOTS_SLASH, 770 QMARK, 771 QMARK_NO_DOT, 772 STAR, 773 START_ANCHOR 774 } = PLATFORM_CHARS; 775 776 const globstar = opts => { 777 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 778 }; 779 780 const nodot = opts.dot ? '' : NO_DOT; 781 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; 782 let star = opts.bash === true ? globstar(opts) : STAR; 783 784 if (opts.capture) { 785 star = `(${star})`; 786 } 787 788 // minimatch options support 789 if (typeof opts.noext === 'boolean') { 790 opts.noextglob = opts.noext; 791 } 792 793 const state = { 794 input, 795 index: -1, 796 start: 0, 797 dot: opts.dot === true, 798 consumed: '', 799 output: '', 800 prefix: '', 801 backtrack: false, 802 negated: false, 803 brackets: 0, 804 braces: 0, 805 parens: 0, 806 quotes: 0, 807 globstar: false, 808 tokens 809 }; 810 811 input = utils.removePrefix(input, state); 812 len = input.length; 813 814 const extglobs = []; 815 const braces = []; 816 const stack = []; 817 let prev = bos; 818 let value; 819 820 /** 821 * Tokenizing helpers 822 */ 823 824 const eos = () => state.index === len - 1; 825 const peek = state.peek = (n = 1) => input[state.index + n]; 826 const advance = state.advance = () => input[++state.index] || ''; 827 const remaining = () => input.slice(state.index + 1); 828 const consume = (value = '', num = 0) => { 829 state.consumed += value; 830 state.index += num; 831 }; 832 833 const append = token => { 834 state.output += token.output != null ? token.output : token.value; 835 consume(token.value); 836 }; 837 838 const negate = () => { 839 let count = 1; 840 841 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { 842 advance(); 843 state.start++; 844 count++; 845 } 846 847 if (count % 2 === 0) { 848 return false; 849 } 850 851 state.negated = true; 852 state.start++; 853 return true; 854 }; 855 856 const increment = type => { 857 state[type]++; 858 stack.push(type); 859 }; 860 861 const decrement = type => { 862 state[type]--; 863 stack.pop(); 864 }; 865 866 /** 867 * Push tokens onto the tokens array. This helper speeds up 868 * tokenizing by 1) helping us avoid backtracking as much as possible, 869 * and 2) helping us avoid creating extra tokens when consecutive 870 * characters are plain text. This improves performance and simplifies 871 * lookbehinds. 872 */ 873 874 const push = tok => { 875 if (prev.type === 'globstar') { 876 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); 877 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); 878 879 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { 880 state.output = state.output.slice(0, -prev.output.length); 881 prev.type = 'star'; 882 prev.value = '*'; 883 prev.output = star; 884 state.output += prev.output; 885 } 886 } 887 888 if (extglobs.length && tok.type !== 'paren') { 889 extglobs[extglobs.length - 1].inner += tok.value; 890 } 891 892 if (tok.value || tok.output) append(tok); 893 if (prev && prev.type === 'text' && tok.type === 'text') { 894 prev.value += tok.value; 895 prev.output = (prev.output || '') + tok.value; 896 return; 897 } 898 899 tok.prev = prev; 900 tokens.push(tok); 901 prev = tok; 902 }; 903 904 const extglobOpen = (type, value) => { 905 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; 906 907 token.prev = prev; 908 token.parens = state.parens; 909 token.output = state.output; 910 const output = (opts.capture ? '(' : '') + token.open; 911 912 increment('parens'); 913 push({ type, value, output: state.output ? '' : ONE_CHAR }); 914 push({ type: 'paren', extglob: true, value: advance(), output }); 915 extglobs.push(token); 916 }; 917 918 const extglobClose = token => { 919 let output = token.close + (opts.capture ? ')' : ''); 920 let rest; 921 922 if (token.type === 'negate') { 923 let extglobStar = star; 924 925 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { 926 extglobStar = globstar(opts); 927 } 928 929 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { 930 output = token.close = `)$))${extglobStar}`; 931 } 932 933 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { 934 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. 935 // In this case, we need to parse the string and use it in the output of the original pattern. 936 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. 937 // 938 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. 939 const expression = parse(rest, { ...options, fastpaths: false }).output; 940 941 output = token.close = `)${expression})${extglobStar})`; 942 } 943 944 if (token.prev.type === 'bos') { 945 state.negatedExtglob = true; 946 } 947 } 948 949 push({ type: 'paren', extglob: true, value, output }); 950 decrement('parens'); 951 }; 952 953 /** 954 * Fast paths 955 */ 956 957 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { 958 let backslashes = false; 959 960 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { 961 if (first === '\\') { 962 backslashes = true; 963 return m; 964 } 965 966 if (first === '?') { 967 if (esc) { 968 return esc + first + (rest ? QMARK.repeat(rest.length) : ''); 969 } 970 if (index === 0) { 971 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); 972 } 973 return QMARK.repeat(chars.length); 974 } 975 976 if (first === '.') { 977 return DOT_LITERAL.repeat(chars.length); 978 } 979 980 if (first === '*') { 981 if (esc) { 982 return esc + first + (rest ? star : ''); 983 } 984 return star; 985 } 986 return esc ? m : `\\${m}`; 987 }); 988 989 if (backslashes === true) { 990 if (opts.unescape === true) { 991 output = output.replace(/\\/g, ''); 992 } else { 993 output = output.replace(/\\+/g, m => { 994 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); 995 }); 996 } 997 } 998 999 if (output === input && opts.contains === true) { 1000 state.output = input; 1001 return state; 1002 } 1003 1004 state.output = utils.wrapOutput(output, state, options); 1005 return state; 1006 } 1007 1008 /** 1009 * Tokenize input until we reach end-of-string 1010 */ 1011 1012 while (!eos()) { 1013 value = advance(); 1014 1015 if (value === '\u0000') { 1016 continue; 1017 } 1018 1019 /** 1020 * Escaped characters 1021 */ 1022 1023 if (value === '\\') { 1024 const next = peek(); 1025 1026 if (next === '/' && opts.bash !== true) { 1027 continue; 1028 } 1029 1030 if (next === '.' || next === ';') { 1031 continue; 1032 } 1033 1034 if (!next) { 1035 value += '\\'; 1036 push({ type: 'text', value }); 1037 continue; 1038 } 1039 1040 // collapse slashes to reduce potential for exploits 1041 const match = /^\\+/.exec(remaining()); 1042 let slashes = 0; 1043 1044 if (match && match[0].length > 2) { 1045 slashes = match[0].length; 1046 state.index += slashes; 1047 if (slashes % 2 !== 0) { 1048 value += '\\'; 1049 } 1050 } 1051 1052 if (opts.unescape === true) { 1053 value = advance(); 1054 } else { 1055 value += advance(); 1056 } 1057 1058 if (state.brackets === 0) { 1059 push({ type: 'text', value }); 1060 continue; 1061 } 1062 } 1063 1064 /** 1065 * If we're inside a regex character class, continue 1066 * until we reach the closing bracket. 1067 */ 1068 1069 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { 1070 if (opts.posix !== false && value === ':') { 1071 const inner = prev.value.slice(1); 1072 if (inner.includes('[')) { 1073 prev.posix = true; 1074 1075 if (inner.includes(':')) { 1076 const idx = prev.value.lastIndexOf('['); 1077 const pre = prev.value.slice(0, idx); 1078 const rest = prev.value.slice(idx + 2); 1079 const posix = POSIX_REGEX_SOURCE[rest]; 1080 if (posix) { 1081 prev.value = pre + posix; 1082 state.backtrack = true; 1083 advance(); 1084 1085 if (!bos.output && tokens.indexOf(prev) === 1) { 1086 bos.output = ONE_CHAR; 1087 } 1088 continue; 1089 } 1090 } 1091 } 1092 } 1093 1094 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { 1095 value = `\\${value}`; 1096 } 1097 1098 if (value === ']' && (prev.value === '[' || prev.value === '[^')) { 1099 value = `\\${value}`; 1100 } 1101 1102 if (opts.posix === true && value === '!' && prev.value === '[') { 1103 value = '^'; 1104 } 1105 1106 prev.value += value; 1107 append({ value }); 1108 continue; 1109 } 1110 1111 /** 1112 * If we're inside a quoted string, continue 1113 * until we reach the closing double quote. 1114 */ 1115 1116 if (state.quotes === 1 && value !== '"') { 1117 value = utils.escapeRegex(value); 1118 prev.value += value; 1119 append({ value }); 1120 continue; 1121 } 1122 1123 /** 1124 * Double quotes 1125 */ 1126 1127 if (value === '"') { 1128 state.quotes = state.quotes === 1 ? 0 : 1; 1129 if (opts.keepQuotes === true) { 1130 push({ type: 'text', value }); 1131 } 1132 continue; 1133 } 1134 1135 /** 1136 * Parentheses 1137 */ 1138 1139 if (value === '(') { 1140 increment('parens'); 1141 push({ type: 'paren', value }); 1142 continue; 1143 } 1144 1145 if (value === ')') { 1146 if (state.parens === 0 && opts.strictBrackets === true) { 1147 throw new SyntaxError(syntaxError('opening', '(')); 1148 } 1149 1150 const extglob = extglobs[extglobs.length - 1]; 1151 if (extglob && state.parens === extglob.parens + 1) { 1152 extglobClose(extglobs.pop()); 1153 continue; 1154 } 1155 1156 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); 1157 decrement('parens'); 1158 continue; 1159 } 1160 1161 /** 1162 * Square brackets 1163 */ 1164 1165 if (value === '[') { 1166 if (opts.nobracket === true || !remaining().includes(']')) { 1167 if (opts.nobracket !== true && opts.strictBrackets === true) { 1168 throw new SyntaxError(syntaxError('closing', ']')); 1169 } 1170 1171 value = `\\${value}`; 1172 } else { 1173 increment('brackets'); 1174 } 1175 1176 push({ type: 'bracket', value }); 1177 continue; 1178 } 1179 1180 if (value === ']') { 1181 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { 1182 push({ type: 'text', value, output: `\\${value}` }); 1183 continue; 1184 } 1185 1186 if (state.brackets === 0) { 1187 if (opts.strictBrackets === true) { 1188 throw new SyntaxError(syntaxError('opening', '[')); 1189 } 1190 1191 push({ type: 'text', value, output: `\\${value}` }); 1192 continue; 1193 } 1194 1195 decrement('brackets'); 1196 1197 const prevValue = prev.value.slice(1); 1198 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { 1199 value = `/${value}`; 1200 } 1201 1202 prev.value += value; 1203 append({ value }); 1204 1205 // when literal brackets are explicitly disabled 1206 // assume we should match with a regex character class 1207 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { 1208 continue; 1209 } 1210 1211 const escaped = utils.escapeRegex(prev.value); 1212 state.output = state.output.slice(0, -prev.value.length); 1213 1214 // when literal brackets are explicitly enabled 1215 // assume we should escape the brackets to match literal characters 1216 if (opts.literalBrackets === true) { 1217 state.output += escaped; 1218 prev.value = escaped; 1219 continue; 1220 } 1221 1222 // when the user specifies nothing, try to match both 1223 prev.value = `(${capture}${escaped}|${prev.value})`; 1224 state.output += prev.value; 1225 continue; 1226 } 1227 1228 /** 1229 * Braces 1230 */ 1231 1232 if (value === '{' && opts.nobrace !== true) { 1233 increment('braces'); 1234 1235 const open = { 1236 type: 'brace', 1237 value, 1238 output: '(', 1239 outputIndex: state.output.length, 1240 tokensIndex: state.tokens.length 1241 }; 1242 1243 braces.push(open); 1244 push(open); 1245 continue; 1246 } 1247 1248 if (value === '}') { 1249 const brace = braces[braces.length - 1]; 1250 1251 if (opts.nobrace === true || !brace) { 1252 push({ type: 'text', value, output: value }); 1253 continue; 1254 } 1255 1256 let output = ')'; 1257 1258 if (brace.dots === true) { 1259 const arr = tokens.slice(); 1260 const range = []; 1261 1262 for (let i = arr.length - 1; i >= 0; i--) { 1263 tokens.pop(); 1264 if (arr[i].type === 'brace') { 1265 break; 1266 } 1267 if (arr[i].type !== 'dots') { 1268 range.unshift(arr[i].value); 1269 } 1270 } 1271 1272 output = expandRange(range, opts); 1273 state.backtrack = true; 1274 } 1275 1276 if (brace.comma !== true && brace.dots !== true) { 1277 const out = state.output.slice(0, brace.outputIndex); 1278 const toks = state.tokens.slice(brace.tokensIndex); 1279 brace.value = brace.output = '\\{'; 1280 value = output = '\\}'; 1281 state.output = out; 1282 for (const t of toks) { 1283 state.output += (t.output || t.value); 1284 } 1285 } 1286 1287 push({ type: 'brace', value, output }); 1288 decrement('braces'); 1289 braces.pop(); 1290 continue; 1291 } 1292 1293 /** 1294 * Pipes 1295 */ 1296 1297 if (value === '|') { 1298 if (extglobs.length > 0) { 1299 extglobs[extglobs.length - 1].conditions++; 1300 } 1301 push({ type: 'text', value }); 1302 continue; 1303 } 1304 1305 /** 1306 * Commas 1307 */ 1308 1309 if (value === ',') { 1310 let output = value; 1311 1312 const brace = braces[braces.length - 1]; 1313 if (brace && stack[stack.length - 1] === 'braces') { 1314 brace.comma = true; 1315 output = '|'; 1316 } 1317 1318 push({ type: 'comma', value, output }); 1319 continue; 1320 } 1321 1322 /** 1323 * Slashes 1324 */ 1325 1326 if (value === '/') { 1327 // if the beginning of the glob is "./", advance the start 1328 // to the current index, and don't add the "./" characters 1329 // to the state. This greatly simplifies lookbehinds when 1330 // checking for BOS characters like "!" and "." (not "./") 1331 if (prev.type === 'dot' && state.index === state.start + 1) { 1332 state.start = state.index + 1; 1333 state.consumed = ''; 1334 state.output = ''; 1335 tokens.pop(); 1336 prev = bos; // reset "prev" to the first token 1337 continue; 1338 } 1339 1340 push({ type: 'slash', value, output: SLASH_LITERAL }); 1341 continue; 1342 } 1343 1344 /** 1345 * Dots 1346 */ 1347 1348 if (value === '.') { 1349 if (state.braces > 0 && prev.type === 'dot') { 1350 if (prev.value === '.') prev.output = DOT_LITERAL; 1351 const brace = braces[braces.length - 1]; 1352 prev.type = 'dots'; 1353 prev.output += value; 1354 prev.value += value; 1355 brace.dots = true; 1356 continue; 1357 } 1358 1359 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { 1360 push({ type: 'text', value, output: DOT_LITERAL }); 1361 continue; 1362 } 1363 1364 push({ type: 'dot', value, output: DOT_LITERAL }); 1365 continue; 1366 } 1367 1368 /** 1369 * Question marks 1370 */ 1371 1372 if (value === '?') { 1373 const isGroup = prev && prev.value === '('; 1374 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 1375 extglobOpen('qmark', value); 1376 continue; 1377 } 1378 1379 if (prev && prev.type === 'paren') { 1380 const next = peek(); 1381 let output = value; 1382 1383 if (next === '<' && !utils.supportsLookbehinds()) { 1384 throw new Error('Node.js v10 or higher is required for regex lookbehinds'); 1385 } 1386 1387 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { 1388 output = `\\${value}`; 1389 } 1390 1391 push({ type: 'text', value, output }); 1392 continue; 1393 } 1394 1395 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { 1396 push({ type: 'qmark', value, output: QMARK_NO_DOT }); 1397 continue; 1398 } 1399 1400 push({ type: 'qmark', value, output: QMARK }); 1401 continue; 1402 } 1403 1404 /** 1405 * Exclamation 1406 */ 1407 1408 if (value === '!') { 1409 if (opts.noextglob !== true && peek() === '(') { 1410 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { 1411 extglobOpen('negate', value); 1412 continue; 1413 } 1414 } 1415 1416 if (opts.nonegate !== true && state.index === 0) { 1417 negate(); 1418 continue; 1419 } 1420 } 1421 1422 /** 1423 * Plus 1424 */ 1425 1426 if (value === '+') { 1427 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 1428 extglobOpen('plus', value); 1429 continue; 1430 } 1431 1432 if ((prev && prev.value === '(') || opts.regex === false) { 1433 push({ type: 'plus', value, output: PLUS_LITERAL }); 1434 continue; 1435 } 1436 1437 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { 1438 push({ type: 'plus', value }); 1439 continue; 1440 } 1441 1442 push({ type: 'plus', value: PLUS_LITERAL }); 1443 continue; 1444 } 1445 1446 /** 1447 * Plain text 1448 */ 1449 1450 if (value === '@') { 1451 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 1452 push({ type: 'at', extglob: true, value, output: '' }); 1453 continue; 1454 } 1455 1456 push({ type: 'text', value }); 1457 continue; 1458 } 1459 1460 /** 1461 * Plain text 1462 */ 1463 1464 if (value !== '*') { 1465 if (value === '$' || value === '^') { 1466 value = `\\${value}`; 1467 } 1468 1469 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); 1470 if (match) { 1471 value += match[0]; 1472 state.index += match[0].length; 1473 } 1474 1475 push({ type: 'text', value }); 1476 continue; 1477 } 1478 1479 /** 1480 * Stars 1481 */ 1482 1483 if (prev && (prev.type === 'globstar' || prev.star === true)) { 1484 prev.type = 'star'; 1485 prev.star = true; 1486 prev.value += value; 1487 prev.output = star; 1488 state.backtrack = true; 1489 state.globstar = true; 1490 consume(value); 1491 continue; 1492 } 1493 1494 let rest = remaining(); 1495 if (opts.noextglob !== true && /^\([^?]/.test(rest)) { 1496 extglobOpen('star', value); 1497 continue; 1498 } 1499 1500 if (prev.type === 'star') { 1501 if (opts.noglobstar === true) { 1502 consume(value); 1503 continue; 1504 } 1505 1506 const prior = prev.prev; 1507 const before = prior.prev; 1508 const isStart = prior.type === 'slash' || prior.type === 'bos'; 1509 const afterStar = before && (before.type === 'star' || before.type === 'globstar'); 1510 1511 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { 1512 push({ type: 'star', value, output: '' }); 1513 continue; 1514 } 1515 1516 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); 1517 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); 1518 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { 1519 push({ type: 'star', value, output: '' }); 1520 continue; 1521 } 1522 1523 // strip consecutive `/**/` 1524 while (rest.slice(0, 3) === '/**') { 1525 const after = input[state.index + 4]; 1526 if (after && after !== '/') { 1527 break; 1528 } 1529 rest = rest.slice(3); 1530 consume('/**', 3); 1531 } 1532 1533 if (prior.type === 'bos' && eos()) { 1534 prev.type = 'globstar'; 1535 prev.value += value; 1536 prev.output = globstar(opts); 1537 state.output = prev.output; 1538 state.globstar = true; 1539 consume(value); 1540 continue; 1541 } 1542 1543 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { 1544 state.output = state.output.slice(0, -(prior.output + prev.output).length); 1545 prior.output = `(?:${prior.output}`; 1546 1547 prev.type = 'globstar'; 1548 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); 1549 prev.value += value; 1550 state.globstar = true; 1551 state.output += prior.output + prev.output; 1552 consume(value); 1553 continue; 1554 } 1555 1556 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { 1557 const end = rest[1] !== void 0 ? '|$' : ''; 1558 1559 state.output = state.output.slice(0, -(prior.output + prev.output).length); 1560 prior.output = `(?:${prior.output}`; 1561 1562 prev.type = 'globstar'; 1563 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; 1564 prev.value += value; 1565 1566 state.output += prior.output + prev.output; 1567 state.globstar = true; 1568 1569 consume(value + advance()); 1570 1571 push({ type: 'slash', value: '/', output: '' }); 1572 continue; 1573 } 1574 1575 if (prior.type === 'bos' && rest[0] === '/') { 1576 prev.type = 'globstar'; 1577 prev.value += value; 1578 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; 1579 state.output = prev.output; 1580 state.globstar = true; 1581 consume(value + advance()); 1582 push({ type: 'slash', value: '/', output: '' }); 1583 continue; 1584 } 1585 1586 // remove single star from output 1587 state.output = state.output.slice(0, -prev.output.length); 1588 1589 // reset previous token to globstar 1590 prev.type = 'globstar'; 1591 prev.output = globstar(opts); 1592 prev.value += value; 1593 1594 // reset output with globstar 1595 state.output += prev.output; 1596 state.globstar = true; 1597 consume(value); 1598 continue; 1599 } 1600 1601 const token = { type: 'star', value, output: star }; 1602 1603 if (opts.bash === true) { 1604 token.output = '.*?'; 1605 if (prev.type === 'bos' || prev.type === 'slash') { 1606 token.output = nodot + token.output; 1607 } 1608 push(token); 1609 continue; 1610 } 1611 1612 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { 1613 token.output = value; 1614 push(token); 1615 continue; 1616 } 1617 1618 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { 1619 if (prev.type === 'dot') { 1620 state.output += NO_DOT_SLASH; 1621 prev.output += NO_DOT_SLASH; 1622 1623 } else if (opts.dot === true) { 1624 state.output += NO_DOTS_SLASH; 1625 prev.output += NO_DOTS_SLASH; 1626 1627 } else { 1628 state.output += nodot; 1629 prev.output += nodot; 1630 } 1631 1632 if (peek() !== '*') { 1633 state.output += ONE_CHAR; 1634 prev.output += ONE_CHAR; 1635 } 1636 } 1637 1638 push(token); 1639 } 1640 1641 while (state.brackets > 0) { 1642 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); 1643 state.output = utils.escapeLast(state.output, '['); 1644 decrement('brackets'); 1645 } 1646 1647 while (state.parens > 0) { 1648 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); 1649 state.output = utils.escapeLast(state.output, '('); 1650 decrement('parens'); 1651 } 1652 1653 while (state.braces > 0) { 1654 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); 1655 state.output = utils.escapeLast(state.output, '{'); 1656 decrement('braces'); 1657 } 1658 1659 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { 1660 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); 1661 } 1662 1663 // rebuild the output if we had to backtrack at any point 1664 if (state.backtrack === true) { 1665 state.output = ''; 1666 1667 for (const token of state.tokens) { 1668 state.output += token.output != null ? token.output : token.value; 1669 1670 if (token.suffix) { 1671 state.output += token.suffix; 1672 } 1673 } 1674 } 1675 1676 return state; 1677 }; 1678 1679 /** 1680 * Fast paths for creating regular expressions for common glob patterns. 1681 * This can significantly speed up processing and has very little downside 1682 * impact when none of the fast paths match. 1683 */ 1684 1685 parse.fastpaths = (input, options) => { 1686 const opts = { ...options }; 1687 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 1688 const len = input.length; 1689 if (len > max) { 1690 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 1691 } 1692 1693 input = REPLACEMENTS[input] || input; 1694 const win32 = utils.isWindows(options); 1695 1696 // create constants based on platform, for windows or posix 1697 const { 1698 DOT_LITERAL, 1699 SLASH_LITERAL, 1700 ONE_CHAR, 1701 DOTS_SLASH, 1702 NO_DOT, 1703 NO_DOTS, 1704 NO_DOTS_SLASH, 1705 STAR, 1706 START_ANCHOR 1707 } = constants.globChars(win32); 1708 1709 const nodot = opts.dot ? NO_DOTS : NO_DOT; 1710 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; 1711 const capture = opts.capture ? '' : '?:'; 1712 const state = { negated: false, prefix: '' }; 1713 let star = opts.bash === true ? '.*?' : STAR; 1714 1715 if (opts.capture) { 1716 star = `(${star})`; 1717 } 1718 1719 const globstar = opts => { 1720 if (opts.noglobstar === true) return star; 1721 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 1722 }; 1723 1724 const create = str => { 1725 switch (str) { 1726 case '*': 1727 return `${nodot}${ONE_CHAR}${star}`; 1728 1729 case '.*': 1730 return `${DOT_LITERAL}${ONE_CHAR}${star}`; 1731 1732 case '*.*': 1733 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 1734 1735 case '*/*': 1736 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; 1737 1738 case '**': 1739 return nodot + globstar(opts); 1740 1741 case '**/*': 1742 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; 1743 1744 case '**/*.*': 1745 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 1746 1747 case '**/.*': 1748 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; 1749 1750 default: { 1751 const match = /^(.*?)\.(\w+)$/.exec(str); 1752 if (!match) return; 1753 1754 const source = create(match[1]); 1755 if (!source) return; 1756 1757 return source + DOT_LITERAL + match[2]; 1758 } 1759 } 1760 }; 1761 1762 const output = utils.removePrefix(input, state); 1763 let source = create(output); 1764 1765 if (source && opts.strictSlashes !== true) { 1766 source += `${SLASH_LITERAL}?`; 1767 } 1768 1769 return source; 1770 }; 1771 1772 parse_1$2 = parse; 1773 return parse_1$2; 1774 } 1775 1776 var picomatch_1$1; 1777 var hasRequiredPicomatch$3; 1778 1779 function requirePicomatch$3 () { 1780 if (hasRequiredPicomatch$3) return picomatch_1$1; 1781 hasRequiredPicomatch$3 = 1; 1782 1783 const path = require$$0$1; 1784 const scan = /*@__PURE__*/ requireScan$1(); 1785 const parse = /*@__PURE__*/ requireParse$2(); 1786 const utils = /*@__PURE__*/ requireUtils$2(); 1787 const constants = /*@__PURE__*/ requireConstants$3(); 1788 const isObject = val => val && typeof val === 'object' && !Array.isArray(val); 1789 1790 /** 1791 * Creates a matcher function from one or more glob patterns. The 1792 * returned function takes a string to match as its first argument, 1793 * and returns true if the string is a match. The returned matcher 1794 * function also takes a boolean as the second argument that, when true, 1795 * returns an object with additional information. 1796 * 1797 * ```js 1798 * const picomatch = require('picomatch'); 1799 * // picomatch(glob[, options]); 1800 * 1801 * const isMatch = picomatch('*.!(*a)'); 1802 * console.log(isMatch('a.a')); //=> false 1803 * console.log(isMatch('a.b')); //=> true 1804 * ``` 1805 * @name picomatch 1806 * @param {String|Array} `globs` One or more glob patterns. 1807 * @param {Object=} `options` 1808 * @return {Function=} Returns a matcher function. 1809 * @api public 1810 */ 1811 1812 const picomatch = (glob, options, returnState = false) => { 1813 if (Array.isArray(glob)) { 1814 const fns = glob.map(input => picomatch(input, options, returnState)); 1815 const arrayMatcher = str => { 1816 for (const isMatch of fns) { 1817 const state = isMatch(str); 1818 if (state) return state; 1819 } 1820 return false; 1821 }; 1822 return arrayMatcher; 1823 } 1824 1825 const isState = isObject(glob) && glob.tokens && glob.input; 1826 1827 if (glob === '' || (typeof glob !== 'string' && !isState)) { 1828 throw new TypeError('Expected pattern to be a non-empty string'); 1829 } 1830 1831 const opts = options || {}; 1832 const posix = utils.isWindows(options); 1833 const regex = isState 1834 ? picomatch.compileRe(glob, options) 1835 : picomatch.makeRe(glob, options, false, true); 1836 1837 const state = regex.state; 1838 delete regex.state; 1839 1840 let isIgnored = () => false; 1841 if (opts.ignore) { 1842 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; 1843 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); 1844 } 1845 1846 const matcher = (input, returnObject = false) => { 1847 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); 1848 const result = { glob, state, regex, posix, input, output, match, isMatch }; 1849 1850 if (typeof opts.onResult === 'function') { 1851 opts.onResult(result); 1852 } 1853 1854 if (isMatch === false) { 1855 result.isMatch = false; 1856 return returnObject ? result : false; 1857 } 1858 1859 if (isIgnored(input)) { 1860 if (typeof opts.onIgnore === 'function') { 1861 opts.onIgnore(result); 1862 } 1863 result.isMatch = false; 1864 return returnObject ? result : false; 1865 } 1866 1867 if (typeof opts.onMatch === 'function') { 1868 opts.onMatch(result); 1869 } 1870 return returnObject ? result : true; 1871 }; 1872 1873 if (returnState) { 1874 matcher.state = state; 1875 } 1876 1877 return matcher; 1878 }; 1879 1880 /** 1881 * Test `input` with the given `regex`. This is used by the main 1882 * `picomatch()` function to test the input string. 1883 * 1884 * ```js 1885 * const picomatch = require('picomatch'); 1886 * // picomatch.test(input, regex[, options]); 1887 * 1888 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); 1889 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } 1890 * ``` 1891 * @param {String} `input` String to test. 1892 * @param {RegExp} `regex` 1893 * @return {Object} Returns an object with matching info. 1894 * @api public 1895 */ 1896 1897 picomatch.test = (input, regex, options, { glob, posix } = {}) => { 1898 if (typeof input !== 'string') { 1899 throw new TypeError('Expected input to be a string'); 1900 } 1901 1902 if (input === '') { 1903 return { isMatch: false, output: '' }; 1904 } 1905 1906 const opts = options || {}; 1907 const format = opts.format || (posix ? utils.toPosixSlashes : null); 1908 let match = input === glob; 1909 let output = (match && format) ? format(input) : input; 1910 1911 if (match === false) { 1912 output = format ? format(input) : input; 1913 match = output === glob; 1914 } 1915 1916 if (match === false || opts.capture === true) { 1917 if (opts.matchBase === true || opts.basename === true) { 1918 match = picomatch.matchBase(input, regex, options, posix); 1919 } else { 1920 match = regex.exec(output); 1921 } 1922 } 1923 1924 return { isMatch: Boolean(match), match, output }; 1925 }; 1926 1927 /** 1928 * Match the basename of a filepath. 1929 * 1930 * ```js 1931 * const picomatch = require('picomatch'); 1932 * // picomatch.matchBase(input, glob[, options]); 1933 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true 1934 * ``` 1935 * @param {String} `input` String to test. 1936 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). 1937 * @return {Boolean} 1938 * @api public 1939 */ 1940 1941 picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { 1942 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); 1943 return regex.test(path.basename(input)); 1944 }; 1945 1946 /** 1947 * Returns true if **any** of the given glob `patterns` match the specified `string`. 1948 * 1949 * ```js 1950 * const picomatch = require('picomatch'); 1951 * // picomatch.isMatch(string, patterns[, options]); 1952 * 1953 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true 1954 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false 1955 * ``` 1956 * @param {String|Array} str The string to test. 1957 * @param {String|Array} patterns One or more glob patterns to use for matching. 1958 * @param {Object} [options] See available [options](#options). 1959 * @return {Boolean} Returns true if any patterns match `str` 1960 * @api public 1961 */ 1962 1963 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); 1964 1965 /** 1966 * Parse a glob pattern to create the source string for a regular 1967 * expression. 1968 * 1969 * ```js 1970 * const picomatch = require('picomatch'); 1971 * const result = picomatch.parse(pattern[, options]); 1972 * ``` 1973 * @param {String} `pattern` 1974 * @param {Object} `options` 1975 * @return {Object} Returns an object with useful properties and output to be used as a regex source string. 1976 * @api public 1977 */ 1978 1979 picomatch.parse = (pattern, options) => { 1980 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); 1981 return parse(pattern, { ...options, fastpaths: false }); 1982 }; 1983 1984 /** 1985 * Scan a glob pattern to separate the pattern into segments. 1986 * 1987 * ```js 1988 * const picomatch = require('picomatch'); 1989 * // picomatch.scan(input[, options]); 1990 * 1991 * const result = picomatch.scan('!./foo/*.js'); 1992 * console.log(result); 1993 * { prefix: '!./', 1994 * input: '!./foo/*.js', 1995 * start: 3, 1996 * base: 'foo', 1997 * glob: '*.js', 1998 * isBrace: false, 1999 * isBracket: false, 2000 * isGlob: true, 2001 * isExtglob: false, 2002 * isGlobstar: false, 2003 * negated: true } 2004 * ``` 2005 * @param {String} `input` Glob pattern to scan. 2006 * @param {Object} `options` 2007 * @return {Object} Returns an object with 2008 * @api public 2009 */ 2010 2011 picomatch.scan = (input, options) => scan(input, options); 2012 2013 /** 2014 * Compile a regular expression from the `state` object returned by the 2015 * [parse()](#parse) method. 2016 * 2017 * @param {Object} `state` 2018 * @param {Object} `options` 2019 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. 2020 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. 2021 * @return {RegExp} 2022 * @api public 2023 */ 2024 2025 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { 2026 if (returnOutput === true) { 2027 return state.output; 2028 } 2029 2030 const opts = options || {}; 2031 const prepend = opts.contains ? '' : '^'; 2032 const append = opts.contains ? '' : '$'; 2033 2034 let source = `${prepend}(?:${state.output})${append}`; 2035 if (state && state.negated === true) { 2036 source = `^(?!${source}).*$`; 2037 } 2038 2039 const regex = picomatch.toRegex(source, options); 2040 if (returnState === true) { 2041 regex.state = state; 2042 } 2043 2044 return regex; 2045 }; 2046 2047 /** 2048 * Create a regular expression from a parsed glob pattern. 2049 * 2050 * ```js 2051 * const picomatch = require('picomatch'); 2052 * const state = picomatch.parse('*.js'); 2053 * // picomatch.compileRe(state[, options]); 2054 * 2055 * console.log(picomatch.compileRe(state)); 2056 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 2057 * ``` 2058 * @param {String} `state` The object returned from the `.parse` method. 2059 * @param {Object} `options` 2060 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. 2061 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. 2062 * @return {RegExp} Returns a regex created from the given pattern. 2063 * @api public 2064 */ 2065 2066 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { 2067 if (!input || typeof input !== 'string') { 2068 throw new TypeError('Expected a non-empty string'); 2069 } 2070 2071 let parsed = { negated: false, fastpaths: true }; 2072 2073 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { 2074 parsed.output = parse.fastpaths(input, options); 2075 } 2076 2077 if (!parsed.output) { 2078 parsed = parse(input, options); 2079 } 2080 2081 return picomatch.compileRe(parsed, options, returnOutput, returnState); 2082 }; 2083 2084 /** 2085 * Create a regular expression from the given regex source string. 2086 * 2087 * ```js 2088 * const picomatch = require('picomatch'); 2089 * // picomatch.toRegex(source[, options]); 2090 * 2091 * const { output } = picomatch.parse('*.js'); 2092 * console.log(picomatch.toRegex(output)); 2093 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 2094 * ``` 2095 * @param {String} `source` Regular expression source string. 2096 * @param {Object} `options` 2097 * @return {RegExp} 2098 * @api public 2099 */ 2100 2101 picomatch.toRegex = (source, options) => { 2102 try { 2103 const opts = options || {}; 2104 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); 2105 } catch (err) { 2106 if (options && options.debug === true) throw err; 2107 return /$^/; 2108 } 2109 }; 2110 2111 /** 2112 * Picomatch constants. 2113 * @return {Object} 2114 */ 2115 2116 picomatch.constants = constants; 2117 2118 /** 2119 * Expose "picomatch" 2120 */ 2121 2122 picomatch_1$1 = picomatch; 2123 return picomatch_1$1; 2124 } 2125 2126 var picomatch$1; 2127 var hasRequiredPicomatch$2; 2128 2129 function requirePicomatch$2 () { 2130 if (hasRequiredPicomatch$2) return picomatch$1; 2131 hasRequiredPicomatch$2 = 1; 2132 2133 picomatch$1 = /*@__PURE__*/ requirePicomatch$3(); 2134 return picomatch$1; 2135 } 2136 2137 var readdirp_1; 2138 var hasRequiredReaddirp; 2139 2140 function requireReaddirp () { 2141 if (hasRequiredReaddirp) return readdirp_1; 2142 hasRequiredReaddirp = 1; 2143 2144 const fs = require$$0$2; 2145 const { Readable } = require$$1; 2146 const sysPath = require$$0$1; 2147 const { promisify } = require$$2; 2148 const picomatch = /*@__PURE__*/ requirePicomatch$2(); 2149 2150 const readdir = promisify(fs.readdir); 2151 const stat = promisify(fs.stat); 2152 const lstat = promisify(fs.lstat); 2153 const realpath = promisify(fs.realpath); 2154 2155 /** 2156 * @typedef {Object} EntryInfo 2157 * @property {String} path 2158 * @property {String} fullPath 2159 * @property {fs.Stats=} stats 2160 * @property {fs.Dirent=} dirent 2161 * @property {String} basename 2162 */ 2163 2164 const BANG = '!'; 2165 const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR'; 2166 const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]); 2167 const FILE_TYPE = 'files'; 2168 const DIR_TYPE = 'directories'; 2169 const FILE_DIR_TYPE = 'files_directories'; 2170 const EVERYTHING_TYPE = 'all'; 2171 const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]; 2172 2173 const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code); 2174 const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10)); 2175 const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5)); 2176 2177 const normalizeFilter = filter => { 2178 if (filter === undefined) return; 2179 if (typeof filter === 'function') return filter; 2180 2181 if (typeof filter === 'string') { 2182 const glob = picomatch(filter.trim()); 2183 return entry => glob(entry.basename); 2184 } 2185 2186 if (Array.isArray(filter)) { 2187 const positive = []; 2188 const negative = []; 2189 for (const item of filter) { 2190 const trimmed = item.trim(); 2191 if (trimmed.charAt(0) === BANG) { 2192 negative.push(picomatch(trimmed.slice(1))); 2193 } else { 2194 positive.push(picomatch(trimmed)); 2195 } 2196 } 2197 2198 if (negative.length > 0) { 2199 if (positive.length > 0) { 2200 return entry => 2201 positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename)); 2202 } 2203 return entry => !negative.some(f => f(entry.basename)); 2204 } 2205 return entry => positive.some(f => f(entry.basename)); 2206 } 2207 }; 2208 2209 class ReaddirpStream extends Readable { 2210 static get defaultOptions() { 2211 return { 2212 root: '.', 2213 /* eslint-disable no-unused-vars */ 2214 fileFilter: (path) => true, 2215 directoryFilter: (path) => true, 2216 /* eslint-enable no-unused-vars */ 2217 type: FILE_TYPE, 2218 lstat: false, 2219 depth: 2147483648, 2220 alwaysStat: false 2221 }; 2222 } 2223 2224 constructor(options = {}) { 2225 super({ 2226 objectMode: true, 2227 autoDestroy: true, 2228 highWaterMark: options.highWaterMark || 4096 2229 }); 2230 const opts = { ...ReaddirpStream.defaultOptions, ...options }; 2231 const { root, type } = opts; 2232 2233 this._fileFilter = normalizeFilter(opts.fileFilter); 2234 this._directoryFilter = normalizeFilter(opts.directoryFilter); 2235 2236 const statMethod = opts.lstat ? lstat : stat; 2237 // Use bigint stats if it's windows and stat() supports options (node 10+). 2238 if (wantBigintFsStats) { 2239 this._stat = path => statMethod(path, { bigint: true }); 2240 } else { 2241 this._stat = statMethod; 2242 } 2243 2244 this._maxDepth = opts.depth; 2245 this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); 2246 this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); 2247 this._wantsEverything = type === EVERYTHING_TYPE; 2248 this._root = sysPath.resolve(root); 2249 this._isDirent = ('Dirent' in fs) && !opts.alwaysStat; 2250 this._statsProp = this._isDirent ? 'dirent' : 'stats'; 2251 this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent }; 2252 2253 // Launch stream with one parent, the root dir. 2254 this.parents = [this._exploreDir(root, 1)]; 2255 this.reading = false; 2256 this.parent = undefined; 2257 } 2258 2259 async _read(batch) { 2260 if (this.reading) return; 2261 this.reading = true; 2262 2263 try { 2264 while (!this.destroyed && batch > 0) { 2265 const { path, depth, files = [] } = this.parent || {}; 2266 2267 if (files.length > 0) { 2268 const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path)); 2269 for (const entry of await Promise.all(slice)) { 2270 if (this.destroyed) return; 2271 2272 const entryType = await this._getEntryType(entry); 2273 if (entryType === 'directory' && this._directoryFilter(entry)) { 2274 if (depth <= this._maxDepth) { 2275 this.parents.push(this._exploreDir(entry.fullPath, depth + 1)); 2276 } 2277 2278 if (this._wantsDir) { 2279 this.push(entry); 2280 batch--; 2281 } 2282 } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) { 2283 if (this._wantsFile) { 2284 this.push(entry); 2285 batch--; 2286 } 2287 } 2288 } 2289 } else { 2290 const parent = this.parents.pop(); 2291 if (!parent) { 2292 this.push(null); 2293 break; 2294 } 2295 this.parent = await parent; 2296 if (this.destroyed) return; 2297 } 2298 } 2299 } catch (error) { 2300 this.destroy(error); 2301 } finally { 2302 this.reading = false; 2303 } 2304 } 2305 2306 async _exploreDir(path, depth) { 2307 let files; 2308 try { 2309 files = await readdir(path, this._rdOptions); 2310 } catch (error) { 2311 this._onError(error); 2312 } 2313 return { files, depth, path }; 2314 } 2315 2316 async _formatEntry(dirent, path) { 2317 let entry; 2318 try { 2319 const basename = this._isDirent ? dirent.name : dirent; 2320 const fullPath = sysPath.resolve(sysPath.join(path, basename)); 2321 entry = { path: sysPath.relative(this._root, fullPath), fullPath, basename }; 2322 entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath); 2323 } catch (err) { 2324 this._onError(err); 2325 } 2326 return entry; 2327 } 2328 2329 _onError(err) { 2330 if (isNormalFlowError(err) && !this.destroyed) { 2331 this.emit('warn', err); 2332 } else { 2333 this.destroy(err); 2334 } 2335 } 2336 2337 async _getEntryType(entry) { 2338 // entry may be undefined, because a warning or an error were emitted 2339 // and the statsProp is undefined 2340 const stats = entry && entry[this._statsProp]; 2341 if (!stats) { 2342 return; 2343 } 2344 if (stats.isFile()) { 2345 return 'file'; 2346 } 2347 if (stats.isDirectory()) { 2348 return 'directory'; 2349 } 2350 if (stats && stats.isSymbolicLink()) { 2351 const full = entry.fullPath; 2352 try { 2353 const entryRealPath = await realpath(full); 2354 const entryRealPathStats = await lstat(entryRealPath); 2355 if (entryRealPathStats.isFile()) { 2356 return 'file'; 2357 } 2358 if (entryRealPathStats.isDirectory()) { 2359 const len = entryRealPath.length; 2360 if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath.sep) { 2361 const recursiveError = new Error( 2362 `Circular symlink detected: "${full}" points to "${entryRealPath}"` 2363 ); 2364 recursiveError.code = RECURSIVE_ERROR_CODE; 2365 return this._onError(recursiveError); 2366 } 2367 return 'directory'; 2368 } 2369 } catch (error) { 2370 this._onError(error); 2371 } 2372 } 2373 } 2374 2375 _includeAsFile(entry) { 2376 const stats = entry && entry[this._statsProp]; 2377 2378 return stats && this._wantsEverything && !stats.isDirectory(); 2379 } 2380 } 2381 2382 /** 2383 * @typedef {Object} ReaddirpArguments 2384 * @property {Function=} fileFilter 2385 * @property {Function=} directoryFilter 2386 * @property {String=} type 2387 * @property {Number=} depth 2388 * @property {String=} root 2389 * @property {Boolean=} lstat 2390 * @property {Boolean=} bigint 2391 */ 2392 2393 /** 2394 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively. 2395 * @param {String} root Root directory 2396 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth 2397 */ 2398 const readdirp = (root, options = {}) => { 2399 let type = options.entryType || options.type; 2400 if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility 2401 if (type) options.type = type; 2402 if (!root) { 2403 throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)'); 2404 } else if (typeof root !== 'string') { 2405 throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)'); 2406 } else if (type && !ALL_TYPES.includes(type)) { 2407 throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`); 2408 } 2409 2410 options.root = root; 2411 return new ReaddirpStream(options); 2412 }; 2413 2414 const readdirpPromise = (root, options = {}) => { 2415 return new Promise((resolve, reject) => { 2416 const files = []; 2417 readdirp(root, options) 2418 .on('data', entry => files.push(entry)) 2419 .on('end', () => resolve(files)) 2420 .on('error', error => reject(error)); 2421 }); 2422 }; 2423 2424 readdirp.promise = readdirpPromise; 2425 readdirp.ReaddirpStream = ReaddirpStream; 2426 readdirp.default = readdirp; 2427 2428 readdirp_1 = readdirp; 2429 return readdirp_1; 2430 } 2431 2432 var anymatch = {exports: {}}; 2433 2434 var utils$1 = {}; 2435 2436 var constants$2; 2437 var hasRequiredConstants$2; 2438 2439 function requireConstants$2 () { 2440 if (hasRequiredConstants$2) return constants$2; 2441 hasRequiredConstants$2 = 1; 2442 2443 const path = require$$0$1; 2444 const WIN_SLASH = '\\\\/'; 2445 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 2446 2447 /** 2448 * Posix glob regex 2449 */ 2450 2451 const DOT_LITERAL = '\\.'; 2452 const PLUS_LITERAL = '\\+'; 2453 const QMARK_LITERAL = '\\?'; 2454 const SLASH_LITERAL = '\\/'; 2455 const ONE_CHAR = '(?=.)'; 2456 const QMARK = '[^/]'; 2457 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 2458 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 2459 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 2460 const NO_DOT = `(?!${DOT_LITERAL})`; 2461 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 2462 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 2463 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 2464 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 2465 const STAR = `${QMARK}*?`; 2466 2467 const POSIX_CHARS = { 2468 DOT_LITERAL, 2469 PLUS_LITERAL, 2470 QMARK_LITERAL, 2471 SLASH_LITERAL, 2472 ONE_CHAR, 2473 QMARK, 2474 END_ANCHOR, 2475 DOTS_SLASH, 2476 NO_DOT, 2477 NO_DOTS, 2478 NO_DOT_SLASH, 2479 NO_DOTS_SLASH, 2480 QMARK_NO_DOT, 2481 STAR, 2482 START_ANCHOR 2483 }; 2484 2485 /** 2486 * Windows glob regex 2487 */ 2488 2489 const WINDOWS_CHARS = { 2490 ...POSIX_CHARS, 2491 2492 SLASH_LITERAL: `[${WIN_SLASH}]`, 2493 QMARK: WIN_NO_SLASH, 2494 STAR: `${WIN_NO_SLASH}*?`, 2495 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, 2496 NO_DOT: `(?!${DOT_LITERAL})`, 2497 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 2498 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, 2499 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 2500 QMARK_NO_DOT: `[^.${WIN_SLASH}]`, 2501 START_ANCHOR: `(?:^|[${WIN_SLASH}])`, 2502 END_ANCHOR: `(?:[${WIN_SLASH}]|$)` 2503 }; 2504 2505 /** 2506 * POSIX Bracket Regex 2507 */ 2508 2509 const POSIX_REGEX_SOURCE = { 2510 alnum: 'a-zA-Z0-9', 2511 alpha: 'a-zA-Z', 2512 ascii: '\\x00-\\x7F', 2513 blank: ' \\t', 2514 cntrl: '\\x00-\\x1F\\x7F', 2515 digit: '0-9', 2516 graph: '\\x21-\\x7E', 2517 lower: 'a-z', 2518 print: '\\x20-\\x7E ', 2519 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', 2520 space: ' \\t\\r\\n\\v\\f', 2521 upper: 'A-Z', 2522 word: 'A-Za-z0-9_', 2523 xdigit: 'A-Fa-f0-9' 2524 }; 2525 2526 constants$2 = { 2527 MAX_LENGTH: 1024 * 64, 2528 POSIX_REGEX_SOURCE, 2529 2530 // regular expressions 2531 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, 2532 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, 2533 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, 2534 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, 2535 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, 2536 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, 2537 2538 // Replace globs with equivalent patterns to reduce parsing time. 2539 REPLACEMENTS: { 2540 '***': '*', 2541 '**/**': '**', 2542 '**/**/**': '**' 2543 }, 2544 2545 // Digits 2546 CHAR_0: 48, /* 0 */ 2547 CHAR_9: 57, /* 9 */ 2548 2549 // Alphabet chars. 2550 CHAR_UPPERCASE_A: 65, /* A */ 2551 CHAR_LOWERCASE_A: 97, /* a */ 2552 CHAR_UPPERCASE_Z: 90, /* Z */ 2553 CHAR_LOWERCASE_Z: 122, /* z */ 2554 2555 CHAR_LEFT_PARENTHESES: 40, /* ( */ 2556 CHAR_RIGHT_PARENTHESES: 41, /* ) */ 2557 2558 CHAR_ASTERISK: 42, /* * */ 2559 2560 // Non-alphabetic chars. 2561 CHAR_AMPERSAND: 38, /* & */ 2562 CHAR_AT: 64, /* @ */ 2563 CHAR_BACKWARD_SLASH: 92, /* \ */ 2564 CHAR_CARRIAGE_RETURN: 13, /* \r */ 2565 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ 2566 CHAR_COLON: 58, /* : */ 2567 CHAR_COMMA: 44, /* , */ 2568 CHAR_DOT: 46, /* . */ 2569 CHAR_DOUBLE_QUOTE: 34, /* " */ 2570 CHAR_EQUAL: 61, /* = */ 2571 CHAR_EXCLAMATION_MARK: 33, /* ! */ 2572 CHAR_FORM_FEED: 12, /* \f */ 2573 CHAR_FORWARD_SLASH: 47, /* / */ 2574 CHAR_GRAVE_ACCENT: 96, /* ` */ 2575 CHAR_HASH: 35, /* # */ 2576 CHAR_HYPHEN_MINUS: 45, /* - */ 2577 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ 2578 CHAR_LEFT_CURLY_BRACE: 123, /* { */ 2579 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ 2580 CHAR_LINE_FEED: 10, /* \n */ 2581 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ 2582 CHAR_PERCENT: 37, /* % */ 2583 CHAR_PLUS: 43, /* + */ 2584 CHAR_QUESTION_MARK: 63, /* ? */ 2585 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ 2586 CHAR_RIGHT_CURLY_BRACE: 125, /* } */ 2587 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ 2588 CHAR_SEMICOLON: 59, /* ; */ 2589 CHAR_SINGLE_QUOTE: 39, /* ' */ 2590 CHAR_SPACE: 32, /* */ 2591 CHAR_TAB: 9, /* \t */ 2592 CHAR_UNDERSCORE: 95, /* _ */ 2593 CHAR_VERTICAL_LINE: 124, /* | */ 2594 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ 2595 2596 SEP: path.sep, 2597 2598 /** 2599 * Create EXTGLOB_CHARS 2600 */ 2601 2602 extglobChars(chars) { 2603 return { 2604 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, 2605 '?': { type: 'qmark', open: '(?:', close: ')?' }, 2606 '+': { type: 'plus', open: '(?:', close: ')+' }, 2607 '*': { type: 'star', open: '(?:', close: ')*' }, 2608 '@': { type: 'at', open: '(?:', close: ')' } 2609 }; 2610 }, 2611 2612 /** 2613 * Create GLOB_CHARS 2614 */ 2615 2616 globChars(win32) { 2617 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; 2618 } 2619 }; 2620 return constants$2; 2621 } 2622 2623 var hasRequiredUtils$1; 2624 2625 function requireUtils$1 () { 2626 if (hasRequiredUtils$1) return utils$1; 2627 hasRequiredUtils$1 = 1; 2628 (function (exports) { 2629 2630 const path = require$$0$1; 2631 const win32 = process.platform === 'win32'; 2632 const { 2633 REGEX_BACKSLASH, 2634 REGEX_REMOVE_BACKSLASH, 2635 REGEX_SPECIAL_CHARS, 2636 REGEX_SPECIAL_CHARS_GLOBAL 2637 } = /*@__PURE__*/ requireConstants$2(); 2638 2639 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 2640 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); 2641 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); 2642 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); 2643 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); 2644 2645 exports.removeBackslashes = str => { 2646 return str.replace(REGEX_REMOVE_BACKSLASH, match => { 2647 return match === '\\' ? '' : match; 2648 }); 2649 }; 2650 2651 exports.supportsLookbehinds = () => { 2652 const segs = process.version.slice(1).split('.').map(Number); 2653 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { 2654 return true; 2655 } 2656 return false; 2657 }; 2658 2659 exports.isWindows = options => { 2660 if (options && typeof options.windows === 'boolean') { 2661 return options.windows; 2662 } 2663 return win32 === true || path.sep === '\\'; 2664 }; 2665 2666 exports.escapeLast = (input, char, lastIdx) => { 2667 const idx = input.lastIndexOf(char, lastIdx); 2668 if (idx === -1) return input; 2669 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); 2670 return `${input.slice(0, idx)}\\${input.slice(idx)}`; 2671 }; 2672 2673 exports.removePrefix = (input, state = {}) => { 2674 let output = input; 2675 if (output.startsWith('./')) { 2676 output = output.slice(2); 2677 state.prefix = './'; 2678 } 2679 return output; 2680 }; 2681 2682 exports.wrapOutput = (input, state = {}, options = {}) => { 2683 const prepend = options.contains ? '' : '^'; 2684 const append = options.contains ? '' : '$'; 2685 2686 let output = `${prepend}(?:${input})${append}`; 2687 if (state.negated === true) { 2688 output = `(?:^(?!${output}).*$)`; 2689 } 2690 return output; 2691 }; 2692 } (utils$1)); 2693 return utils$1; 2694 } 2695 2696 var scan_1; 2697 var hasRequiredScan; 2698 2699 function requireScan () { 2700 if (hasRequiredScan) return scan_1; 2701 hasRequiredScan = 1; 2702 2703 const utils = /*@__PURE__*/ requireUtils$1(); 2704 const { 2705 CHAR_ASTERISK, /* * */ 2706 CHAR_AT, /* @ */ 2707 CHAR_BACKWARD_SLASH, /* \ */ 2708 CHAR_COMMA, /* , */ 2709 CHAR_DOT, /* . */ 2710 CHAR_EXCLAMATION_MARK, /* ! */ 2711 CHAR_FORWARD_SLASH, /* / */ 2712 CHAR_LEFT_CURLY_BRACE, /* { */ 2713 CHAR_LEFT_PARENTHESES, /* ( */ 2714 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 2715 CHAR_PLUS, /* + */ 2716 CHAR_QUESTION_MARK, /* ? */ 2717 CHAR_RIGHT_CURLY_BRACE, /* } */ 2718 CHAR_RIGHT_PARENTHESES, /* ) */ 2719 CHAR_RIGHT_SQUARE_BRACKET /* ] */ 2720 } = /*@__PURE__*/ requireConstants$2(); 2721 2722 const isPathSeparator = code => { 2723 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; 2724 }; 2725 2726 const depth = token => { 2727 if (token.isPrefix !== true) { 2728 token.depth = token.isGlobstar ? Infinity : 1; 2729 } 2730 }; 2731 2732 /** 2733 * Quickly scans a glob pattern and returns an object with a handful of 2734 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), 2735 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not 2736 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). 2737 * 2738 * ```js 2739 * const pm = require('picomatch'); 2740 * console.log(pm.scan('foo/bar/*.js')); 2741 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } 2742 * ``` 2743 * @param {String} `str` 2744 * @param {Object} `options` 2745 * @return {Object} Returns an object with tokens and regex source string. 2746 * @api public 2747 */ 2748 2749 const scan = (input, options) => { 2750 const opts = options || {}; 2751 2752 const length = input.length - 1; 2753 const scanToEnd = opts.parts === true || opts.scanToEnd === true; 2754 const slashes = []; 2755 const tokens = []; 2756 const parts = []; 2757 2758 let str = input; 2759 let index = -1; 2760 let start = 0; 2761 let lastIndex = 0; 2762 let isBrace = false; 2763 let isBracket = false; 2764 let isGlob = false; 2765 let isExtglob = false; 2766 let isGlobstar = false; 2767 let braceEscaped = false; 2768 let backslashes = false; 2769 let negated = false; 2770 let negatedExtglob = false; 2771 let finished = false; 2772 let braces = 0; 2773 let prev; 2774 let code; 2775 let token = { value: '', depth: 0, isGlob: false }; 2776 2777 const eos = () => index >= length; 2778 const peek = () => str.charCodeAt(index + 1); 2779 const advance = () => { 2780 prev = code; 2781 return str.charCodeAt(++index); 2782 }; 2783 2784 while (index < length) { 2785 code = advance(); 2786 let next; 2787 2788 if (code === CHAR_BACKWARD_SLASH) { 2789 backslashes = token.backslashes = true; 2790 code = advance(); 2791 2792 if (code === CHAR_LEFT_CURLY_BRACE) { 2793 braceEscaped = true; 2794 } 2795 continue; 2796 } 2797 2798 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { 2799 braces++; 2800 2801 while (eos() !== true && (code = advance())) { 2802 if (code === CHAR_BACKWARD_SLASH) { 2803 backslashes = token.backslashes = true; 2804 advance(); 2805 continue; 2806 } 2807 2808 if (code === CHAR_LEFT_CURLY_BRACE) { 2809 braces++; 2810 continue; 2811 } 2812 2813 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { 2814 isBrace = token.isBrace = true; 2815 isGlob = token.isGlob = true; 2816 finished = true; 2817 2818 if (scanToEnd === true) { 2819 continue; 2820 } 2821 2822 break; 2823 } 2824 2825 if (braceEscaped !== true && code === CHAR_COMMA) { 2826 isBrace = token.isBrace = true; 2827 isGlob = token.isGlob = true; 2828 finished = true; 2829 2830 if (scanToEnd === true) { 2831 continue; 2832 } 2833 2834 break; 2835 } 2836 2837 if (code === CHAR_RIGHT_CURLY_BRACE) { 2838 braces--; 2839 2840 if (braces === 0) { 2841 braceEscaped = false; 2842 isBrace = token.isBrace = true; 2843 finished = true; 2844 break; 2845 } 2846 } 2847 } 2848 2849 if (scanToEnd === true) { 2850 continue; 2851 } 2852 2853 break; 2854 } 2855 2856 if (code === CHAR_FORWARD_SLASH) { 2857 slashes.push(index); 2858 tokens.push(token); 2859 token = { value: '', depth: 0, isGlob: false }; 2860 2861 if (finished === true) continue; 2862 if (prev === CHAR_DOT && index === (start + 1)) { 2863 start += 2; 2864 continue; 2865 } 2866 2867 lastIndex = index + 1; 2868 continue; 2869 } 2870 2871 if (opts.noext !== true) { 2872 const isExtglobChar = code === CHAR_PLUS 2873 || code === CHAR_AT 2874 || code === CHAR_ASTERISK 2875 || code === CHAR_QUESTION_MARK 2876 || code === CHAR_EXCLAMATION_MARK; 2877 2878 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { 2879 isGlob = token.isGlob = true; 2880 isExtglob = token.isExtglob = true; 2881 finished = true; 2882 if (code === CHAR_EXCLAMATION_MARK && index === start) { 2883 negatedExtglob = true; 2884 } 2885 2886 if (scanToEnd === true) { 2887 while (eos() !== true && (code = advance())) { 2888 if (code === CHAR_BACKWARD_SLASH) { 2889 backslashes = token.backslashes = true; 2890 code = advance(); 2891 continue; 2892 } 2893 2894 if (code === CHAR_RIGHT_PARENTHESES) { 2895 isGlob = token.isGlob = true; 2896 finished = true; 2897 break; 2898 } 2899 } 2900 continue; 2901 } 2902 break; 2903 } 2904 } 2905 2906 if (code === CHAR_ASTERISK) { 2907 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; 2908 isGlob = token.isGlob = true; 2909 finished = true; 2910 2911 if (scanToEnd === true) { 2912 continue; 2913 } 2914 break; 2915 } 2916 2917 if (code === CHAR_QUESTION_MARK) { 2918 isGlob = token.isGlob = true; 2919 finished = true; 2920 2921 if (scanToEnd === true) { 2922 continue; 2923 } 2924 break; 2925 } 2926 2927 if (code === CHAR_LEFT_SQUARE_BRACKET) { 2928 while (eos() !== true && (next = advance())) { 2929 if (next === CHAR_BACKWARD_SLASH) { 2930 backslashes = token.backslashes = true; 2931 advance(); 2932 continue; 2933 } 2934 2935 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 2936 isBracket = token.isBracket = true; 2937 isGlob = token.isGlob = true; 2938 finished = true; 2939 break; 2940 } 2941 } 2942 2943 if (scanToEnd === true) { 2944 continue; 2945 } 2946 2947 break; 2948 } 2949 2950 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { 2951 negated = token.negated = true; 2952 start++; 2953 continue; 2954 } 2955 2956 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { 2957 isGlob = token.isGlob = true; 2958 2959 if (scanToEnd === true) { 2960 while (eos() !== true && (code = advance())) { 2961 if (code === CHAR_LEFT_PARENTHESES) { 2962 backslashes = token.backslashes = true; 2963 code = advance(); 2964 continue; 2965 } 2966 2967 if (code === CHAR_RIGHT_PARENTHESES) { 2968 finished = true; 2969 break; 2970 } 2971 } 2972 continue; 2973 } 2974 break; 2975 } 2976 2977 if (isGlob === true) { 2978 finished = true; 2979 2980 if (scanToEnd === true) { 2981 continue; 2982 } 2983 2984 break; 2985 } 2986 } 2987 2988 if (opts.noext === true) { 2989 isExtglob = false; 2990 isGlob = false; 2991 } 2992 2993 let base = str; 2994 let prefix = ''; 2995 let glob = ''; 2996 2997 if (start > 0) { 2998 prefix = str.slice(0, start); 2999 str = str.slice(start); 3000 lastIndex -= start; 3001 } 3002 3003 if (base && isGlob === true && lastIndex > 0) { 3004 base = str.slice(0, lastIndex); 3005 glob = str.slice(lastIndex); 3006 } else if (isGlob === true) { 3007 base = ''; 3008 glob = str; 3009 } else { 3010 base = str; 3011 } 3012 3013 if (base && base !== '' && base !== '/' && base !== str) { 3014 if (isPathSeparator(base.charCodeAt(base.length - 1))) { 3015 base = base.slice(0, -1); 3016 } 3017 } 3018 3019 if (opts.unescape === true) { 3020 if (glob) glob = utils.removeBackslashes(glob); 3021 3022 if (base && backslashes === true) { 3023 base = utils.removeBackslashes(base); 3024 } 3025 } 3026 3027 const state = { 3028 prefix, 3029 input, 3030 start, 3031 base, 3032 glob, 3033 isBrace, 3034 isBracket, 3035 isGlob, 3036 isExtglob, 3037 isGlobstar, 3038 negated, 3039 negatedExtglob 3040 }; 3041 3042 if (opts.tokens === true) { 3043 state.maxDepth = 0; 3044 if (!isPathSeparator(code)) { 3045 tokens.push(token); 3046 } 3047 state.tokens = tokens; 3048 } 3049 3050 if (opts.parts === true || opts.tokens === true) { 3051 let prevIndex; 3052 3053 for (let idx = 0; idx < slashes.length; idx++) { 3054 const n = prevIndex ? prevIndex + 1 : start; 3055 const i = slashes[idx]; 3056 const value = input.slice(n, i); 3057 if (opts.tokens) { 3058 if (idx === 0 && start !== 0) { 3059 tokens[idx].isPrefix = true; 3060 tokens[idx].value = prefix; 3061 } else { 3062 tokens[idx].value = value; 3063 } 3064 depth(tokens[idx]); 3065 state.maxDepth += tokens[idx].depth; 3066 } 3067 if (idx !== 0 || value !== '') { 3068 parts.push(value); 3069 } 3070 prevIndex = i; 3071 } 3072 3073 if (prevIndex && prevIndex + 1 < input.length) { 3074 const value = input.slice(prevIndex + 1); 3075 parts.push(value); 3076 3077 if (opts.tokens) { 3078 tokens[tokens.length - 1].value = value; 3079 depth(tokens[tokens.length - 1]); 3080 state.maxDepth += tokens[tokens.length - 1].depth; 3081 } 3082 } 3083 3084 state.slashes = slashes; 3085 state.parts = parts; 3086 } 3087 3088 return state; 3089 }; 3090 3091 scan_1 = scan; 3092 return scan_1; 3093 } 3094 3095 var parse_1$1; 3096 var hasRequiredParse$1; 3097 3098 function requireParse$1 () { 3099 if (hasRequiredParse$1) return parse_1$1; 3100 hasRequiredParse$1 = 1; 3101 3102 const constants = /*@__PURE__*/ requireConstants$2(); 3103 const utils = /*@__PURE__*/ requireUtils$1(); 3104 3105 /** 3106 * Constants 3107 */ 3108 3109 const { 3110 MAX_LENGTH, 3111 POSIX_REGEX_SOURCE, 3112 REGEX_NON_SPECIAL_CHARS, 3113 REGEX_SPECIAL_CHARS_BACKREF, 3114 REPLACEMENTS 3115 } = constants; 3116 3117 /** 3118 * Helpers 3119 */ 3120 3121 const expandRange = (args, options) => { 3122 if (typeof options.expandRange === 'function') { 3123 return options.expandRange(...args, options); 3124 } 3125 3126 args.sort(); 3127 const value = `[${args.join('-')}]`; 3128 3129 return value; 3130 }; 3131 3132 /** 3133 * Create the message for a syntax error 3134 */ 3135 3136 const syntaxError = (type, char) => { 3137 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; 3138 }; 3139 3140 /** 3141 * Parse the given input string. 3142 * @param {String} input 3143 * @param {Object} options 3144 * @return {Object} 3145 */ 3146 3147 const parse = (input, options) => { 3148 if (typeof input !== 'string') { 3149 throw new TypeError('Expected a string'); 3150 } 3151 3152 input = REPLACEMENTS[input] || input; 3153 3154 const opts = { ...options }; 3155 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 3156 3157 let len = input.length; 3158 if (len > max) { 3159 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 3160 } 3161 3162 const bos = { type: 'bos', value: '', output: opts.prepend || '' }; 3163 const tokens = [bos]; 3164 3165 const capture = opts.capture ? '' : '?:'; 3166 const win32 = utils.isWindows(options); 3167 3168 // create constants based on platform, for windows or posix 3169 const PLATFORM_CHARS = constants.globChars(win32); 3170 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); 3171 3172 const { 3173 DOT_LITERAL, 3174 PLUS_LITERAL, 3175 SLASH_LITERAL, 3176 ONE_CHAR, 3177 DOTS_SLASH, 3178 NO_DOT, 3179 NO_DOT_SLASH, 3180 NO_DOTS_SLASH, 3181 QMARK, 3182 QMARK_NO_DOT, 3183 STAR, 3184 START_ANCHOR 3185 } = PLATFORM_CHARS; 3186 3187 const globstar = opts => { 3188 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 3189 }; 3190 3191 const nodot = opts.dot ? '' : NO_DOT; 3192 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; 3193 let star = opts.bash === true ? globstar(opts) : STAR; 3194 3195 if (opts.capture) { 3196 star = `(${star})`; 3197 } 3198 3199 // minimatch options support 3200 if (typeof opts.noext === 'boolean') { 3201 opts.noextglob = opts.noext; 3202 } 3203 3204 const state = { 3205 input, 3206 index: -1, 3207 start: 0, 3208 dot: opts.dot === true, 3209 consumed: '', 3210 output: '', 3211 prefix: '', 3212 backtrack: false, 3213 negated: false, 3214 brackets: 0, 3215 braces: 0, 3216 parens: 0, 3217 quotes: 0, 3218 globstar: false, 3219 tokens 3220 }; 3221 3222 input = utils.removePrefix(input, state); 3223 len = input.length; 3224 3225 const extglobs = []; 3226 const braces = []; 3227 const stack = []; 3228 let prev = bos; 3229 let value; 3230 3231 /** 3232 * Tokenizing helpers 3233 */ 3234 3235 const eos = () => state.index === len - 1; 3236 const peek = state.peek = (n = 1) => input[state.index + n]; 3237 const advance = state.advance = () => input[++state.index] || ''; 3238 const remaining = () => input.slice(state.index + 1); 3239 const consume = (value = '', num = 0) => { 3240 state.consumed += value; 3241 state.index += num; 3242 }; 3243 3244 const append = token => { 3245 state.output += token.output != null ? token.output : token.value; 3246 consume(token.value); 3247 }; 3248 3249 const negate = () => { 3250 let count = 1; 3251 3252 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { 3253 advance(); 3254 state.start++; 3255 count++; 3256 } 3257 3258 if (count % 2 === 0) { 3259 return false; 3260 } 3261 3262 state.negated = true; 3263 state.start++; 3264 return true; 3265 }; 3266 3267 const increment = type => { 3268 state[type]++; 3269 stack.push(type); 3270 }; 3271 3272 const decrement = type => { 3273 state[type]--; 3274 stack.pop(); 3275 }; 3276 3277 /** 3278 * Push tokens onto the tokens array. This helper speeds up 3279 * tokenizing by 1) helping us avoid backtracking as much as possible, 3280 * and 2) helping us avoid creating extra tokens when consecutive 3281 * characters are plain text. This improves performance and simplifies 3282 * lookbehinds. 3283 */ 3284 3285 const push = tok => { 3286 if (prev.type === 'globstar') { 3287 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); 3288 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); 3289 3290 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { 3291 state.output = state.output.slice(0, -prev.output.length); 3292 prev.type = 'star'; 3293 prev.value = '*'; 3294 prev.output = star; 3295 state.output += prev.output; 3296 } 3297 } 3298 3299 if (extglobs.length && tok.type !== 'paren') { 3300 extglobs[extglobs.length - 1].inner += tok.value; 3301 } 3302 3303 if (tok.value || tok.output) append(tok); 3304 if (prev && prev.type === 'text' && tok.type === 'text') { 3305 prev.value += tok.value; 3306 prev.output = (prev.output || '') + tok.value; 3307 return; 3308 } 3309 3310 tok.prev = prev; 3311 tokens.push(tok); 3312 prev = tok; 3313 }; 3314 3315 const extglobOpen = (type, value) => { 3316 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; 3317 3318 token.prev = prev; 3319 token.parens = state.parens; 3320 token.output = state.output; 3321 const output = (opts.capture ? '(' : '') + token.open; 3322 3323 increment('parens'); 3324 push({ type, value, output: state.output ? '' : ONE_CHAR }); 3325 push({ type: 'paren', extglob: true, value: advance(), output }); 3326 extglobs.push(token); 3327 }; 3328 3329 const extglobClose = token => { 3330 let output = token.close + (opts.capture ? ')' : ''); 3331 let rest; 3332 3333 if (token.type === 'negate') { 3334 let extglobStar = star; 3335 3336 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { 3337 extglobStar = globstar(opts); 3338 } 3339 3340 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { 3341 output = token.close = `)$))${extglobStar}`; 3342 } 3343 3344 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { 3345 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. 3346 // In this case, we need to parse the string and use it in the output of the original pattern. 3347 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. 3348 // 3349 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. 3350 const expression = parse(rest, { ...options, fastpaths: false }).output; 3351 3352 output = token.close = `)${expression})${extglobStar})`; 3353 } 3354 3355 if (token.prev.type === 'bos') { 3356 state.negatedExtglob = true; 3357 } 3358 } 3359 3360 push({ type: 'paren', extglob: true, value, output }); 3361 decrement('parens'); 3362 }; 3363 3364 /** 3365 * Fast paths 3366 */ 3367 3368 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { 3369 let backslashes = false; 3370 3371 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { 3372 if (first === '\\') { 3373 backslashes = true; 3374 return m; 3375 } 3376 3377 if (first === '?') { 3378 if (esc) { 3379 return esc + first + (rest ? QMARK.repeat(rest.length) : ''); 3380 } 3381 if (index === 0) { 3382 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); 3383 } 3384 return QMARK.repeat(chars.length); 3385 } 3386 3387 if (first === '.') { 3388 return DOT_LITERAL.repeat(chars.length); 3389 } 3390 3391 if (first === '*') { 3392 if (esc) { 3393 return esc + first + (rest ? star : ''); 3394 } 3395 return star; 3396 } 3397 return esc ? m : `\\${m}`; 3398 }); 3399 3400 if (backslashes === true) { 3401 if (opts.unescape === true) { 3402 output = output.replace(/\\/g, ''); 3403 } else { 3404 output = output.replace(/\\+/g, m => { 3405 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); 3406 }); 3407 } 3408 } 3409 3410 if (output === input && opts.contains === true) { 3411 state.output = input; 3412 return state; 3413 } 3414 3415 state.output = utils.wrapOutput(output, state, options); 3416 return state; 3417 } 3418 3419 /** 3420 * Tokenize input until we reach end-of-string 3421 */ 3422 3423 while (!eos()) { 3424 value = advance(); 3425 3426 if (value === '\u0000') { 3427 continue; 3428 } 3429 3430 /** 3431 * Escaped characters 3432 */ 3433 3434 if (value === '\\') { 3435 const next = peek(); 3436 3437 if (next === '/' && opts.bash !== true) { 3438 continue; 3439 } 3440 3441 if (next === '.' || next === ';') { 3442 continue; 3443 } 3444 3445 if (!next) { 3446 value += '\\'; 3447 push({ type: 'text', value }); 3448 continue; 3449 } 3450 3451 // collapse slashes to reduce potential for exploits 3452 const match = /^\\+/.exec(remaining()); 3453 let slashes = 0; 3454 3455 if (match && match[0].length > 2) { 3456 slashes = match[0].length; 3457 state.index += slashes; 3458 if (slashes % 2 !== 0) { 3459 value += '\\'; 3460 } 3461 } 3462 3463 if (opts.unescape === true) { 3464 value = advance(); 3465 } else { 3466 value += advance(); 3467 } 3468 3469 if (state.brackets === 0) { 3470 push({ type: 'text', value }); 3471 continue; 3472 } 3473 } 3474 3475 /** 3476 * If we're inside a regex character class, continue 3477 * until we reach the closing bracket. 3478 */ 3479 3480 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { 3481 if (opts.posix !== false && value === ':') { 3482 const inner = prev.value.slice(1); 3483 if (inner.includes('[')) { 3484 prev.posix = true; 3485 3486 if (inner.includes(':')) { 3487 const idx = prev.value.lastIndexOf('['); 3488 const pre = prev.value.slice(0, idx); 3489 const rest = prev.value.slice(idx + 2); 3490 const posix = POSIX_REGEX_SOURCE[rest]; 3491 if (posix) { 3492 prev.value = pre + posix; 3493 state.backtrack = true; 3494 advance(); 3495 3496 if (!bos.output && tokens.indexOf(prev) === 1) { 3497 bos.output = ONE_CHAR; 3498 } 3499 continue; 3500 } 3501 } 3502 } 3503 } 3504 3505 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { 3506 value = `\\${value}`; 3507 } 3508 3509 if (value === ']' && (prev.value === '[' || prev.value === '[^')) { 3510 value = `\\${value}`; 3511 } 3512 3513 if (opts.posix === true && value === '!' && prev.value === '[') { 3514 value = '^'; 3515 } 3516 3517 prev.value += value; 3518 append({ value }); 3519 continue; 3520 } 3521 3522 /** 3523 * If we're inside a quoted string, continue 3524 * until we reach the closing double quote. 3525 */ 3526 3527 if (state.quotes === 1 && value !== '"') { 3528 value = utils.escapeRegex(value); 3529 prev.value += value; 3530 append({ value }); 3531 continue; 3532 } 3533 3534 /** 3535 * Double quotes 3536 */ 3537 3538 if (value === '"') { 3539 state.quotes = state.quotes === 1 ? 0 : 1; 3540 if (opts.keepQuotes === true) { 3541 push({ type: 'text', value }); 3542 } 3543 continue; 3544 } 3545 3546 /** 3547 * Parentheses 3548 */ 3549 3550 if (value === '(') { 3551 increment('parens'); 3552 push({ type: 'paren', value }); 3553 continue; 3554 } 3555 3556 if (value === ')') { 3557 if (state.parens === 0 && opts.strictBrackets === true) { 3558 throw new SyntaxError(syntaxError('opening', '(')); 3559 } 3560 3561 const extglob = extglobs[extglobs.length - 1]; 3562 if (extglob && state.parens === extglob.parens + 1) { 3563 extglobClose(extglobs.pop()); 3564 continue; 3565 } 3566 3567 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); 3568 decrement('parens'); 3569 continue; 3570 } 3571 3572 /** 3573 * Square brackets 3574 */ 3575 3576 if (value === '[') { 3577 if (opts.nobracket === true || !remaining().includes(']')) { 3578 if (opts.nobracket !== true && opts.strictBrackets === true) { 3579 throw new SyntaxError(syntaxError('closing', ']')); 3580 } 3581 3582 value = `\\${value}`; 3583 } else { 3584 increment('brackets'); 3585 } 3586 3587 push({ type: 'bracket', value }); 3588 continue; 3589 } 3590 3591 if (value === ']') { 3592 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { 3593 push({ type: 'text', value, output: `\\${value}` }); 3594 continue; 3595 } 3596 3597 if (state.brackets === 0) { 3598 if (opts.strictBrackets === true) { 3599 throw new SyntaxError(syntaxError('opening', '[')); 3600 } 3601 3602 push({ type: 'text', value, output: `\\${value}` }); 3603 continue; 3604 } 3605 3606 decrement('brackets'); 3607 3608 const prevValue = prev.value.slice(1); 3609 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { 3610 value = `/${value}`; 3611 } 3612 3613 prev.value += value; 3614 append({ value }); 3615 3616 // when literal brackets are explicitly disabled 3617 // assume we should match with a regex character class 3618 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { 3619 continue; 3620 } 3621 3622 const escaped = utils.escapeRegex(prev.value); 3623 state.output = state.output.slice(0, -prev.value.length); 3624 3625 // when literal brackets are explicitly enabled 3626 // assume we should escape the brackets to match literal characters 3627 if (opts.literalBrackets === true) { 3628 state.output += escaped; 3629 prev.value = escaped; 3630 continue; 3631 } 3632 3633 // when the user specifies nothing, try to match both 3634 prev.value = `(${capture}${escaped}|${prev.value})`; 3635 state.output += prev.value; 3636 continue; 3637 } 3638 3639 /** 3640 * Braces 3641 */ 3642 3643 if (value === '{' && opts.nobrace !== true) { 3644 increment('braces'); 3645 3646 const open = { 3647 type: 'brace', 3648 value, 3649 output: '(', 3650 outputIndex: state.output.length, 3651 tokensIndex: state.tokens.length 3652 }; 3653 3654 braces.push(open); 3655 push(open); 3656 continue; 3657 } 3658 3659 if (value === '}') { 3660 const brace = braces[braces.length - 1]; 3661 3662 if (opts.nobrace === true || !brace) { 3663 push({ type: 'text', value, output: value }); 3664 continue; 3665 } 3666 3667 let output = ')'; 3668 3669 if (brace.dots === true) { 3670 const arr = tokens.slice(); 3671 const range = []; 3672 3673 for (let i = arr.length - 1; i >= 0; i--) { 3674 tokens.pop(); 3675 if (arr[i].type === 'brace') { 3676 break; 3677 } 3678 if (arr[i].type !== 'dots') { 3679 range.unshift(arr[i].value); 3680 } 3681 } 3682 3683 output = expandRange(range, opts); 3684 state.backtrack = true; 3685 } 3686 3687 if (brace.comma !== true && brace.dots !== true) { 3688 const out = state.output.slice(0, brace.outputIndex); 3689 const toks = state.tokens.slice(brace.tokensIndex); 3690 brace.value = brace.output = '\\{'; 3691 value = output = '\\}'; 3692 state.output = out; 3693 for (const t of toks) { 3694 state.output += (t.output || t.value); 3695 } 3696 } 3697 3698 push({ type: 'brace', value, output }); 3699 decrement('braces'); 3700 braces.pop(); 3701 continue; 3702 } 3703 3704 /** 3705 * Pipes 3706 */ 3707 3708 if (value === '|') { 3709 if (extglobs.length > 0) { 3710 extglobs[extglobs.length - 1].conditions++; 3711 } 3712 push({ type: 'text', value }); 3713 continue; 3714 } 3715 3716 /** 3717 * Commas 3718 */ 3719 3720 if (value === ',') { 3721 let output = value; 3722 3723 const brace = braces[braces.length - 1]; 3724 if (brace && stack[stack.length - 1] === 'braces') { 3725 brace.comma = true; 3726 output = '|'; 3727 } 3728 3729 push({ type: 'comma', value, output }); 3730 continue; 3731 } 3732 3733 /** 3734 * Slashes 3735 */ 3736 3737 if (value === '/') { 3738 // if the beginning of the glob is "./", advance the start 3739 // to the current index, and don't add the "./" characters 3740 // to the state. This greatly simplifies lookbehinds when 3741 // checking for BOS characters like "!" and "." (not "./") 3742 if (prev.type === 'dot' && state.index === state.start + 1) { 3743 state.start = state.index + 1; 3744 state.consumed = ''; 3745 state.output = ''; 3746 tokens.pop(); 3747 prev = bos; // reset "prev" to the first token 3748 continue; 3749 } 3750 3751 push({ type: 'slash', value, output: SLASH_LITERAL }); 3752 continue; 3753 } 3754 3755 /** 3756 * Dots 3757 */ 3758 3759 if (value === '.') { 3760 if (state.braces > 0 && prev.type === 'dot') { 3761 if (prev.value === '.') prev.output = DOT_LITERAL; 3762 const brace = braces[braces.length - 1]; 3763 prev.type = 'dots'; 3764 prev.output += value; 3765 prev.value += value; 3766 brace.dots = true; 3767 continue; 3768 } 3769 3770 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { 3771 push({ type: 'text', value, output: DOT_LITERAL }); 3772 continue; 3773 } 3774 3775 push({ type: 'dot', value, output: DOT_LITERAL }); 3776 continue; 3777 } 3778 3779 /** 3780 * Question marks 3781 */ 3782 3783 if (value === '?') { 3784 const isGroup = prev && prev.value === '('; 3785 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 3786 extglobOpen('qmark', value); 3787 continue; 3788 } 3789 3790 if (prev && prev.type === 'paren') { 3791 const next = peek(); 3792 let output = value; 3793 3794 if (next === '<' && !utils.supportsLookbehinds()) { 3795 throw new Error('Node.js v10 or higher is required for regex lookbehinds'); 3796 } 3797 3798 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { 3799 output = `\\${value}`; 3800 } 3801 3802 push({ type: 'text', value, output }); 3803 continue; 3804 } 3805 3806 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { 3807 push({ type: 'qmark', value, output: QMARK_NO_DOT }); 3808 continue; 3809 } 3810 3811 push({ type: 'qmark', value, output: QMARK }); 3812 continue; 3813 } 3814 3815 /** 3816 * Exclamation 3817 */ 3818 3819 if (value === '!') { 3820 if (opts.noextglob !== true && peek() === '(') { 3821 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { 3822 extglobOpen('negate', value); 3823 continue; 3824 } 3825 } 3826 3827 if (opts.nonegate !== true && state.index === 0) { 3828 negate(); 3829 continue; 3830 } 3831 } 3832 3833 /** 3834 * Plus 3835 */ 3836 3837 if (value === '+') { 3838 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 3839 extglobOpen('plus', value); 3840 continue; 3841 } 3842 3843 if ((prev && prev.value === '(') || opts.regex === false) { 3844 push({ type: 'plus', value, output: PLUS_LITERAL }); 3845 continue; 3846 } 3847 3848 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { 3849 push({ type: 'plus', value }); 3850 continue; 3851 } 3852 3853 push({ type: 'plus', value: PLUS_LITERAL }); 3854 continue; 3855 } 3856 3857 /** 3858 * Plain text 3859 */ 3860 3861 if (value === '@') { 3862 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 3863 push({ type: 'at', extglob: true, value, output: '' }); 3864 continue; 3865 } 3866 3867 push({ type: 'text', value }); 3868 continue; 3869 } 3870 3871 /** 3872 * Plain text 3873 */ 3874 3875 if (value !== '*') { 3876 if (value === '$' || value === '^') { 3877 value = `\\${value}`; 3878 } 3879 3880 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); 3881 if (match) { 3882 value += match[0]; 3883 state.index += match[0].length; 3884 } 3885 3886 push({ type: 'text', value }); 3887 continue; 3888 } 3889 3890 /** 3891 * Stars 3892 */ 3893 3894 if (prev && (prev.type === 'globstar' || prev.star === true)) { 3895 prev.type = 'star'; 3896 prev.star = true; 3897 prev.value += value; 3898 prev.output = star; 3899 state.backtrack = true; 3900 state.globstar = true; 3901 consume(value); 3902 continue; 3903 } 3904 3905 let rest = remaining(); 3906 if (opts.noextglob !== true && /^\([^?]/.test(rest)) { 3907 extglobOpen('star', value); 3908 continue; 3909 } 3910 3911 if (prev.type === 'star') { 3912 if (opts.noglobstar === true) { 3913 consume(value); 3914 continue; 3915 } 3916 3917 const prior = prev.prev; 3918 const before = prior.prev; 3919 const isStart = prior.type === 'slash' || prior.type === 'bos'; 3920 const afterStar = before && (before.type === 'star' || before.type === 'globstar'); 3921 3922 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { 3923 push({ type: 'star', value, output: '' }); 3924 continue; 3925 } 3926 3927 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); 3928 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); 3929 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { 3930 push({ type: 'star', value, output: '' }); 3931 continue; 3932 } 3933 3934 // strip consecutive `/**/` 3935 while (rest.slice(0, 3) === '/**') { 3936 const after = input[state.index + 4]; 3937 if (after && after !== '/') { 3938 break; 3939 } 3940 rest = rest.slice(3); 3941 consume('/**', 3); 3942 } 3943 3944 if (prior.type === 'bos' && eos()) { 3945 prev.type = 'globstar'; 3946 prev.value += value; 3947 prev.output = globstar(opts); 3948 state.output = prev.output; 3949 state.globstar = true; 3950 consume(value); 3951 continue; 3952 } 3953 3954 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { 3955 state.output = state.output.slice(0, -(prior.output + prev.output).length); 3956 prior.output = `(?:${prior.output}`; 3957 3958 prev.type = 'globstar'; 3959 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); 3960 prev.value += value; 3961 state.globstar = true; 3962 state.output += prior.output + prev.output; 3963 consume(value); 3964 continue; 3965 } 3966 3967 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { 3968 const end = rest[1] !== void 0 ? '|$' : ''; 3969 3970 state.output = state.output.slice(0, -(prior.output + prev.output).length); 3971 prior.output = `(?:${prior.output}`; 3972 3973 prev.type = 'globstar'; 3974 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; 3975 prev.value += value; 3976 3977 state.output += prior.output + prev.output; 3978 state.globstar = true; 3979 3980 consume(value + advance()); 3981 3982 push({ type: 'slash', value: '/', output: '' }); 3983 continue; 3984 } 3985 3986 if (prior.type === 'bos' && rest[0] === '/') { 3987 prev.type = 'globstar'; 3988 prev.value += value; 3989 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; 3990 state.output = prev.output; 3991 state.globstar = true; 3992 consume(value + advance()); 3993 push({ type: 'slash', value: '/', output: '' }); 3994 continue; 3995 } 3996 3997 // remove single star from output 3998 state.output = state.output.slice(0, -prev.output.length); 3999 4000 // reset previous token to globstar 4001 prev.type = 'globstar'; 4002 prev.output = globstar(opts); 4003 prev.value += value; 4004 4005 // reset output with globstar 4006 state.output += prev.output; 4007 state.globstar = true; 4008 consume(value); 4009 continue; 4010 } 4011 4012 const token = { type: 'star', value, output: star }; 4013 4014 if (opts.bash === true) { 4015 token.output = '.*?'; 4016 if (prev.type === 'bos' || prev.type === 'slash') { 4017 token.output = nodot + token.output; 4018 } 4019 push(token); 4020 continue; 4021 } 4022 4023 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { 4024 token.output = value; 4025 push(token); 4026 continue; 4027 } 4028 4029 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { 4030 if (prev.type === 'dot') { 4031 state.output += NO_DOT_SLASH; 4032 prev.output += NO_DOT_SLASH; 4033 4034 } else if (opts.dot === true) { 4035 state.output += NO_DOTS_SLASH; 4036 prev.output += NO_DOTS_SLASH; 4037 4038 } else { 4039 state.output += nodot; 4040 prev.output += nodot; 4041 } 4042 4043 if (peek() !== '*') { 4044 state.output += ONE_CHAR; 4045 prev.output += ONE_CHAR; 4046 } 4047 } 4048 4049 push(token); 4050 } 4051 4052 while (state.brackets > 0) { 4053 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); 4054 state.output = utils.escapeLast(state.output, '['); 4055 decrement('brackets'); 4056 } 4057 4058 while (state.parens > 0) { 4059 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); 4060 state.output = utils.escapeLast(state.output, '('); 4061 decrement('parens'); 4062 } 4063 4064 while (state.braces > 0) { 4065 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); 4066 state.output = utils.escapeLast(state.output, '{'); 4067 decrement('braces'); 4068 } 4069 4070 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { 4071 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); 4072 } 4073 4074 // rebuild the output if we had to backtrack at any point 4075 if (state.backtrack === true) { 4076 state.output = ''; 4077 4078 for (const token of state.tokens) { 4079 state.output += token.output != null ? token.output : token.value; 4080 4081 if (token.suffix) { 4082 state.output += token.suffix; 4083 } 4084 } 4085 } 4086 4087 return state; 4088 }; 4089 4090 /** 4091 * Fast paths for creating regular expressions for common glob patterns. 4092 * This can significantly speed up processing and has very little downside 4093 * impact when none of the fast paths match. 4094 */ 4095 4096 parse.fastpaths = (input, options) => { 4097 const opts = { ...options }; 4098 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 4099 const len = input.length; 4100 if (len > max) { 4101 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 4102 } 4103 4104 input = REPLACEMENTS[input] || input; 4105 const win32 = utils.isWindows(options); 4106 4107 // create constants based on platform, for windows or posix 4108 const { 4109 DOT_LITERAL, 4110 SLASH_LITERAL, 4111 ONE_CHAR, 4112 DOTS_SLASH, 4113 NO_DOT, 4114 NO_DOTS, 4115 NO_DOTS_SLASH, 4116 STAR, 4117 START_ANCHOR 4118 } = constants.globChars(win32); 4119 4120 const nodot = opts.dot ? NO_DOTS : NO_DOT; 4121 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; 4122 const capture = opts.capture ? '' : '?:'; 4123 const state = { negated: false, prefix: '' }; 4124 let star = opts.bash === true ? '.*?' : STAR; 4125 4126 if (opts.capture) { 4127 star = `(${star})`; 4128 } 4129 4130 const globstar = opts => { 4131 if (opts.noglobstar === true) return star; 4132 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 4133 }; 4134 4135 const create = str => { 4136 switch (str) { 4137 case '*': 4138 return `${nodot}${ONE_CHAR}${star}`; 4139 4140 case '.*': 4141 return `${DOT_LITERAL}${ONE_CHAR}${star}`; 4142 4143 case '*.*': 4144 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 4145 4146 case '*/*': 4147 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; 4148 4149 case '**': 4150 return nodot + globstar(opts); 4151 4152 case '**/*': 4153 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; 4154 4155 case '**/*.*': 4156 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 4157 4158 case '**/.*': 4159 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; 4160 4161 default: { 4162 const match = /^(.*?)\.(\w+)$/.exec(str); 4163 if (!match) return; 4164 4165 const source = create(match[1]); 4166 if (!source) return; 4167 4168 return source + DOT_LITERAL + match[2]; 4169 } 4170 } 4171 }; 4172 4173 const output = utils.removePrefix(input, state); 4174 let source = create(output); 4175 4176 if (source && opts.strictSlashes !== true) { 4177 source += `${SLASH_LITERAL}?`; 4178 } 4179 4180 return source; 4181 }; 4182 4183 parse_1$1 = parse; 4184 return parse_1$1; 4185 } 4186 4187 var picomatch_1; 4188 var hasRequiredPicomatch$1; 4189 4190 function requirePicomatch$1 () { 4191 if (hasRequiredPicomatch$1) return picomatch_1; 4192 hasRequiredPicomatch$1 = 1; 4193 4194 const path = require$$0$1; 4195 const scan = /*@__PURE__*/ requireScan(); 4196 const parse = /*@__PURE__*/ requireParse$1(); 4197 const utils = /*@__PURE__*/ requireUtils$1(); 4198 const constants = /*@__PURE__*/ requireConstants$2(); 4199 const isObject = val => val && typeof val === 'object' && !Array.isArray(val); 4200 4201 /** 4202 * Creates a matcher function from one or more glob patterns. The 4203 * returned function takes a string to match as its first argument, 4204 * and returns true if the string is a match. The returned matcher 4205 * function also takes a boolean as the second argument that, when true, 4206 * returns an object with additional information. 4207 * 4208 * ```js 4209 * const picomatch = require('picomatch'); 4210 * // picomatch(glob[, options]); 4211 * 4212 * const isMatch = picomatch('*.!(*a)'); 4213 * console.log(isMatch('a.a')); //=> false 4214 * console.log(isMatch('a.b')); //=> true 4215 * ``` 4216 * @name picomatch 4217 * @param {String|Array} `globs` One or more glob patterns. 4218 * @param {Object=} `options` 4219 * @return {Function=} Returns a matcher function. 4220 * @api public 4221 */ 4222 4223 const picomatch = (glob, options, returnState = false) => { 4224 if (Array.isArray(glob)) { 4225 const fns = glob.map(input => picomatch(input, options, returnState)); 4226 const arrayMatcher = str => { 4227 for (const isMatch of fns) { 4228 const state = isMatch(str); 4229 if (state) return state; 4230 } 4231 return false; 4232 }; 4233 return arrayMatcher; 4234 } 4235 4236 const isState = isObject(glob) && glob.tokens && glob.input; 4237 4238 if (glob === '' || (typeof glob !== 'string' && !isState)) { 4239 throw new TypeError('Expected pattern to be a non-empty string'); 4240 } 4241 4242 const opts = options || {}; 4243 const posix = utils.isWindows(options); 4244 const regex = isState 4245 ? picomatch.compileRe(glob, options) 4246 : picomatch.makeRe(glob, options, false, true); 4247 4248 const state = regex.state; 4249 delete regex.state; 4250 4251 let isIgnored = () => false; 4252 if (opts.ignore) { 4253 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; 4254 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); 4255 } 4256 4257 const matcher = (input, returnObject = false) => { 4258 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); 4259 const result = { glob, state, regex, posix, input, output, match, isMatch }; 4260 4261 if (typeof opts.onResult === 'function') { 4262 opts.onResult(result); 4263 } 4264 4265 if (isMatch === false) { 4266 result.isMatch = false; 4267 return returnObject ? result : false; 4268 } 4269 4270 if (isIgnored(input)) { 4271 if (typeof opts.onIgnore === 'function') { 4272 opts.onIgnore(result); 4273 } 4274 result.isMatch = false; 4275 return returnObject ? result : false; 4276 } 4277 4278 if (typeof opts.onMatch === 'function') { 4279 opts.onMatch(result); 4280 } 4281 return returnObject ? result : true; 4282 }; 4283 4284 if (returnState) { 4285 matcher.state = state; 4286 } 4287 4288 return matcher; 4289 }; 4290 4291 /** 4292 * Test `input` with the given `regex`. This is used by the main 4293 * `picomatch()` function to test the input string. 4294 * 4295 * ```js 4296 * const picomatch = require('picomatch'); 4297 * // picomatch.test(input, regex[, options]); 4298 * 4299 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); 4300 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } 4301 * ``` 4302 * @param {String} `input` String to test. 4303 * @param {RegExp} `regex` 4304 * @return {Object} Returns an object with matching info. 4305 * @api public 4306 */ 4307 4308 picomatch.test = (input, regex, options, { glob, posix } = {}) => { 4309 if (typeof input !== 'string') { 4310 throw new TypeError('Expected input to be a string'); 4311 } 4312 4313 if (input === '') { 4314 return { isMatch: false, output: '' }; 4315 } 4316 4317 const opts = options || {}; 4318 const format = opts.format || (posix ? utils.toPosixSlashes : null); 4319 let match = input === glob; 4320 let output = (match && format) ? format(input) : input; 4321 4322 if (match === false) { 4323 output = format ? format(input) : input; 4324 match = output === glob; 4325 } 4326 4327 if (match === false || opts.capture === true) { 4328 if (opts.matchBase === true || opts.basename === true) { 4329 match = picomatch.matchBase(input, regex, options, posix); 4330 } else { 4331 match = regex.exec(output); 4332 } 4333 } 4334 4335 return { isMatch: Boolean(match), match, output }; 4336 }; 4337 4338 /** 4339 * Match the basename of a filepath. 4340 * 4341 * ```js 4342 * const picomatch = require('picomatch'); 4343 * // picomatch.matchBase(input, glob[, options]); 4344 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true 4345 * ``` 4346 * @param {String} `input` String to test. 4347 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). 4348 * @return {Boolean} 4349 * @api public 4350 */ 4351 4352 picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { 4353 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); 4354 return regex.test(path.basename(input)); 4355 }; 4356 4357 /** 4358 * Returns true if **any** of the given glob `patterns` match the specified `string`. 4359 * 4360 * ```js 4361 * const picomatch = require('picomatch'); 4362 * // picomatch.isMatch(string, patterns[, options]); 4363 * 4364 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true 4365 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false 4366 * ``` 4367 * @param {String|Array} str The string to test. 4368 * @param {String|Array} patterns One or more glob patterns to use for matching. 4369 * @param {Object} [options] See available [options](#options). 4370 * @return {Boolean} Returns true if any patterns match `str` 4371 * @api public 4372 */ 4373 4374 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); 4375 4376 /** 4377 * Parse a glob pattern to create the source string for a regular 4378 * expression. 4379 * 4380 * ```js 4381 * const picomatch = require('picomatch'); 4382 * const result = picomatch.parse(pattern[, options]); 4383 * ``` 4384 * @param {String} `pattern` 4385 * @param {Object} `options` 4386 * @return {Object} Returns an object with useful properties and output to be used as a regex source string. 4387 * @api public 4388 */ 4389 4390 picomatch.parse = (pattern, options) => { 4391 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); 4392 return parse(pattern, { ...options, fastpaths: false }); 4393 }; 4394 4395 /** 4396 * Scan a glob pattern to separate the pattern into segments. 4397 * 4398 * ```js 4399 * const picomatch = require('picomatch'); 4400 * // picomatch.scan(input[, options]); 4401 * 4402 * const result = picomatch.scan('!./foo/*.js'); 4403 * console.log(result); 4404 * { prefix: '!./', 4405 * input: '!./foo/*.js', 4406 * start: 3, 4407 * base: 'foo', 4408 * glob: '*.js', 4409 * isBrace: false, 4410 * isBracket: false, 4411 * isGlob: true, 4412 * isExtglob: false, 4413 * isGlobstar: false, 4414 * negated: true } 4415 * ``` 4416 * @param {String} `input` Glob pattern to scan. 4417 * @param {Object} `options` 4418 * @return {Object} Returns an object with 4419 * @api public 4420 */ 4421 4422 picomatch.scan = (input, options) => scan(input, options); 4423 4424 /** 4425 * Compile a regular expression from the `state` object returned by the 4426 * [parse()](#parse) method. 4427 * 4428 * @param {Object} `state` 4429 * @param {Object} `options` 4430 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. 4431 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. 4432 * @return {RegExp} 4433 * @api public 4434 */ 4435 4436 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { 4437 if (returnOutput === true) { 4438 return state.output; 4439 } 4440 4441 const opts = options || {}; 4442 const prepend = opts.contains ? '' : '^'; 4443 const append = opts.contains ? '' : '$'; 4444 4445 let source = `${prepend}(?:${state.output})${append}`; 4446 if (state && state.negated === true) { 4447 source = `^(?!${source}).*$`; 4448 } 4449 4450 const regex = picomatch.toRegex(source, options); 4451 if (returnState === true) { 4452 regex.state = state; 4453 } 4454 4455 return regex; 4456 }; 4457 4458 /** 4459 * Create a regular expression from a parsed glob pattern. 4460 * 4461 * ```js 4462 * const picomatch = require('picomatch'); 4463 * const state = picomatch.parse('*.js'); 4464 * // picomatch.compileRe(state[, options]); 4465 * 4466 * console.log(picomatch.compileRe(state)); 4467 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 4468 * ``` 4469 * @param {String} `state` The object returned from the `.parse` method. 4470 * @param {Object} `options` 4471 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. 4472 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. 4473 * @return {RegExp} Returns a regex created from the given pattern. 4474 * @api public 4475 */ 4476 4477 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { 4478 if (!input || typeof input !== 'string') { 4479 throw new TypeError('Expected a non-empty string'); 4480 } 4481 4482 let parsed = { negated: false, fastpaths: true }; 4483 4484 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { 4485 parsed.output = parse.fastpaths(input, options); 4486 } 4487 4488 if (!parsed.output) { 4489 parsed = parse(input, options); 4490 } 4491 4492 return picomatch.compileRe(parsed, options, returnOutput, returnState); 4493 }; 4494 4495 /** 4496 * Create a regular expression from the given regex source string. 4497 * 4498 * ```js 4499 * const picomatch = require('picomatch'); 4500 * // picomatch.toRegex(source[, options]); 4501 * 4502 * const { output } = picomatch.parse('*.js'); 4503 * console.log(picomatch.toRegex(output)); 4504 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 4505 * ``` 4506 * @param {String} `source` Regular expression source string. 4507 * @param {Object} `options` 4508 * @return {RegExp} 4509 * @api public 4510 */ 4511 4512 picomatch.toRegex = (source, options) => { 4513 try { 4514 const opts = options || {}; 4515 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); 4516 } catch (err) { 4517 if (options && options.debug === true) throw err; 4518 return /$^/; 4519 } 4520 }; 4521 4522 /** 4523 * Picomatch constants. 4524 * @return {Object} 4525 */ 4526 4527 picomatch.constants = constants; 4528 4529 /** 4530 * Expose "picomatch" 4531 */ 4532 4533 picomatch_1 = picomatch; 4534 return picomatch_1; 4535 } 4536 4537 var picomatch; 4538 var hasRequiredPicomatch; 4539 4540 function requirePicomatch () { 4541 if (hasRequiredPicomatch) return picomatch; 4542 hasRequiredPicomatch = 1; 4543 4544 picomatch = /*@__PURE__*/ requirePicomatch$1(); 4545 return picomatch; 4546 } 310 4547 311 4548 /*! … … 316 4553 */ 317 4554 318 var normalizePath$2 = function(path, stripTrailing) { 319 if (typeof path !== 'string') { 320 throw new TypeError('expected path to be a string'); 321 } 322 323 if (path === '\\' || path === '/') return '/'; 324 325 var len = path.length; 326 if (len <= 1) return path; 327 328 // ensure that win32 namespaces has two leading slashes, so that the path is 329 // handled properly by the win32 version of path.parse() after being normalized 330 // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces 331 var prefix = ''; 332 if (len > 4 && path[3] === '\\') { 333 var ch = path[2]; 334 if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') { 335 path = path.slice(2); 336 prefix = '//'; 337 } 338 } 339 340 var segs = path.split(/[/\\]+/); 341 if (stripTrailing !== false && segs[segs.length - 1] === '') { 342 segs.pop(); 343 } 344 return prefix + segs.join('/'); 345 }; 346 347 var anymatch_1 = anymatch$2.exports; 348 349 Object.defineProperty(anymatch_1, "__esModule", { value: true }); 350 351 const picomatch = rollup.picomatch; 352 const normalizePath$1 = normalizePath$2; 353 354 /** 355 * @typedef {(testString: string) => boolean} AnymatchFn 356 * @typedef {string|RegExp|AnymatchFn} AnymatchPattern 357 * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher 358 */ 359 const BANG$1 = '!'; 360 const DEFAULT_OPTIONS = {returnIndex: false}; 361 const arrify$1 = (item) => Array.isArray(item) ? item : [item]; 362 363 /** 364 * @param {AnymatchPattern} matcher 365 * @param {object} options 366 * @returns {AnymatchFn} 367 */ 368 const createPattern = (matcher, options) => { 369 if (typeof matcher === 'function') { 370 return matcher; 371 } 372 if (typeof matcher === 'string') { 373 const glob = picomatch(matcher, options); 374 return (string) => matcher === string || glob(string); 375 } 376 if (matcher instanceof RegExp) { 377 return (string) => matcher.test(string); 378 } 379 return (string) => false; 380 }; 381 382 /** 383 * @param {Array<Function>} patterns 384 * @param {Array<Function>} negPatterns 385 * @param {String|Array} args 386 * @param {Boolean} returnIndex 387 * @returns {boolean|number} 388 */ 389 const matchPatterns = (patterns, negPatterns, args, returnIndex) => { 390 const isList = Array.isArray(args); 391 const _path = isList ? args[0] : args; 392 if (!isList && typeof _path !== 'string') { 393 throw new TypeError('anymatch: second argument must be a string: got ' + 394 Object.prototype.toString.call(_path)) 395 } 396 const path = normalizePath$1(_path, false); 397 398 for (let index = 0; index < negPatterns.length; index++) { 399 const nglob = negPatterns[index]; 400 if (nglob(path)) { 401 return returnIndex ? -1 : false; 402 } 403 } 404 405 const applied = isList && [path].concat(args.slice(1)); 406 for (let index = 0; index < patterns.length; index++) { 407 const pattern = patterns[index]; 408 if (isList ? pattern(...applied) : pattern(path)) { 409 return returnIndex ? index : true; 410 } 411 } 412 413 return returnIndex ? -1 : false; 414 }; 415 416 /** 417 * @param {AnymatchMatcher} matchers 418 * @param {Array|string} testString 419 * @param {object} options 420 * @returns {boolean|number|Function} 421 */ 422 const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => { 423 if (matchers == null) { 424 throw new TypeError('anymatch: specify first argument'); 425 } 426 const opts = typeof options === 'boolean' ? {returnIndex: options} : options; 427 const returnIndex = opts.returnIndex || false; 428 429 // Early cache for matchers. 430 const mtchers = arrify$1(matchers); 431 const negatedGlobs = mtchers 432 .filter(item => typeof item === 'string' && item.charAt(0) === BANG$1) 433 .map(item => item.slice(1)) 434 .map(item => picomatch(item, opts)); 435 const patterns = mtchers 436 .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG$1)) 437 .map(matcher => createPattern(matcher, opts)); 438 439 if (testString == null) { 440 return (testString, ri = false) => { 441 const returnIndex = typeof ri === 'boolean' ? ri : false; 442 return matchPatterns(patterns, negatedGlobs, testString, returnIndex); 443 } 444 } 445 446 return matchPatterns(patterns, negatedGlobs, testString, returnIndex); 447 }; 448 449 anymatch$1.default = anymatch$1; 450 anymatch$2.exports = anymatch$1; 451 452 var anymatchExports = anymatch$2.exports; 4555 var normalizePath; 4556 var hasRequiredNormalizePath; 4557 4558 function requireNormalizePath () { 4559 if (hasRequiredNormalizePath) return normalizePath; 4560 hasRequiredNormalizePath = 1; 4561 normalizePath = function(path, stripTrailing) { 4562 if (typeof path !== 'string') { 4563 throw new TypeError('expected path to be a string'); 4564 } 4565 4566 if (path === '\\' || path === '/') return '/'; 4567 4568 var len = path.length; 4569 if (len <= 1) return path; 4570 4571 // ensure that win32 namespaces has two leading slashes, so that the path is 4572 // handled properly by the win32 version of path.parse() after being normalized 4573 // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces 4574 var prefix = ''; 4575 if (len > 4 && path[3] === '\\') { 4576 var ch = path[2]; 4577 if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') { 4578 path = path.slice(2); 4579 prefix = '//'; 4580 } 4581 } 4582 4583 var segs = path.split(/[/\\]+/); 4584 if (stripTrailing !== false && segs[segs.length - 1] === '') { 4585 segs.pop(); 4586 } 4587 return prefix + segs.join('/'); 4588 }; 4589 return normalizePath; 4590 } 4591 4592 var anymatch_1 = anymatch.exports; 4593 4594 var hasRequiredAnymatch; 4595 4596 function requireAnymatch () { 4597 if (hasRequiredAnymatch) return anymatch.exports; 4598 hasRequiredAnymatch = 1; 4599 4600 Object.defineProperty(anymatch_1, "__esModule", { value: true }); 4601 4602 const picomatch = /*@__PURE__*/ requirePicomatch(); 4603 const normalizePath = /*@__PURE__*/ requireNormalizePath(); 4604 4605 /** 4606 * @typedef {(testString: string) => boolean} AnymatchFn 4607 * @typedef {string|RegExp|AnymatchFn} AnymatchPattern 4608 * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher 4609 */ 4610 const BANG = '!'; 4611 const DEFAULT_OPTIONS = {returnIndex: false}; 4612 const arrify = (item) => Array.isArray(item) ? item : [item]; 4613 4614 /** 4615 * @param {AnymatchPattern} matcher 4616 * @param {object} options 4617 * @returns {AnymatchFn} 4618 */ 4619 const createPattern = (matcher, options) => { 4620 if (typeof matcher === 'function') { 4621 return matcher; 4622 } 4623 if (typeof matcher === 'string') { 4624 const glob = picomatch(matcher, options); 4625 return (string) => matcher === string || glob(string); 4626 } 4627 if (matcher instanceof RegExp) { 4628 return (string) => matcher.test(string); 4629 } 4630 return (string) => false; 4631 }; 4632 4633 /** 4634 * @param {Array<Function>} patterns 4635 * @param {Array<Function>} negPatterns 4636 * @param {String|Array} args 4637 * @param {Boolean} returnIndex 4638 * @returns {boolean|number} 4639 */ 4640 const matchPatterns = (patterns, negPatterns, args, returnIndex) => { 4641 const isList = Array.isArray(args); 4642 const _path = isList ? args[0] : args; 4643 if (!isList && typeof _path !== 'string') { 4644 throw new TypeError('anymatch: second argument must be a string: got ' + 4645 Object.prototype.toString.call(_path)) 4646 } 4647 const path = normalizePath(_path, false); 4648 4649 for (let index = 0; index < negPatterns.length; index++) { 4650 const nglob = negPatterns[index]; 4651 if (nglob(path)) { 4652 return returnIndex ? -1 : false; 4653 } 4654 } 4655 4656 const applied = isList && [path].concat(args.slice(1)); 4657 for (let index = 0; index < patterns.length; index++) { 4658 const pattern = patterns[index]; 4659 if (isList ? pattern(...applied) : pattern(path)) { 4660 return returnIndex ? index : true; 4661 } 4662 } 4663 4664 return returnIndex ? -1 : false; 4665 }; 4666 4667 /** 4668 * @param {AnymatchMatcher} matchers 4669 * @param {Array|string} testString 4670 * @param {object} options 4671 * @returns {boolean|number|Function} 4672 */ 4673 const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => { 4674 if (matchers == null) { 4675 throw new TypeError('anymatch: specify first argument'); 4676 } 4677 const opts = typeof options === 'boolean' ? {returnIndex: options} : options; 4678 const returnIndex = opts.returnIndex || false; 4679 4680 // Early cache for matchers. 4681 const mtchers = arrify(matchers); 4682 const negatedGlobs = mtchers 4683 .filter(item => typeof item === 'string' && item.charAt(0) === BANG) 4684 .map(item => item.slice(1)) 4685 .map(item => picomatch(item, opts)); 4686 const patterns = mtchers 4687 .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG)) 4688 .map(matcher => createPattern(matcher, opts)); 4689 4690 if (testString == null) { 4691 return (testString, ri = false) => { 4692 const returnIndex = typeof ri === 'boolean' ? ri : false; 4693 return matchPatterns(patterns, negatedGlobs, testString, returnIndex); 4694 } 4695 } 4696 4697 return matchPatterns(patterns, negatedGlobs, testString, returnIndex); 4698 }; 4699 4700 anymatch$1.default = anymatch$1; 4701 anymatch.exports = anymatch$1; 4702 return anymatch.exports; 4703 } 453 4704 454 4705 /*! … … 459 4710 */ 460 4711 461 var isExtglob$1 = function isExtglob(str) { 462 if (typeof str !== 'string' || str === '') { 463 return false; 464 } 465 466 var match; 467 while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { 468 if (match[2]) return true; 469 str = str.slice(match.index + match[0].length); 470 } 471 472 return false; 473 }; 4712 var isExtglob; 4713 var hasRequiredIsExtglob; 4714 4715 function requireIsExtglob () { 4716 if (hasRequiredIsExtglob) return isExtglob; 4717 hasRequiredIsExtglob = 1; 4718 isExtglob = function isExtglob(str) { 4719 if (typeof str !== 'string' || str === '') { 4720 return false; 4721 } 4722 4723 var match; 4724 while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { 4725 if (match[2]) return true; 4726 str = str.slice(match.index + match[0].length); 4727 } 4728 4729 return false; 4730 }; 4731 return isExtglob; 4732 } 474 4733 475 4734 /*! … … 480 4739 */ 481 4740 482 var isExtglob = isExtglob$1; 483 var chars = { '{': '}', '(': ')', '[': ']'}; 484 var strictCheck = function(str) { 485 if (str[0] === '!') { 486 return true; 487 } 488 var index = 0; 489 var pipeIndex = -2; 490 var closeSquareIndex = -2; 491 var closeCurlyIndex = -2; 492 var closeParenIndex = -2; 493 var backSlashIndex = -2; 494 while (index < str.length) { 495 if (str[index] === '*') { 496 return true; 497 } 498 499 if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) { 500 return true; 501 } 502 503 if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') { 504 if (closeSquareIndex < index) { 505 closeSquareIndex = str.indexOf(']', index); 506 } 507 if (closeSquareIndex > index) { 508 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { 509 return true; 510 } 511 backSlashIndex = str.indexOf('\\', index); 512 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { 513 return true; 514 } 515 } 516 } 517 518 if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') { 519 closeCurlyIndex = str.indexOf('}', index); 520 if (closeCurlyIndex > index) { 521 backSlashIndex = str.indexOf('\\', index); 522 if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) { 523 return true; 524 } 525 } 526 } 527 528 if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') { 529 closeParenIndex = str.indexOf(')', index); 530 if (closeParenIndex > index) { 531 backSlashIndex = str.indexOf('\\', index); 532 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { 533 return true; 534 } 535 } 536 } 537 538 if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') { 539 if (pipeIndex < index) { 540 pipeIndex = str.indexOf('|', index); 541 } 542 if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') { 543 closeParenIndex = str.indexOf(')', pipeIndex); 544 if (closeParenIndex > pipeIndex) { 545 backSlashIndex = str.indexOf('\\', pipeIndex); 546 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { 547 return true; 548 } 549 } 550 } 551 } 552 553 if (str[index] === '\\') { 554 var open = str[index + 1]; 555 index += 2; 556 var close = chars[open]; 557 558 if (close) { 559 var n = str.indexOf(close, index); 560 if (n !== -1) { 561 index = n + 1; 562 } 563 } 564 565 if (str[index] === '!') { 566 return true; 567 } 568 } else { 569 index++; 570 } 571 } 572 return false; 573 }; 574 575 var relaxedCheck = function(str) { 576 if (str[0] === '!') { 577 return true; 578 } 579 var index = 0; 580 while (index < str.length) { 581 if (/[*?{}()[\]]/.test(str[index])) { 582 return true; 583 } 584 585 if (str[index] === '\\') { 586 var open = str[index + 1]; 587 index += 2; 588 var close = chars[open]; 589 590 if (close) { 591 var n = str.indexOf(close, index); 592 if (n !== -1) { 593 index = n + 1; 594 } 595 } 596 597 if (str[index] === '!') { 598 return true; 599 } 600 } else { 601 index++; 602 } 603 } 604 return false; 605 }; 606 607 var isGlob$2 = function isGlob(str, options) { 608 if (typeof str !== 'string' || str === '') { 609 return false; 610 } 611 612 if (isExtglob(str)) { 613 return true; 614 } 615 616 var check = strictCheck; 617 618 // optionally relax check 619 if (options && options.strict === false) { 620 check = relaxedCheck; 621 } 622 623 return check(str); 624 }; 625 626 var isGlob$1 = isGlob$2; 627 var pathPosixDirname = require$$0$2.posix.dirname; 628 var isWin32 = require$$2$1.platform() === 'win32'; 629 630 var slash = '/'; 631 var backslash = /\\/g; 632 var enclosure = /[\{\[].*[\}\]]$/; 633 var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; 634 var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; 635 636 /** 637 * @param {string} str 638 * @param {Object} opts 639 * @param {boolean} [opts.flipBackslashes=true] 640 * @returns {string} 641 */ 642 var globParent$1 = function globParent(str, opts) { 643 var options = Object.assign({ flipBackslashes: true }, opts); 644 645 // flip windows path separators 646 if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { 647 str = str.replace(backslash, slash); 648 } 649 650 // special case for strings ending in enclosure containing path separator 651 if (enclosure.test(str)) { 652 str += slash; 653 } 654 655 // preserves full path in case of trailing path separator 656 str += 'a'; 657 658 // remove path parts that are globby 659 do { 660 str = pathPosixDirname(str); 661 } while (isGlob$1(str) || globby.test(str)); 662 663 // remove escape chars and return result 664 return str.replace(escaped, '$1'); 665 }; 666 667 var utils$3 = {}; 668 669 (function (exports) { 670 671 exports.isInteger = num => { 672 if (typeof num === 'number') { 673 return Number.isInteger(num); 674 } 675 if (typeof num === 'string' && num.trim() !== '') { 676 return Number.isInteger(Number(num)); 4741 var isGlob; 4742 var hasRequiredIsGlob; 4743 4744 function requireIsGlob () { 4745 if (hasRequiredIsGlob) return isGlob; 4746 hasRequiredIsGlob = 1; 4747 var isExtglob = /*@__PURE__*/ requireIsExtglob(); 4748 var chars = { '{': '}', '(': ')', '[': ']'}; 4749 var strictCheck = function(str) { 4750 if (str[0] === '!') { 4751 return true; 4752 } 4753 var index = 0; 4754 var pipeIndex = -2; 4755 var closeSquareIndex = -2; 4756 var closeCurlyIndex = -2; 4757 var closeParenIndex = -2; 4758 var backSlashIndex = -2; 4759 while (index < str.length) { 4760 if (str[index] === '*') { 4761 return true; 4762 } 4763 4764 if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) { 4765 return true; 4766 } 4767 4768 if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') { 4769 if (closeSquareIndex < index) { 4770 closeSquareIndex = str.indexOf(']', index); 4771 } 4772 if (closeSquareIndex > index) { 4773 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { 4774 return true; 4775 } 4776 backSlashIndex = str.indexOf('\\', index); 4777 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { 4778 return true; 4779 } 4780 } 4781 } 4782 4783 if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') { 4784 closeCurlyIndex = str.indexOf('}', index); 4785 if (closeCurlyIndex > index) { 4786 backSlashIndex = str.indexOf('\\', index); 4787 if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) { 4788 return true; 4789 } 4790 } 4791 } 4792 4793 if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') { 4794 closeParenIndex = str.indexOf(')', index); 4795 if (closeParenIndex > index) { 4796 backSlashIndex = str.indexOf('\\', index); 4797 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { 4798 return true; 4799 } 4800 } 4801 } 4802 4803 if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') { 4804 if (pipeIndex < index) { 4805 pipeIndex = str.indexOf('|', index); 4806 } 4807 if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') { 4808 closeParenIndex = str.indexOf(')', pipeIndex); 4809 if (closeParenIndex > pipeIndex) { 4810 backSlashIndex = str.indexOf('\\', pipeIndex); 4811 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { 4812 return true; 4813 } 4814 } 4815 } 4816 } 4817 4818 if (str[index] === '\\') { 4819 var open = str[index + 1]; 4820 index += 2; 4821 var close = chars[open]; 4822 4823 if (close) { 4824 var n = str.indexOf(close, index); 4825 if (n !== -1) { 4826 index = n + 1; 4827 } 4828 } 4829 4830 if (str[index] === '!') { 4831 return true; 4832 } 4833 } else { 4834 index++; 4835 } 677 4836 } 678 4837 return false; 679 4838 }; 680 4839 681 /** 682 * Find a node of the given type 683 */ 684 685 exports.find = (node, type) => node.nodes.find(node => node.type === type); 686 687 /** 688 * Find a node of the given type 689 */ 690 691 exports.exceedsLimit = (min, max, step = 1, limit) => { 692 if (limit === false) return false; 693 if (!exports.isInteger(min) || !exports.isInteger(max)) return false; 694 return ((Number(max) - Number(min)) / Number(step)) >= limit; 695 }; 696 697 /** 698 * Escape the given node with '\\' before node.value 699 */ 700 701 exports.escapeNode = (block, n = 0, type) => { 702 const node = block.nodes[n]; 703 if (!node) return; 704 705 if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { 706 if (node.escaped !== true) { 707 node.value = '\\' + node.value; 708 node.escaped = true; 709 } 710 } 711 }; 712 713 /** 714 * Returns true if the given brace node should be enclosed in literal braces 715 */ 716 717 exports.encloseBrace = node => { 718 if (node.type !== 'brace') return false; 719 if ((node.commas >> 0 + node.ranges >> 0) === 0) { 720 node.invalid = true; 4840 var relaxedCheck = function(str) { 4841 if (str[0] === '!') { 721 4842 return true; 722 4843 } 4844 var index = 0; 4845 while (index < str.length) { 4846 if (/[*?{}()[\]]/.test(str[index])) { 4847 return true; 4848 } 4849 4850 if (str[index] === '\\') { 4851 var open = str[index + 1]; 4852 index += 2; 4853 var close = chars[open]; 4854 4855 if (close) { 4856 var n = str.indexOf(close, index); 4857 if (n !== -1) { 4858 index = n + 1; 4859 } 4860 } 4861 4862 if (str[index] === '!') { 4863 return true; 4864 } 4865 } else { 4866 index++; 4867 } 4868 } 723 4869 return false; 724 4870 }; 725 4871 726 /** 727 * Returns true if a brace node is invalid. 728 */ 729 730 exports.isInvalidBrace = block => { 731 if (block.type !== 'brace') return false; 732 if (block.invalid === true || block.dollar) return true; 733 if ((block.commas >> 0 + block.ranges >> 0) === 0) { 734 block.invalid = true; 4872 isGlob = function isGlob(str, options) { 4873 if (typeof str !== 'string' || str === '') { 4874 return false; 4875 } 4876 4877 if (isExtglob(str)) { 735 4878 return true; 736 4879 } 737 if (block.open !== true || block.close !== true) { 738 block.invalid = true; 739 return true; 740 } 741 return false; 742 }; 743 744 /** 745 * Returns true if a node is an open or close node 746 */ 747 748 exports.isOpenOrClose = node => { 749 if (node.type === 'open' || node.type === 'close') { 750 return true; 751 } 752 return node.open === true || node.close === true; 753 }; 754 755 /** 756 * Reduce an array of text nodes. 757 */ 758 759 exports.reduce = nodes => nodes.reduce((acc, node) => { 760 if (node.type === 'text') acc.push(node.value); 761 if (node.type === 'range') node.type = 'text'; 762 return acc; 763 }, []); 764 765 /** 766 * Flatten an array 767 */ 768 769 exports.flatten = (...args) => { 770 const result = []; 771 772 const flat = arr => { 773 for (let i = 0; i < arr.length; i++) { 774 const ele = arr[i]; 775 776 if (Array.isArray(ele)) { 777 flat(ele); 778 continue; 779 } 780 781 if (ele !== undefined) { 782 result.push(ele); 783 } 784 } 785 return result; 4880 4881 var check = strictCheck; 4882 4883 // optionally relax check 4884 if (options && options.strict === false) { 4885 check = relaxedCheck; 4886 } 4887 4888 return check(str); 4889 }; 4890 return isGlob; 4891 } 4892 4893 var globParent; 4894 var hasRequiredGlobParent; 4895 4896 function requireGlobParent () { 4897 if (hasRequiredGlobParent) return globParent; 4898 hasRequiredGlobParent = 1; 4899 4900 var isGlob = /*@__PURE__*/ requireIsGlob(); 4901 var pathPosixDirname = require$$0$1.posix.dirname; 4902 var isWin32 = require$$2$1.platform() === 'win32'; 4903 4904 var slash = '/'; 4905 var backslash = /\\/g; 4906 var enclosure = /[\{\[].*[\}\]]$/; 4907 var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; 4908 var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; 4909 4910 /** 4911 * @param {string} str 4912 * @param {Object} opts 4913 * @param {boolean} [opts.flipBackslashes=true] 4914 * @returns {string} 4915 */ 4916 globParent = function globParent(str, opts) { 4917 var options = Object.assign({ flipBackslashes: true }, opts); 4918 4919 // flip windows path separators 4920 if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { 4921 str = str.replace(backslash, slash); 4922 } 4923 4924 // special case for strings ending in enclosure containing path separator 4925 if (enclosure.test(str)) { 4926 str += slash; 4927 } 4928 4929 // preserves full path in case of trailing path separator 4930 str += 'a'; 4931 4932 // remove path parts that are globby 4933 do { 4934 str = pathPosixDirname(str); 4935 } while (isGlob(str) || globby.test(str)); 4936 4937 // remove escape chars and return result 4938 return str.replace(escaped, '$1'); 4939 }; 4940 return globParent; 4941 } 4942 4943 var utils = {}; 4944 4945 var hasRequiredUtils; 4946 4947 function requireUtils () { 4948 if (hasRequiredUtils) return utils; 4949 hasRequiredUtils = 1; 4950 (function (exports) { 4951 4952 exports.isInteger = num => { 4953 if (typeof num === 'number') { 4954 return Number.isInteger(num); 4955 } 4956 if (typeof num === 'string' && num.trim() !== '') { 4957 return Number.isInteger(Number(num)); 4958 } 4959 return false; 4960 }; 4961 4962 /** 4963 * Find a node of the given type 4964 */ 4965 4966 exports.find = (node, type) => node.nodes.find(node => node.type === type); 4967 4968 /** 4969 * Find a node of the given type 4970 */ 4971 4972 exports.exceedsLimit = (min, max, step = 1, limit) => { 4973 if (limit === false) return false; 4974 if (!exports.isInteger(min) || !exports.isInteger(max)) return false; 4975 return ((Number(max) - Number(min)) / Number(step)) >= limit; 4976 }; 4977 4978 /** 4979 * Escape the given node with '\\' before node.value 4980 */ 4981 4982 exports.escapeNode = (block, n = 0, type) => { 4983 const node = block.nodes[n]; 4984 if (!node) return; 4985 4986 if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { 4987 if (node.escaped !== true) { 4988 node.value = '\\' + node.value; 4989 node.escaped = true; 4990 } 4991 } 4992 }; 4993 4994 /** 4995 * Returns true if the given brace node should be enclosed in literal braces 4996 */ 4997 4998 exports.encloseBrace = node => { 4999 if (node.type !== 'brace') return false; 5000 if ((node.commas >> 0 + node.ranges >> 0) === 0) { 5001 node.invalid = true; 5002 return true; 5003 } 5004 return false; 5005 }; 5006 5007 /** 5008 * Returns true if a brace node is invalid. 5009 */ 5010 5011 exports.isInvalidBrace = block => { 5012 if (block.type !== 'brace') return false; 5013 if (block.invalid === true || block.dollar) return true; 5014 if ((block.commas >> 0 + block.ranges >> 0) === 0) { 5015 block.invalid = true; 5016 return true; 5017 } 5018 if (block.open !== true || block.close !== true) { 5019 block.invalid = true; 5020 return true; 5021 } 5022 return false; 5023 }; 5024 5025 /** 5026 * Returns true if a node is an open or close node 5027 */ 5028 5029 exports.isOpenOrClose = node => { 5030 if (node.type === 'open' || node.type === 'close') { 5031 return true; 5032 } 5033 return node.open === true || node.close === true; 5034 }; 5035 5036 /** 5037 * Reduce an array of text nodes. 5038 */ 5039 5040 exports.reduce = nodes => nodes.reduce((acc, node) => { 5041 if (node.type === 'text') acc.push(node.value); 5042 if (node.type === 'range') node.type = 'text'; 5043 return acc; 5044 }, []); 5045 5046 /** 5047 * Flatten an array 5048 */ 5049 5050 exports.flatten = (...args) => { 5051 const result = []; 5052 5053 const flat = arr => { 5054 for (let i = 0; i < arr.length; i++) { 5055 const ele = arr[i]; 5056 5057 if (Array.isArray(ele)) { 5058 flat(ele); 5059 continue; 5060 } 5061 5062 if (ele !== undefined) { 5063 result.push(ele); 5064 } 5065 } 5066 return result; 5067 }; 5068 5069 flat(args); 5070 return result; 5071 }; 5072 } (utils)); 5073 return utils; 5074 } 5075 5076 var stringify; 5077 var hasRequiredStringify; 5078 5079 function requireStringify () { 5080 if (hasRequiredStringify) return stringify; 5081 hasRequiredStringify = 1; 5082 5083 const utils = /*@__PURE__*/ requireUtils(); 5084 5085 stringify = (ast, options = {}) => { 5086 const stringify = (node, parent = {}) => { 5087 const invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); 5088 const invalidNode = node.invalid === true && options.escapeInvalid === true; 5089 let output = ''; 5090 5091 if (node.value) { 5092 if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { 5093 return '\\' + node.value; 5094 } 5095 return node.value; 5096 } 5097 5098 if (node.value) { 5099 return node.value; 5100 } 5101 5102 if (node.nodes) { 5103 for (const child of node.nodes) { 5104 output += stringify(child); 5105 } 5106 } 5107 return output; 786 5108 }; 787 5109 788 flat(args); 789 return result; 790 }; 791 } (utils$3)); 792 793 const utils$2 = utils$3; 794 795 var stringify$4 = (ast, options = {}) => { 796 const stringify = (node, parent = {}) => { 797 const invalidBlock = options.escapeInvalid && utils$2.isInvalidBrace(parent); 798 const invalidNode = node.invalid === true && options.escapeInvalid === true; 799 let output = ''; 800 801 if (node.value) { 802 if ((invalidBlock || invalidNode) && utils$2.isOpenOrClose(node)) { 803 return '\\' + node.value; 804 } 805 return node.value; 806 } 807 808 if (node.value) { 809 return node.value; 810 } 811 812 if (node.nodes) { 813 for (const child of node.nodes) { 814 output += stringify(child); 815 } 816 } 817 return output; 818 }; 819 820 return stringify(ast); 821 }; 5110 return stringify(ast); 5111 }; 5112 return stringify; 5113 } 822 5114 823 5115 /*! … … 828 5120 */ 829 5121 830 var isNumber$2 = function(num) { 831 if (typeof num === 'number') { 832 return num - num === 0; 833 } 834 if (typeof num === 'string' && num.trim() !== '') { 835 return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); 836 } 837 return false; 838 }; 5122 var isNumber; 5123 var hasRequiredIsNumber; 5124 5125 function requireIsNumber () { 5126 if (hasRequiredIsNumber) return isNumber; 5127 hasRequiredIsNumber = 1; 5128 5129 isNumber = function(num) { 5130 if (typeof num === 'number') { 5131 return num - num === 0; 5132 } 5133 if (typeof num === 'string' && num.trim() !== '') { 5134 return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); 5135 } 5136 return false; 5137 }; 5138 return isNumber; 5139 } 839 5140 840 5141 /*! … … 845 5146 */ 846 5147 847 const isNumber$1 = isNumber$2; 848 849 const toRegexRange$1 = (min, max, options) => { 850 if (isNumber$1(min) === false) { 851 throw new TypeError('toRegexRange: expected the first argument to be a number'); 852 } 853 854 if (max === void 0 || min === max) { 855 return String(min); 856 } 857 858 if (isNumber$1(max) === false) { 859 throw new TypeError('toRegexRange: expected the second argument to be a number.'); 860 } 861 862 let opts = { relaxZeros: true, ...options }; 863 if (typeof opts.strictZeros === 'boolean') { 864 opts.relaxZeros = opts.strictZeros === false; 865 } 866 867 let relax = String(opts.relaxZeros); 868 let shorthand = String(opts.shorthand); 869 let capture = String(opts.capture); 870 let wrap = String(opts.wrap); 871 let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; 872 873 if (toRegexRange$1.cache.hasOwnProperty(cacheKey)) { 874 return toRegexRange$1.cache[cacheKey].result; 875 } 876 877 let a = Math.min(min, max); 878 let b = Math.max(min, max); 879 880 if (Math.abs(a - b) === 1) { 881 let result = min + '|' + max; 882 if (opts.capture) { 883 return `(${result})`; 884 } 885 if (opts.wrap === false) { 886 return result; 887 } 888 return `(?:${result})`; 889 } 890 891 let isPadded = hasPadding(min) || hasPadding(max); 892 let state = { min, max, a, b }; 893 let positives = []; 894 let negatives = []; 895 896 if (isPadded) { 897 state.isPadded = isPadded; 898 state.maxLen = String(state.max).length; 899 } 900 901 if (a < 0) { 902 let newMin = b < 0 ? Math.abs(b) : 1; 903 negatives = splitToPatterns(newMin, Math.abs(a), state, opts); 904 a = state.a = 0; 905 } 906 907 if (b >= 0) { 908 positives = splitToPatterns(a, b, state, opts); 909 } 910 911 state.negatives = negatives; 912 state.positives = positives; 913 state.result = collatePatterns(negatives, positives); 914 915 if (opts.capture === true) { 916 state.result = `(${state.result})`; 917 } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { 918 state.result = `(?:${state.result})`; 919 } 920 921 toRegexRange$1.cache[cacheKey] = state; 922 return state.result; 923 }; 924 925 function collatePatterns(neg, pos, options) { 926 let onlyNegative = filterPatterns(neg, pos, '-', false) || []; 927 let onlyPositive = filterPatterns(pos, neg, '', false) || []; 928 let intersected = filterPatterns(neg, pos, '-?', true) || []; 929 let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); 930 return subpatterns.join('|'); 5148 var toRegexRange_1; 5149 var hasRequiredToRegexRange; 5150 5151 function requireToRegexRange () { 5152 if (hasRequiredToRegexRange) return toRegexRange_1; 5153 hasRequiredToRegexRange = 1; 5154 5155 const isNumber = /*@__PURE__*/ requireIsNumber(); 5156 5157 const toRegexRange = (min, max, options) => { 5158 if (isNumber(min) === false) { 5159 throw new TypeError('toRegexRange: expected the first argument to be a number'); 5160 } 5161 5162 if (max === void 0 || min === max) { 5163 return String(min); 5164 } 5165 5166 if (isNumber(max) === false) { 5167 throw new TypeError('toRegexRange: expected the second argument to be a number.'); 5168 } 5169 5170 let opts = { relaxZeros: true, ...options }; 5171 if (typeof opts.strictZeros === 'boolean') { 5172 opts.relaxZeros = opts.strictZeros === false; 5173 } 5174 5175 let relax = String(opts.relaxZeros); 5176 let shorthand = String(opts.shorthand); 5177 let capture = String(opts.capture); 5178 let wrap = String(opts.wrap); 5179 let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; 5180 5181 if (toRegexRange.cache.hasOwnProperty(cacheKey)) { 5182 return toRegexRange.cache[cacheKey].result; 5183 } 5184 5185 let a = Math.min(min, max); 5186 let b = Math.max(min, max); 5187 5188 if (Math.abs(a - b) === 1) { 5189 let result = min + '|' + max; 5190 if (opts.capture) { 5191 return `(${result})`; 5192 } 5193 if (opts.wrap === false) { 5194 return result; 5195 } 5196 return `(?:${result})`; 5197 } 5198 5199 let isPadded = hasPadding(min) || hasPadding(max); 5200 let state = { min, max, a, b }; 5201 let positives = []; 5202 let negatives = []; 5203 5204 if (isPadded) { 5205 state.isPadded = isPadded; 5206 state.maxLen = String(state.max).length; 5207 } 5208 5209 if (a < 0) { 5210 let newMin = b < 0 ? Math.abs(b) : 1; 5211 negatives = splitToPatterns(newMin, Math.abs(a), state, opts); 5212 a = state.a = 0; 5213 } 5214 5215 if (b >= 0) { 5216 positives = splitToPatterns(a, b, state, opts); 5217 } 5218 5219 state.negatives = negatives; 5220 state.positives = positives; 5221 state.result = collatePatterns(negatives, positives); 5222 5223 if (opts.capture === true) { 5224 state.result = `(${state.result})`; 5225 } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { 5226 state.result = `(?:${state.result})`; 5227 } 5228 5229 toRegexRange.cache[cacheKey] = state; 5230 return state.result; 5231 }; 5232 5233 function collatePatterns(neg, pos, options) { 5234 let onlyNegative = filterPatterns(neg, pos, '-', false) || []; 5235 let onlyPositive = filterPatterns(pos, neg, '', false) || []; 5236 let intersected = filterPatterns(neg, pos, '-?', true) || []; 5237 let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); 5238 return subpatterns.join('|'); 5239 } 5240 5241 function splitToRanges(min, max) { 5242 let nines = 1; 5243 let zeros = 1; 5244 5245 let stop = countNines(min, nines); 5246 let stops = new Set([max]); 5247 5248 while (min <= stop && stop <= max) { 5249 stops.add(stop); 5250 nines += 1; 5251 stop = countNines(min, nines); 5252 } 5253 5254 stop = countZeros(max + 1, zeros) - 1; 5255 5256 while (min < stop && stop <= max) { 5257 stops.add(stop); 5258 zeros += 1; 5259 stop = countZeros(max + 1, zeros) - 1; 5260 } 5261 5262 stops = [...stops]; 5263 stops.sort(compare); 5264 return stops; 5265 } 5266 5267 /** 5268 * Convert a range to a regex pattern 5269 * @param {Number} `start` 5270 * @param {Number} `stop` 5271 * @return {String} 5272 */ 5273 5274 function rangeToPattern(start, stop, options) { 5275 if (start === stop) { 5276 return { pattern: start, count: [], digits: 0 }; 5277 } 5278 5279 let zipped = zip(start, stop); 5280 let digits = zipped.length; 5281 let pattern = ''; 5282 let count = 0; 5283 5284 for (let i = 0; i < digits; i++) { 5285 let [startDigit, stopDigit] = zipped[i]; 5286 5287 if (startDigit === stopDigit) { 5288 pattern += startDigit; 5289 5290 } else if (startDigit !== '0' || stopDigit !== '9') { 5291 pattern += toCharacterClass(startDigit, stopDigit); 5292 5293 } else { 5294 count++; 5295 } 5296 } 5297 5298 if (count) { 5299 pattern += options.shorthand === true ? '\\d' : '[0-9]'; 5300 } 5301 5302 return { pattern, count: [count], digits }; 5303 } 5304 5305 function splitToPatterns(min, max, tok, options) { 5306 let ranges = splitToRanges(min, max); 5307 let tokens = []; 5308 let start = min; 5309 let prev; 5310 5311 for (let i = 0; i < ranges.length; i++) { 5312 let max = ranges[i]; 5313 let obj = rangeToPattern(String(start), String(max), options); 5314 let zeros = ''; 5315 5316 if (!tok.isPadded && prev && prev.pattern === obj.pattern) { 5317 if (prev.count.length > 1) { 5318 prev.count.pop(); 5319 } 5320 5321 prev.count.push(obj.count[0]); 5322 prev.string = prev.pattern + toQuantifier(prev.count); 5323 start = max + 1; 5324 continue; 5325 } 5326 5327 if (tok.isPadded) { 5328 zeros = padZeros(max, tok, options); 5329 } 5330 5331 obj.string = zeros + obj.pattern + toQuantifier(obj.count); 5332 tokens.push(obj); 5333 start = max + 1; 5334 prev = obj; 5335 } 5336 5337 return tokens; 5338 } 5339 5340 function filterPatterns(arr, comparison, prefix, intersection, options) { 5341 let result = []; 5342 5343 for (let ele of arr) { 5344 let { string } = ele; 5345 5346 // only push if _both_ are negative... 5347 if (!intersection && !contains(comparison, 'string', string)) { 5348 result.push(prefix + string); 5349 } 5350 5351 // or _both_ are positive 5352 if (intersection && contains(comparison, 'string', string)) { 5353 result.push(prefix + string); 5354 } 5355 } 5356 return result; 5357 } 5358 5359 /** 5360 * Zip strings 5361 */ 5362 5363 function zip(a, b) { 5364 let arr = []; 5365 for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); 5366 return arr; 5367 } 5368 5369 function compare(a, b) { 5370 return a > b ? 1 : b > a ? -1 : 0; 5371 } 5372 5373 function contains(arr, key, val) { 5374 return arr.some(ele => ele[key] === val); 5375 } 5376 5377 function countNines(min, len) { 5378 return Number(String(min).slice(0, -len) + '9'.repeat(len)); 5379 } 5380 5381 function countZeros(integer, zeros) { 5382 return integer - (integer % Math.pow(10, zeros)); 5383 } 5384 5385 function toQuantifier(digits) { 5386 let [start = 0, stop = ''] = digits; 5387 if (stop || start > 1) { 5388 return `{${start + (stop ? ',' + stop : '')}}`; 5389 } 5390 return ''; 5391 } 5392 5393 function toCharacterClass(a, b, options) { 5394 return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; 5395 } 5396 5397 function hasPadding(str) { 5398 return /^-?(0+)\d/.test(str); 5399 } 5400 5401 function padZeros(value, tok, options) { 5402 if (!tok.isPadded) { 5403 return value; 5404 } 5405 5406 let diff = Math.abs(tok.maxLen - String(value).length); 5407 let relax = options.relaxZeros !== false; 5408 5409 switch (diff) { 5410 case 0: 5411 return ''; 5412 case 1: 5413 return relax ? '0?' : '0'; 5414 case 2: 5415 return relax ? '0{0,2}' : '00'; 5416 default: { 5417 return relax ? `0{0,${diff}}` : `0{${diff}}`; 5418 } 5419 } 5420 } 5421 5422 /** 5423 * Cache 5424 */ 5425 5426 toRegexRange.cache = {}; 5427 toRegexRange.clearCache = () => (toRegexRange.cache = {}); 5428 5429 /** 5430 * Expose `toRegexRange` 5431 */ 5432 5433 toRegexRange_1 = toRegexRange; 5434 return toRegexRange_1; 931 5435 } 932 933 function splitToRanges(min, max) {934 let nines = 1;935 let zeros = 1;936 937 let stop = countNines(min, nines);938 let stops = new Set([max]);939 940 while (min <= stop && stop <= max) {941 stops.add(stop);942 nines += 1;943 stop = countNines(min, nines);944 }945 946 stop = countZeros(max + 1, zeros) - 1;947 948 while (min < stop && stop <= max) {949 stops.add(stop);950 zeros += 1;951 stop = countZeros(max + 1, zeros) - 1;952 }953 954 stops = [...stops];955 stops.sort(compare);956 return stops;957 }958 959 /**960 * Convert a range to a regex pattern961 * @param {Number} `start`962 * @param {Number} `stop`963 * @return {String}964 */965 966 function rangeToPattern(start, stop, options) {967 if (start === stop) {968 return { pattern: start, count: [], digits: 0 };969 }970 971 let zipped = zip(start, stop);972 let digits = zipped.length;973 let pattern = '';974 let count = 0;975 976 for (let i = 0; i < digits; i++) {977 let [startDigit, stopDigit] = zipped[i];978 979 if (startDigit === stopDigit) {980 pattern += startDigit;981 982 } else if (startDigit !== '0' || stopDigit !== '9') {983 pattern += toCharacterClass(startDigit, stopDigit);984 985 } else {986 count++;987 }988 }989 990 if (count) {991 pattern += options.shorthand === true ? '\\d' : '[0-9]';992 }993 994 return { pattern, count: [count], digits };995 }996 997 function splitToPatterns(min, max, tok, options) {998 let ranges = splitToRanges(min, max);999 let tokens = [];1000 let start = min;1001 let prev;1002 1003 for (let i = 0; i < ranges.length; i++) {1004 let max = ranges[i];1005 let obj = rangeToPattern(String(start), String(max), options);1006 let zeros = '';1007 1008 if (!tok.isPadded && prev && prev.pattern === obj.pattern) {1009 if (prev.count.length > 1) {1010 prev.count.pop();1011 }1012 1013 prev.count.push(obj.count[0]);1014 prev.string = prev.pattern + toQuantifier(prev.count);1015 start = max + 1;1016 continue;1017 }1018 1019 if (tok.isPadded) {1020 zeros = padZeros(max, tok, options);1021 }1022 1023 obj.string = zeros + obj.pattern + toQuantifier(obj.count);1024 tokens.push(obj);1025 start = max + 1;1026 prev = obj;1027 }1028 1029 return tokens;1030 }1031 1032 function filterPatterns(arr, comparison, prefix, intersection, options) {1033 let result = [];1034 1035 for (let ele of arr) {1036 let { string } = ele;1037 1038 // only push if _both_ are negative...1039 if (!intersection && !contains(comparison, 'string', string)) {1040 result.push(prefix + string);1041 }1042 1043 // or _both_ are positive1044 if (intersection && contains(comparison, 'string', string)) {1045 result.push(prefix + string);1046 }1047 }1048 return result;1049 }1050 1051 /**1052 * Zip strings1053 */1054 1055 function zip(a, b) {1056 let arr = [];1057 for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]);1058 return arr;1059 }1060 1061 function compare(a, b) {1062 return a > b ? 1 : b > a ? -1 : 0;1063 }1064 1065 function contains(arr, key, val) {1066 return arr.some(ele => ele[key] === val);1067 }1068 1069 function countNines(min, len) {1070 return Number(String(min).slice(0, -len) + '9'.repeat(len));1071 }1072 1073 function countZeros(integer, zeros) {1074 return integer - (integer % Math.pow(10, zeros));1075 }1076 1077 function toQuantifier(digits) {1078 let [start = 0, stop = ''] = digits;1079 if (stop || start > 1) {1080 return `{${start + (stop ? ',' + stop : '')}}`;1081 }1082 return '';1083 }1084 1085 function toCharacterClass(a, b, options) {1086 return `[${a}${(b - a === 1) ? '' : '-'}${b}]`;1087 }1088 1089 function hasPadding(str) {1090 return /^-?(0+)\d/.test(str);1091 }1092 1093 function padZeros(value, tok, options) {1094 if (!tok.isPadded) {1095 return value;1096 }1097 1098 let diff = Math.abs(tok.maxLen - String(value).length);1099 let relax = options.relaxZeros !== false;1100 1101 switch (diff) {1102 case 0:1103 return '';1104 case 1:1105 return relax ? '0?' : '0';1106 case 2:1107 return relax ? '0{0,2}' : '00';1108 default: {1109 return relax ? `0{0,${diff}}` : `0{${diff}}`;1110 }1111 }1112 }1113 1114 /**1115 * Cache1116 */1117 1118 toRegexRange$1.cache = {};1119 toRegexRange$1.clearCache = () => (toRegexRange$1.cache = {});1120 1121 /**1122 * Expose `toRegexRange`1123 */1124 1125 var toRegexRange_1 = toRegexRange$1;1126 5436 1127 5437 /*! … … 1132 5442 */ 1133 5443 1134 const util = require$$2; 1135 const toRegexRange = toRegexRange_1; 1136 1137 const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 1138 1139 const transform = toNumber => { 1140 return value => toNumber === true ? Number(value) : String(value); 1141 }; 1142 1143 const isValidValue = value => { 1144 return typeof value === 'number' || (typeof value === 'string' && value !== ''); 1145 }; 1146 1147 const isNumber = num => Number.isInteger(+num); 1148 1149 const zeros = input => { 1150 let value = `${input}`; 1151 let index = -1; 1152 if (value[0] === '-') value = value.slice(1); 1153 if (value === '0') return false; 1154 while (value[++index] === '0'); 1155 return index > 0; 1156 }; 1157 1158 const stringify$3 = (start, end, options) => { 1159 if (typeof start === 'string' || typeof end === 'string') { 1160 return true; 1161 } 1162 return options.stringify === true; 1163 }; 1164 1165 const pad = (input, maxLength, toNumber) => { 1166 if (maxLength > 0) { 1167 let dash = input[0] === '-' ? '-' : ''; 1168 if (dash) input = input.slice(1); 1169 input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); 1170 } 1171 if (toNumber === false) { 1172 return String(input); 1173 } 1174 return input; 1175 }; 1176 1177 const toMaxLen = (input, maxLength) => { 1178 let negative = input[0] === '-' ? '-' : ''; 1179 if (negative) { 1180 input = input.slice(1); 1181 maxLength--; 1182 } 1183 while (input.length < maxLength) input = '0' + input; 1184 return negative ? ('-' + input) : input; 1185 }; 1186 1187 const toSequence = (parts, options, maxLen) => { 1188 parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); 1189 parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); 1190 1191 let prefix = options.capture ? '' : '?:'; 1192 let positives = ''; 1193 let negatives = ''; 1194 let result; 1195 1196 if (parts.positives.length) { 1197 positives = parts.positives.map(v => toMaxLen(String(v), maxLen)).join('|'); 1198 } 1199 1200 if (parts.negatives.length) { 1201 negatives = `-(${prefix}${parts.negatives.map(v => toMaxLen(String(v), maxLen)).join('|')})`; 1202 } 1203 1204 if (positives && negatives) { 1205 result = `${positives}|${negatives}`; 1206 } else { 1207 result = positives || negatives; 1208 } 1209 1210 if (options.wrap) { 1211 return `(${prefix}${result})`; 1212 } 1213 1214 return result; 1215 }; 1216 1217 const toRange = (a, b, isNumbers, options) => { 1218 if (isNumbers) { 1219 return toRegexRange(a, b, { wrap: false, ...options }); 1220 } 1221 1222 let start = String.fromCharCode(a); 1223 if (a === b) return start; 1224 1225 let stop = String.fromCharCode(b); 1226 return `[${start}-${stop}]`; 1227 }; 1228 1229 const toRegex = (start, end, options) => { 1230 if (Array.isArray(start)) { 1231 let wrap = options.wrap === true; 1232 let prefix = options.capture ? '' : '?:'; 1233 return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); 1234 } 1235 return toRegexRange(start, end, options); 1236 }; 1237 1238 const rangeError = (...args) => { 1239 return new RangeError('Invalid range arguments: ' + util.inspect(...args)); 1240 }; 1241 1242 const invalidRange = (start, end, options) => { 1243 if (options.strictRanges === true) throw rangeError([start, end]); 1244 return []; 1245 }; 1246 1247 const invalidStep = (step, options) => { 1248 if (options.strictRanges === true) { 1249 throw new TypeError(`Expected step "${step}" to be a number`); 1250 } 1251 return []; 1252 }; 1253 1254 const fillNumbers = (start, end, step = 1, options = {}) => { 1255 let a = Number(start); 1256 let b = Number(end); 1257 1258 if (!Number.isInteger(a) || !Number.isInteger(b)) { 1259 if (options.strictRanges === true) throw rangeError([start, end]); 1260 return []; 1261 } 1262 1263 // fix negative zero 1264 if (a === 0) a = 0; 1265 if (b === 0) b = 0; 1266 1267 let descending = a > b; 1268 let startString = String(start); 1269 let endString = String(end); 1270 let stepString = String(step); 1271 step = Math.max(Math.abs(step), 1); 1272 1273 let padded = zeros(startString) || zeros(endString) || zeros(stepString); 1274 let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; 1275 let toNumber = padded === false && stringify$3(start, end, options) === false; 1276 let format = options.transform || transform(toNumber); 1277 1278 if (options.toRegex && step === 1) { 1279 return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); 1280 } 1281 1282 let parts = { negatives: [], positives: [] }; 1283 let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); 1284 let range = []; 1285 let index = 0; 1286 1287 while (descending ? a >= b : a <= b) { 1288 if (options.toRegex === true && step > 1) { 1289 push(a); 1290 } else { 1291 range.push(pad(format(a, index), maxLen, toNumber)); 1292 } 1293 a = descending ? a - step : a + step; 1294 index++; 1295 } 1296 1297 if (options.toRegex === true) { 1298 return step > 1 1299 ? toSequence(parts, options, maxLen) 1300 : toRegex(range, null, { wrap: false, ...options }); 1301 } 1302 1303 return range; 1304 }; 1305 1306 const fillLetters = (start, end, step = 1, options = {}) => { 1307 if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { 1308 return invalidRange(start, end, options); 1309 } 1310 1311 let format = options.transform || (val => String.fromCharCode(val)); 1312 let a = `${start}`.charCodeAt(0); 1313 let b = `${end}`.charCodeAt(0); 1314 1315 let descending = a > b; 1316 let min = Math.min(a, b); 1317 let max = Math.max(a, b); 1318 1319 if (options.toRegex && step === 1) { 1320 return toRange(min, max, false, options); 1321 } 1322 1323 let range = []; 1324 let index = 0; 1325 1326 while (descending ? a >= b : a <= b) { 1327 range.push(format(a, index)); 1328 a = descending ? a - step : a + step; 1329 index++; 1330 } 1331 1332 if (options.toRegex === true) { 1333 return toRegex(range, null, { wrap: false, options }); 1334 } 1335 1336 return range; 1337 }; 1338 1339 const fill$2 = (start, end, step, options = {}) => { 1340 if (end == null && isValidValue(start)) { 1341 return [start]; 1342 } 1343 1344 if (!isValidValue(start) || !isValidValue(end)) { 1345 return invalidRange(start, end, options); 1346 } 1347 1348 if (typeof step === 'function') { 1349 return fill$2(start, end, 1, { transform: step }); 1350 } 1351 1352 if (isObject(step)) { 1353 return fill$2(start, end, 0, step); 1354 } 1355 1356 let opts = { ...options }; 1357 if (opts.capture === true) opts.wrap = true; 1358 step = step || opts.step || 1; 1359 1360 if (!isNumber(step)) { 1361 if (step != null && !isObject(step)) return invalidStep(step, opts); 1362 return fill$2(start, end, 1, step); 1363 } 1364 1365 if (isNumber(start) && isNumber(end)) { 1366 return fillNumbers(start, end, step, opts); 1367 } 1368 1369 return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); 1370 }; 1371 1372 var fillRange = fill$2; 1373 1374 const fill$1 = fillRange; 1375 const utils$1 = utils$3; 1376 1377 const compile$1 = (ast, options = {}) => { 1378 const walk = (node, parent = {}) => { 1379 const invalidBlock = utils$1.isInvalidBrace(parent); 1380 const invalidNode = node.invalid === true && options.escapeInvalid === true; 1381 const invalid = invalidBlock === true || invalidNode === true; 1382 const prefix = options.escapeInvalid === true ? '\\' : ''; 1383 let output = ''; 1384 1385 if (node.isOpen === true) { 1386 return prefix + node.value; 1387 } 1388 1389 if (node.isClose === true) { 1390 console.log('node.isClose', prefix, node.value); 1391 return prefix + node.value; 1392 } 1393 1394 if (node.type === 'open') { 1395 return invalid ? prefix + node.value : '('; 1396 } 1397 1398 if (node.type === 'close') { 1399 return invalid ? prefix + node.value : ')'; 1400 } 1401 1402 if (node.type === 'comma') { 1403 return node.prev.type === 'comma' ? '' : invalid ? node.value : '|'; 1404 } 1405 1406 if (node.value) { 1407 return node.value; 1408 } 1409 1410 if (node.nodes && node.ranges > 0) { 1411 const args = utils$1.reduce(node.nodes); 1412 const range = fill$1(...args, { ...options, wrap: false, toRegex: true, strictZeros: true }); 1413 1414 if (range.length !== 0) { 1415 return args.length > 1 && range.length > 1 ? `(${range})` : range; 1416 } 1417 } 1418 1419 if (node.nodes) { 1420 for (const child of node.nodes) { 1421 output += walk(child, node); 1422 } 1423 } 1424 1425 return output; 1426 }; 1427 1428 return walk(ast); 1429 }; 1430 1431 var compile_1 = compile$1; 1432 1433 const fill = fillRange; 1434 const stringify$2 = stringify$4; 1435 const utils = utils$3; 1436 1437 const append = (queue = '', stash = '', enclose = false) => { 1438 const result = []; 1439 1440 queue = [].concat(queue); 1441 stash = [].concat(stash); 1442 1443 if (!stash.length) return queue; 1444 if (!queue.length) { 1445 return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; 1446 } 1447 1448 for (const item of queue) { 1449 if (Array.isArray(item)) { 1450 for (const value of item) { 1451 result.push(append(value, stash, enclose)); 1452 } 1453 } else { 1454 for (let ele of stash) { 1455 if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; 1456 result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele); 1457 } 1458 } 1459 } 1460 return utils.flatten(result); 1461 }; 1462 1463 const expand$1 = (ast, options = {}) => { 1464 const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit; 1465 1466 const walk = (node, parent = {}) => { 1467 node.queue = []; 1468 1469 let p = parent; 1470 let q = parent.queue; 1471 1472 while (p.type !== 'brace' && p.type !== 'root' && p.parent) { 1473 p = p.parent; 1474 q = p.queue; 1475 } 1476 1477 if (node.invalid || node.dollar) { 1478 q.push(append(q.pop(), stringify$2(node, options))); 1479 return; 1480 } 1481 1482 if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { 1483 q.push(append(q.pop(), ['{}'])); 1484 return; 1485 } 1486 1487 if (node.nodes && node.ranges > 0) { 1488 const args = utils.reduce(node.nodes); 1489 1490 if (utils.exceedsLimit(...args, options.step, rangeLimit)) { 1491 throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); 1492 } 1493 1494 let range = fill(...args, options); 1495 if (range.length === 0) { 1496 range = stringify$2(node, options); 1497 } 1498 1499 q.push(append(q.pop(), range)); 1500 node.nodes = []; 1501 return; 1502 } 1503 1504 const enclose = utils.encloseBrace(node); 1505 let queue = node.queue; 1506 let block = node; 1507 1508 while (block.type !== 'brace' && block.type !== 'root' && block.parent) { 1509 block = block.parent; 1510 queue = block.queue; 1511 } 1512 1513 for (let i = 0; i < node.nodes.length; i++) { 1514 const child = node.nodes[i]; 1515 1516 if (child.type === 'comma' && node.type === 'brace') { 1517 if (i === 1) queue.push(''); 1518 queue.push(''); 1519 continue; 1520 } 1521 1522 if (child.type === 'close') { 1523 q.push(append(q.pop(), queue, enclose)); 1524 continue; 1525 } 1526 1527 if (child.value && child.type !== 'open') { 1528 queue.push(append(queue.pop(), child.value)); 1529 continue; 1530 } 1531 1532 if (child.nodes) { 1533 walk(child, node); 1534 } 1535 } 1536 1537 return queue; 1538 }; 1539 1540 return utils.flatten(walk(ast)); 1541 }; 1542 1543 var expand_1 = expand$1; 1544 1545 var constants$1 = { 1546 MAX_LENGTH: 10000, 1547 1548 // Digits 1549 CHAR_0: '0', /* 0 */ 1550 CHAR_9: '9', /* 9 */ 1551 1552 // Alphabet chars. 1553 CHAR_UPPERCASE_A: 'A', /* A */ 1554 CHAR_LOWERCASE_A: 'a', /* a */ 1555 CHAR_UPPERCASE_Z: 'Z', /* Z */ 1556 CHAR_LOWERCASE_Z: 'z', /* z */ 1557 1558 CHAR_LEFT_PARENTHESES: '(', /* ( */ 1559 CHAR_RIGHT_PARENTHESES: ')', /* ) */ 1560 1561 CHAR_ASTERISK: '*', /* * */ 1562 1563 // Non-alphabetic chars. 1564 CHAR_AMPERSAND: '&', /* & */ 1565 CHAR_AT: '@', /* @ */ 1566 CHAR_BACKSLASH: '\\', /* \ */ 1567 CHAR_BACKTICK: '`', /* ` */ 1568 CHAR_CARRIAGE_RETURN: '\r', /* \r */ 1569 CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ 1570 CHAR_COLON: ':', /* : */ 1571 CHAR_COMMA: ',', /* , */ 1572 CHAR_DOLLAR: '$', /* . */ 1573 CHAR_DOT: '.', /* . */ 1574 CHAR_DOUBLE_QUOTE: '"', /* " */ 1575 CHAR_EQUAL: '=', /* = */ 1576 CHAR_EXCLAMATION_MARK: '!', /* ! */ 1577 CHAR_FORM_FEED: '\f', /* \f */ 1578 CHAR_FORWARD_SLASH: '/', /* / */ 1579 CHAR_HASH: '#', /* # */ 1580 CHAR_HYPHEN_MINUS: '-', /* - */ 1581 CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ 1582 CHAR_LEFT_CURLY_BRACE: '{', /* { */ 1583 CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ 1584 CHAR_LINE_FEED: '\n', /* \n */ 1585 CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ 1586 CHAR_PERCENT: '%', /* % */ 1587 CHAR_PLUS: '+', /* + */ 1588 CHAR_QUESTION_MARK: '?', /* ? */ 1589 CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ 1590 CHAR_RIGHT_CURLY_BRACE: '}', /* } */ 1591 CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ 1592 CHAR_SEMICOLON: ';', /* ; */ 1593 CHAR_SINGLE_QUOTE: '\'', /* ' */ 1594 CHAR_SPACE: ' ', /* */ 1595 CHAR_TAB: '\t', /* \t */ 1596 CHAR_UNDERSCORE: '_', /* _ */ 1597 CHAR_VERTICAL_LINE: '|', /* | */ 1598 CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ 1599 }; 1600 1601 const stringify$1 = stringify$4; 1602 1603 /** 1604 * Constants 1605 */ 1606 1607 const { 1608 MAX_LENGTH, 1609 CHAR_BACKSLASH, /* \ */ 1610 CHAR_BACKTICK, /* ` */ 1611 CHAR_COMMA, /* , */ 1612 CHAR_DOT, /* . */ 1613 CHAR_LEFT_PARENTHESES, /* ( */ 1614 CHAR_RIGHT_PARENTHESES, /* ) */ 1615 CHAR_LEFT_CURLY_BRACE, /* { */ 1616 CHAR_RIGHT_CURLY_BRACE, /* } */ 1617 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 1618 CHAR_RIGHT_SQUARE_BRACKET, /* ] */ 1619 CHAR_DOUBLE_QUOTE, /* " */ 1620 CHAR_SINGLE_QUOTE, /* ' */ 1621 CHAR_NO_BREAK_SPACE, 1622 CHAR_ZERO_WIDTH_NOBREAK_SPACE 1623 } = constants$1; 1624 1625 /** 1626 * parse 1627 */ 1628 1629 const parse$1 = (input, options = {}) => { 1630 if (typeof input !== 'string') { 1631 throw new TypeError('Expected a string'); 1632 } 1633 1634 const opts = options || {}; 1635 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 1636 if (input.length > max) { 1637 throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); 1638 } 1639 1640 const ast = { type: 'root', input, nodes: [] }; 1641 const stack = [ast]; 1642 let block = ast; 1643 let prev = ast; 1644 let brackets = 0; 1645 const length = input.length; 1646 let index = 0; 1647 let depth = 0; 1648 let value; 1649 1650 /** 1651 * Helpers 1652 */ 1653 1654 const advance = () => input[index++]; 1655 const push = node => { 1656 if (node.type === 'text' && prev.type === 'dot') { 1657 prev.type = 'text'; 1658 } 1659 1660 if (prev && prev.type === 'text' && node.type === 'text') { 1661 prev.value += node.value; 1662 return; 1663 } 1664 1665 block.nodes.push(node); 1666 node.parent = block; 1667 node.prev = prev; 1668 prev = node; 1669 return node; 1670 }; 1671 1672 push({ type: 'bos' }); 1673 1674 while (index < length) { 1675 block = stack[stack.length - 1]; 1676 value = advance(); 1677 1678 /** 1679 * Invalid chars 1680 */ 1681 1682 if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { 1683 continue; 1684 } 1685 1686 /** 1687 * Escaped chars 1688 */ 1689 1690 if (value === CHAR_BACKSLASH) { 1691 push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); 1692 continue; 1693 } 1694 1695 /** 1696 * Right square bracket (literal): ']' 1697 */ 1698 1699 if (value === CHAR_RIGHT_SQUARE_BRACKET) { 1700 push({ type: 'text', value: '\\' + value }); 1701 continue; 1702 } 1703 1704 /** 1705 * Left square bracket: '[' 1706 */ 1707 1708 if (value === CHAR_LEFT_SQUARE_BRACKET) { 1709 brackets++; 1710 1711 let next; 1712 1713 while (index < length && (next = advance())) { 1714 value += next; 1715 1716 if (next === CHAR_LEFT_SQUARE_BRACKET) { 1717 brackets++; 1718 continue; 1719 } 1720 1721 if (next === CHAR_BACKSLASH) { 1722 value += advance(); 1723 continue; 1724 } 1725 1726 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 1727 brackets--; 1728 1729 if (brackets === 0) { 1730 break; 1731 } 1732 } 1733 } 1734 1735 push({ type: 'text', value }); 1736 continue; 1737 } 1738 1739 /** 1740 * Parentheses 1741 */ 1742 1743 if (value === CHAR_LEFT_PARENTHESES) { 1744 block = push({ type: 'paren', nodes: [] }); 1745 stack.push(block); 1746 push({ type: 'text', value }); 1747 continue; 1748 } 1749 1750 if (value === CHAR_RIGHT_PARENTHESES) { 1751 if (block.type !== 'paren') { 1752 push({ type: 'text', value }); 1753 continue; 1754 } 1755 block = stack.pop(); 1756 push({ type: 'text', value }); 1757 block = stack[stack.length - 1]; 1758 continue; 1759 } 1760 1761 /** 1762 * Quotes: '|"|` 1763 */ 1764 1765 if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { 1766 const open = value; 1767 let next; 1768 1769 if (options.keepQuotes !== true) { 1770 value = ''; 1771 } 1772 1773 while (index < length && (next = advance())) { 1774 if (next === CHAR_BACKSLASH) { 1775 value += next + advance(); 1776 continue; 1777 } 1778 1779 if (next === open) { 1780 if (options.keepQuotes === true) value += next; 1781 break; 1782 } 1783 1784 value += next; 1785 } 1786 1787 push({ type: 'text', value }); 1788 continue; 1789 } 1790 1791 /** 1792 * Left curly brace: '{' 1793 */ 1794 1795 if (value === CHAR_LEFT_CURLY_BRACE) { 1796 depth++; 1797 1798 const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; 1799 const brace = { 1800 type: 'brace', 1801 open: true, 1802 close: false, 1803 dollar, 1804 depth, 1805 commas: 0, 1806 ranges: 0, 1807 nodes: [] 1808 }; 1809 1810 block = push(brace); 1811 stack.push(block); 1812 push({ type: 'open', value }); 1813 continue; 1814 } 1815 1816 /** 1817 * Right curly brace: '}' 1818 */ 1819 1820 if (value === CHAR_RIGHT_CURLY_BRACE) { 1821 if (block.type !== 'brace') { 1822 push({ type: 'text', value }); 1823 continue; 1824 } 1825 1826 const type = 'close'; 1827 block = stack.pop(); 1828 block.close = true; 1829 1830 push({ type, value }); 1831 depth--; 1832 1833 block = stack[stack.length - 1]; 1834 continue; 1835 } 1836 1837 /** 1838 * Comma: ',' 1839 */ 1840 1841 if (value === CHAR_COMMA && depth > 0) { 1842 if (block.ranges > 0) { 1843 block.ranges = 0; 1844 const open = block.nodes.shift(); 1845 block.nodes = [open, { type: 'text', value: stringify$1(block) }]; 1846 } 1847 1848 push({ type: 'comma', value }); 1849 block.commas++; 1850 continue; 1851 } 1852 1853 /** 1854 * Dot: '.' 1855 */ 1856 1857 if (value === CHAR_DOT && depth > 0 && block.commas === 0) { 1858 const siblings = block.nodes; 1859 1860 if (depth === 0 || siblings.length === 0) { 1861 push({ type: 'text', value }); 1862 continue; 1863 } 1864 1865 if (prev.type === 'dot') { 1866 block.range = []; 1867 prev.value += value; 1868 prev.type = 'range'; 1869 1870 if (block.nodes.length !== 3 && block.nodes.length !== 5) { 1871 block.invalid = true; 1872 block.ranges = 0; 1873 prev.type = 'text'; 1874 continue; 1875 } 1876 1877 block.ranges++; 1878 block.args = []; 1879 continue; 1880 } 1881 1882 if (prev.type === 'range') { 1883 siblings.pop(); 1884 1885 const before = siblings[siblings.length - 1]; 1886 before.value += prev.value + value; 1887 prev = before; 1888 block.ranges--; 1889 continue; 1890 } 1891 1892 push({ type: 'dot', value }); 1893 continue; 1894 } 1895 1896 /** 1897 * Text 1898 */ 1899 1900 push({ type: 'text', value }); 1901 } 1902 1903 // Mark imbalanced braces and brackets as invalid 1904 do { 1905 block = stack.pop(); 1906 1907 if (block.type !== 'root') { 1908 block.nodes.forEach(node => { 1909 if (!node.nodes) { 1910 if (node.type === 'open') node.isOpen = true; 1911 if (node.type === 'close') node.isClose = true; 1912 if (!node.nodes) node.type = 'text'; 1913 node.invalid = true; 1914 } 1915 }); 1916 1917 // get the location of the block on parent.nodes (block's siblings) 1918 const parent = stack[stack.length - 1]; 1919 const index = parent.nodes.indexOf(block); 1920 // replace the (invalid) block with it's nodes 1921 parent.nodes.splice(index, 1, ...block.nodes); 1922 } 1923 } while (stack.length > 0); 1924 1925 push({ type: 'eos' }); 1926 return ast; 1927 }; 1928 1929 var parse_1 = parse$1; 1930 1931 const stringify = stringify$4; 1932 const compile = compile_1; 1933 const expand = expand_1; 1934 const parse = parse_1; 1935 1936 /** 1937 * Expand the given pattern or create a regex-compatible string. 1938 * 1939 * ```js 1940 * const braces = require('braces'); 1941 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] 1942 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] 1943 * ``` 1944 * @param {String} `str` 1945 * @param {Object} `options` 1946 * @return {String} 1947 * @api public 1948 */ 1949 1950 const braces$1 = (input, options = {}) => { 1951 let output = []; 1952 1953 if (Array.isArray(input)) { 1954 for (const pattern of input) { 1955 const result = braces$1.create(pattern, options); 1956 if (Array.isArray(result)) { 1957 output.push(...result); 1958 } else { 1959 output.push(result); 1960 } 1961 } 1962 } else { 1963 output = [].concat(braces$1.create(input, options)); 1964 } 1965 1966 if (options && options.expand === true && options.nodupes === true) { 1967 output = [...new Set(output)]; 1968 } 1969 return output; 1970 }; 1971 1972 /** 1973 * Parse the given `str` with the given `options`. 1974 * 1975 * ```js 1976 * // braces.parse(pattern, [, options]); 1977 * const ast = braces.parse('a/{b,c}/d'); 1978 * console.log(ast); 1979 * ``` 1980 * @param {String} pattern Brace pattern to parse 1981 * @param {Object} options 1982 * @return {Object} Returns an AST 1983 * @api public 1984 */ 1985 1986 braces$1.parse = (input, options = {}) => parse(input, options); 1987 1988 /** 1989 * Creates a braces string from an AST, or an AST node. 1990 * 1991 * ```js 1992 * const braces = require('braces'); 1993 * let ast = braces.parse('foo/{a,b}/bar'); 1994 * console.log(stringify(ast.nodes[2])); //=> '{a,b}' 1995 * ``` 1996 * @param {String} `input` Brace pattern or AST. 1997 * @param {Object} `options` 1998 * @return {Array} Returns an array of expanded values. 1999 * @api public 2000 */ 2001 2002 braces$1.stringify = (input, options = {}) => { 2003 if (typeof input === 'string') { 2004 return stringify(braces$1.parse(input, options), options); 2005 } 2006 return stringify(input, options); 2007 }; 2008 2009 /** 2010 * Compiles a brace pattern into a regex-compatible, optimized string. 2011 * This method is called by the main [braces](#braces) function by default. 2012 * 2013 * ```js 2014 * const braces = require('braces'); 2015 * console.log(braces.compile('a/{b,c}/d')); 2016 * //=> ['a/(b|c)/d'] 2017 * ``` 2018 * @param {String} `input` Brace pattern or AST. 2019 * @param {Object} `options` 2020 * @return {Array} Returns an array of expanded values. 2021 * @api public 2022 */ 2023 2024 braces$1.compile = (input, options = {}) => { 2025 if (typeof input === 'string') { 2026 input = braces$1.parse(input, options); 2027 } 2028 return compile(input, options); 2029 }; 2030 2031 /** 2032 * Expands a brace pattern into an array. This method is called by the 2033 * main [braces](#braces) function when `options.expand` is true. Before 2034 * using this method it's recommended that you read the [performance notes](#performance)) 2035 * and advantages of using [.compile](#compile) instead. 2036 * 2037 * ```js 2038 * const braces = require('braces'); 2039 * console.log(braces.expand('a/{b,c}/d')); 2040 * //=> ['a/b/d', 'a/c/d']; 2041 * ``` 2042 * @param {String} `pattern` Brace pattern 2043 * @param {Object} `options` 2044 * @return {Array} Returns an array of expanded values. 2045 * @api public 2046 */ 2047 2048 braces$1.expand = (input, options = {}) => { 2049 if (typeof input === 'string') { 2050 input = braces$1.parse(input, options); 2051 } 2052 2053 let result = expand(input, options); 2054 2055 // filter out empty strings if specified 2056 if (options.noempty === true) { 2057 result = result.filter(Boolean); 2058 } 2059 2060 // filter out duplicates if specified 2061 if (options.nodupes === true) { 2062 result = [...new Set(result)]; 2063 } 2064 2065 return result; 2066 }; 2067 2068 /** 2069 * Processes a brace pattern and returns either an expanded array 2070 * (if `options.expand` is true), a highly optimized regex-compatible string. 2071 * This method is called by the main [braces](#braces) function. 2072 * 2073 * ```js 2074 * const braces = require('braces'); 2075 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) 2076 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' 2077 * ``` 2078 * @param {String} `pattern` Brace pattern 2079 * @param {Object} `options` 2080 * @return {Array} Returns an array of expanded values. 2081 * @api public 2082 */ 2083 2084 braces$1.create = (input, options = {}) => { 2085 if (input === '' || input.length < 3) { 2086 return [input]; 2087 } 2088 2089 return options.expand !== true 2090 ? braces$1.compile(input, options) 2091 : braces$1.expand(input, options); 2092 }; 2093 2094 /** 2095 * Expose "braces" 2096 */ 2097 2098 var braces_1 = braces$1; 5444 var fillRange; 5445 var hasRequiredFillRange; 5446 5447 function requireFillRange () { 5448 if (hasRequiredFillRange) return fillRange; 5449 hasRequiredFillRange = 1; 5450 5451 const util = require$$2; 5452 const toRegexRange = /*@__PURE__*/ requireToRegexRange(); 5453 5454 const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 5455 5456 const transform = toNumber => { 5457 return value => toNumber === true ? Number(value) : String(value); 5458 }; 5459 5460 const isValidValue = value => { 5461 return typeof value === 'number' || (typeof value === 'string' && value !== ''); 5462 }; 5463 5464 const isNumber = num => Number.isInteger(+num); 5465 5466 const zeros = input => { 5467 let value = `${input}`; 5468 let index = -1; 5469 if (value[0] === '-') value = value.slice(1); 5470 if (value === '0') return false; 5471 while (value[++index] === '0'); 5472 return index > 0; 5473 }; 5474 5475 const stringify = (start, end, options) => { 5476 if (typeof start === 'string' || typeof end === 'string') { 5477 return true; 5478 } 5479 return options.stringify === true; 5480 }; 5481 5482 const pad = (input, maxLength, toNumber) => { 5483 if (maxLength > 0) { 5484 let dash = input[0] === '-' ? '-' : ''; 5485 if (dash) input = input.slice(1); 5486 input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); 5487 } 5488 if (toNumber === false) { 5489 return String(input); 5490 } 5491 return input; 5492 }; 5493 5494 const toMaxLen = (input, maxLength) => { 5495 let negative = input[0] === '-' ? '-' : ''; 5496 if (negative) { 5497 input = input.slice(1); 5498 maxLength--; 5499 } 5500 while (input.length < maxLength) input = '0' + input; 5501 return negative ? ('-' + input) : input; 5502 }; 5503 5504 const toSequence = (parts, options, maxLen) => { 5505 parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); 5506 parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); 5507 5508 let prefix = options.capture ? '' : '?:'; 5509 let positives = ''; 5510 let negatives = ''; 5511 let result; 5512 5513 if (parts.positives.length) { 5514 positives = parts.positives.map(v => toMaxLen(String(v), maxLen)).join('|'); 5515 } 5516 5517 if (parts.negatives.length) { 5518 negatives = `-(${prefix}${parts.negatives.map(v => toMaxLen(String(v), maxLen)).join('|')})`; 5519 } 5520 5521 if (positives && negatives) { 5522 result = `${positives}|${negatives}`; 5523 } else { 5524 result = positives || negatives; 5525 } 5526 5527 if (options.wrap) { 5528 return `(${prefix}${result})`; 5529 } 5530 5531 return result; 5532 }; 5533 5534 const toRange = (a, b, isNumbers, options) => { 5535 if (isNumbers) { 5536 return toRegexRange(a, b, { wrap: false, ...options }); 5537 } 5538 5539 let start = String.fromCharCode(a); 5540 if (a === b) return start; 5541 5542 let stop = String.fromCharCode(b); 5543 return `[${start}-${stop}]`; 5544 }; 5545 5546 const toRegex = (start, end, options) => { 5547 if (Array.isArray(start)) { 5548 let wrap = options.wrap === true; 5549 let prefix = options.capture ? '' : '?:'; 5550 return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); 5551 } 5552 return toRegexRange(start, end, options); 5553 }; 5554 5555 const rangeError = (...args) => { 5556 return new RangeError('Invalid range arguments: ' + util.inspect(...args)); 5557 }; 5558 5559 const invalidRange = (start, end, options) => { 5560 if (options.strictRanges === true) throw rangeError([start, end]); 5561 return []; 5562 }; 5563 5564 const invalidStep = (step, options) => { 5565 if (options.strictRanges === true) { 5566 throw new TypeError(`Expected step "${step}" to be a number`); 5567 } 5568 return []; 5569 }; 5570 5571 const fillNumbers = (start, end, step = 1, options = {}) => { 5572 let a = Number(start); 5573 let b = Number(end); 5574 5575 if (!Number.isInteger(a) || !Number.isInteger(b)) { 5576 if (options.strictRanges === true) throw rangeError([start, end]); 5577 return []; 5578 } 5579 5580 // fix negative zero 5581 if (a === 0) a = 0; 5582 if (b === 0) b = 0; 5583 5584 let descending = a > b; 5585 let startString = String(start); 5586 let endString = String(end); 5587 let stepString = String(step); 5588 step = Math.max(Math.abs(step), 1); 5589 5590 let padded = zeros(startString) || zeros(endString) || zeros(stepString); 5591 let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; 5592 let toNumber = padded === false && stringify(start, end, options) === false; 5593 let format = options.transform || transform(toNumber); 5594 5595 if (options.toRegex && step === 1) { 5596 return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); 5597 } 5598 5599 let parts = { negatives: [], positives: [] }; 5600 let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); 5601 let range = []; 5602 let index = 0; 5603 5604 while (descending ? a >= b : a <= b) { 5605 if (options.toRegex === true && step > 1) { 5606 push(a); 5607 } else { 5608 range.push(pad(format(a, index), maxLen, toNumber)); 5609 } 5610 a = descending ? a - step : a + step; 5611 index++; 5612 } 5613 5614 if (options.toRegex === true) { 5615 return step > 1 5616 ? toSequence(parts, options, maxLen) 5617 : toRegex(range, null, { wrap: false, ...options }); 5618 } 5619 5620 return range; 5621 }; 5622 5623 const fillLetters = (start, end, step = 1, options = {}) => { 5624 if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { 5625 return invalidRange(start, end, options); 5626 } 5627 5628 let format = options.transform || (val => String.fromCharCode(val)); 5629 let a = `${start}`.charCodeAt(0); 5630 let b = `${end}`.charCodeAt(0); 5631 5632 let descending = a > b; 5633 let min = Math.min(a, b); 5634 let max = Math.max(a, b); 5635 5636 if (options.toRegex && step === 1) { 5637 return toRange(min, max, false, options); 5638 } 5639 5640 let range = []; 5641 let index = 0; 5642 5643 while (descending ? a >= b : a <= b) { 5644 range.push(format(a, index)); 5645 a = descending ? a - step : a + step; 5646 index++; 5647 } 5648 5649 if (options.toRegex === true) { 5650 return toRegex(range, null, { wrap: false, options }); 5651 } 5652 5653 return range; 5654 }; 5655 5656 const fill = (start, end, step, options = {}) => { 5657 if (end == null && isValidValue(start)) { 5658 return [start]; 5659 } 5660 5661 if (!isValidValue(start) || !isValidValue(end)) { 5662 return invalidRange(start, end, options); 5663 } 5664 5665 if (typeof step === 'function') { 5666 return fill(start, end, 1, { transform: step }); 5667 } 5668 5669 if (isObject(step)) { 5670 return fill(start, end, 0, step); 5671 } 5672 5673 let opts = { ...options }; 5674 if (opts.capture === true) opts.wrap = true; 5675 step = step || opts.step || 1; 5676 5677 if (!isNumber(step)) { 5678 if (step != null && !isObject(step)) return invalidStep(step, opts); 5679 return fill(start, end, 1, step); 5680 } 5681 5682 if (isNumber(start) && isNumber(end)) { 5683 return fillNumbers(start, end, step, opts); 5684 } 5685 5686 return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); 5687 }; 5688 5689 fillRange = fill; 5690 return fillRange; 5691 } 5692 5693 var compile_1; 5694 var hasRequiredCompile; 5695 5696 function requireCompile () { 5697 if (hasRequiredCompile) return compile_1; 5698 hasRequiredCompile = 1; 5699 5700 const fill = /*@__PURE__*/ requireFillRange(); 5701 const utils = /*@__PURE__*/ requireUtils(); 5702 5703 const compile = (ast, options = {}) => { 5704 const walk = (node, parent = {}) => { 5705 const invalidBlock = utils.isInvalidBrace(parent); 5706 const invalidNode = node.invalid === true && options.escapeInvalid === true; 5707 const invalid = invalidBlock === true || invalidNode === true; 5708 const prefix = options.escapeInvalid === true ? '\\' : ''; 5709 let output = ''; 5710 5711 if (node.isOpen === true) { 5712 return prefix + node.value; 5713 } 5714 5715 if (node.isClose === true) { 5716 console.log('node.isClose', prefix, node.value); 5717 return prefix + node.value; 5718 } 5719 5720 if (node.type === 'open') { 5721 return invalid ? prefix + node.value : '('; 5722 } 5723 5724 if (node.type === 'close') { 5725 return invalid ? prefix + node.value : ')'; 5726 } 5727 5728 if (node.type === 'comma') { 5729 return node.prev.type === 'comma' ? '' : invalid ? node.value : '|'; 5730 } 5731 5732 if (node.value) { 5733 return node.value; 5734 } 5735 5736 if (node.nodes && node.ranges > 0) { 5737 const args = utils.reduce(node.nodes); 5738 const range = fill(...args, { ...options, wrap: false, toRegex: true, strictZeros: true }); 5739 5740 if (range.length !== 0) { 5741 return args.length > 1 && range.length > 1 ? `(${range})` : range; 5742 } 5743 } 5744 5745 if (node.nodes) { 5746 for (const child of node.nodes) { 5747 output += walk(child, node); 5748 } 5749 } 5750 5751 return output; 5752 }; 5753 5754 return walk(ast); 5755 }; 5756 5757 compile_1 = compile; 5758 return compile_1; 5759 } 5760 5761 var expand_1; 5762 var hasRequiredExpand; 5763 5764 function requireExpand () { 5765 if (hasRequiredExpand) return expand_1; 5766 hasRequiredExpand = 1; 5767 5768 const fill = /*@__PURE__*/ requireFillRange(); 5769 const stringify = /*@__PURE__*/ requireStringify(); 5770 const utils = /*@__PURE__*/ requireUtils(); 5771 5772 const append = (queue = '', stash = '', enclose = false) => { 5773 const result = []; 5774 5775 queue = [].concat(queue); 5776 stash = [].concat(stash); 5777 5778 if (!stash.length) return queue; 5779 if (!queue.length) { 5780 return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; 5781 } 5782 5783 for (const item of queue) { 5784 if (Array.isArray(item)) { 5785 for (const value of item) { 5786 result.push(append(value, stash, enclose)); 5787 } 5788 } else { 5789 for (let ele of stash) { 5790 if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; 5791 result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele); 5792 } 5793 } 5794 } 5795 return utils.flatten(result); 5796 }; 5797 5798 const expand = (ast, options = {}) => { 5799 const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit; 5800 5801 const walk = (node, parent = {}) => { 5802 node.queue = []; 5803 5804 let p = parent; 5805 let q = parent.queue; 5806 5807 while (p.type !== 'brace' && p.type !== 'root' && p.parent) { 5808 p = p.parent; 5809 q = p.queue; 5810 } 5811 5812 if (node.invalid || node.dollar) { 5813 q.push(append(q.pop(), stringify(node, options))); 5814 return; 5815 } 5816 5817 if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { 5818 q.push(append(q.pop(), ['{}'])); 5819 return; 5820 } 5821 5822 if (node.nodes && node.ranges > 0) { 5823 const args = utils.reduce(node.nodes); 5824 5825 if (utils.exceedsLimit(...args, options.step, rangeLimit)) { 5826 throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); 5827 } 5828 5829 let range = fill(...args, options); 5830 if (range.length === 0) { 5831 range = stringify(node, options); 5832 } 5833 5834 q.push(append(q.pop(), range)); 5835 node.nodes = []; 5836 return; 5837 } 5838 5839 const enclose = utils.encloseBrace(node); 5840 let queue = node.queue; 5841 let block = node; 5842 5843 while (block.type !== 'brace' && block.type !== 'root' && block.parent) { 5844 block = block.parent; 5845 queue = block.queue; 5846 } 5847 5848 for (let i = 0; i < node.nodes.length; i++) { 5849 const child = node.nodes[i]; 5850 5851 if (child.type === 'comma' && node.type === 'brace') { 5852 if (i === 1) queue.push(''); 5853 queue.push(''); 5854 continue; 5855 } 5856 5857 if (child.type === 'close') { 5858 q.push(append(q.pop(), queue, enclose)); 5859 continue; 5860 } 5861 5862 if (child.value && child.type !== 'open') { 5863 queue.push(append(queue.pop(), child.value)); 5864 continue; 5865 } 5866 5867 if (child.nodes) { 5868 walk(child, node); 5869 } 5870 } 5871 5872 return queue; 5873 }; 5874 5875 return utils.flatten(walk(ast)); 5876 }; 5877 5878 expand_1 = expand; 5879 return expand_1; 5880 } 5881 5882 var constants$1; 5883 var hasRequiredConstants$1; 5884 5885 function requireConstants$1 () { 5886 if (hasRequiredConstants$1) return constants$1; 5887 hasRequiredConstants$1 = 1; 5888 5889 constants$1 = { 5890 MAX_LENGTH: 10000, 5891 5892 // Digits 5893 CHAR_0: '0', /* 0 */ 5894 CHAR_9: '9', /* 9 */ 5895 5896 // Alphabet chars. 5897 CHAR_UPPERCASE_A: 'A', /* A */ 5898 CHAR_LOWERCASE_A: 'a', /* a */ 5899 CHAR_UPPERCASE_Z: 'Z', /* Z */ 5900 CHAR_LOWERCASE_Z: 'z', /* z */ 5901 5902 CHAR_LEFT_PARENTHESES: '(', /* ( */ 5903 CHAR_RIGHT_PARENTHESES: ')', /* ) */ 5904 5905 CHAR_ASTERISK: '*', /* * */ 5906 5907 // Non-alphabetic chars. 5908 CHAR_AMPERSAND: '&', /* & */ 5909 CHAR_AT: '@', /* @ */ 5910 CHAR_BACKSLASH: '\\', /* \ */ 5911 CHAR_BACKTICK: '`', /* ` */ 5912 CHAR_CARRIAGE_RETURN: '\r', /* \r */ 5913 CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ 5914 CHAR_COLON: ':', /* : */ 5915 CHAR_COMMA: ',', /* , */ 5916 CHAR_DOLLAR: '$', /* . */ 5917 CHAR_DOT: '.', /* . */ 5918 CHAR_DOUBLE_QUOTE: '"', /* " */ 5919 CHAR_EQUAL: '=', /* = */ 5920 CHAR_EXCLAMATION_MARK: '!', /* ! */ 5921 CHAR_FORM_FEED: '\f', /* \f */ 5922 CHAR_FORWARD_SLASH: '/', /* / */ 5923 CHAR_HASH: '#', /* # */ 5924 CHAR_HYPHEN_MINUS: '-', /* - */ 5925 CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ 5926 CHAR_LEFT_CURLY_BRACE: '{', /* { */ 5927 CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ 5928 CHAR_LINE_FEED: '\n', /* \n */ 5929 CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ 5930 CHAR_PERCENT: '%', /* % */ 5931 CHAR_PLUS: '+', /* + */ 5932 CHAR_QUESTION_MARK: '?', /* ? */ 5933 CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ 5934 CHAR_RIGHT_CURLY_BRACE: '}', /* } */ 5935 CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ 5936 CHAR_SEMICOLON: ';', /* ; */ 5937 CHAR_SINGLE_QUOTE: '\'', /* ' */ 5938 CHAR_SPACE: ' ', /* */ 5939 CHAR_TAB: '\t', /* \t */ 5940 CHAR_UNDERSCORE: '_', /* _ */ 5941 CHAR_VERTICAL_LINE: '|', /* | */ 5942 CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ 5943 }; 5944 return constants$1; 5945 } 5946 5947 var parse_1; 5948 var hasRequiredParse; 5949 5950 function requireParse () { 5951 if (hasRequiredParse) return parse_1; 5952 hasRequiredParse = 1; 5953 5954 const stringify = /*@__PURE__*/ requireStringify(); 5955 5956 /** 5957 * Constants 5958 */ 5959 5960 const { 5961 MAX_LENGTH, 5962 CHAR_BACKSLASH, /* \ */ 5963 CHAR_BACKTICK, /* ` */ 5964 CHAR_COMMA, /* , */ 5965 CHAR_DOT, /* . */ 5966 CHAR_LEFT_PARENTHESES, /* ( */ 5967 CHAR_RIGHT_PARENTHESES, /* ) */ 5968 CHAR_LEFT_CURLY_BRACE, /* { */ 5969 CHAR_RIGHT_CURLY_BRACE, /* } */ 5970 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 5971 CHAR_RIGHT_SQUARE_BRACKET, /* ] */ 5972 CHAR_DOUBLE_QUOTE, /* " */ 5973 CHAR_SINGLE_QUOTE, /* ' */ 5974 CHAR_NO_BREAK_SPACE, 5975 CHAR_ZERO_WIDTH_NOBREAK_SPACE 5976 } = /*@__PURE__*/ requireConstants$1(); 5977 5978 /** 5979 * parse 5980 */ 5981 5982 const parse = (input, options = {}) => { 5983 if (typeof input !== 'string') { 5984 throw new TypeError('Expected a string'); 5985 } 5986 5987 const opts = options || {}; 5988 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 5989 if (input.length > max) { 5990 throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); 5991 } 5992 5993 const ast = { type: 'root', input, nodes: [] }; 5994 const stack = [ast]; 5995 let block = ast; 5996 let prev = ast; 5997 let brackets = 0; 5998 const length = input.length; 5999 let index = 0; 6000 let depth = 0; 6001 let value; 6002 6003 /** 6004 * Helpers 6005 */ 6006 6007 const advance = () => input[index++]; 6008 const push = node => { 6009 if (node.type === 'text' && prev.type === 'dot') { 6010 prev.type = 'text'; 6011 } 6012 6013 if (prev && prev.type === 'text' && node.type === 'text') { 6014 prev.value += node.value; 6015 return; 6016 } 6017 6018 block.nodes.push(node); 6019 node.parent = block; 6020 node.prev = prev; 6021 prev = node; 6022 return node; 6023 }; 6024 6025 push({ type: 'bos' }); 6026 6027 while (index < length) { 6028 block = stack[stack.length - 1]; 6029 value = advance(); 6030 6031 /** 6032 * Invalid chars 6033 */ 6034 6035 if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { 6036 continue; 6037 } 6038 6039 /** 6040 * Escaped chars 6041 */ 6042 6043 if (value === CHAR_BACKSLASH) { 6044 push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); 6045 continue; 6046 } 6047 6048 /** 6049 * Right square bracket (literal): ']' 6050 */ 6051 6052 if (value === CHAR_RIGHT_SQUARE_BRACKET) { 6053 push({ type: 'text', value: '\\' + value }); 6054 continue; 6055 } 6056 6057 /** 6058 * Left square bracket: '[' 6059 */ 6060 6061 if (value === CHAR_LEFT_SQUARE_BRACKET) { 6062 brackets++; 6063 6064 let next; 6065 6066 while (index < length && (next = advance())) { 6067 value += next; 6068 6069 if (next === CHAR_LEFT_SQUARE_BRACKET) { 6070 brackets++; 6071 continue; 6072 } 6073 6074 if (next === CHAR_BACKSLASH) { 6075 value += advance(); 6076 continue; 6077 } 6078 6079 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 6080 brackets--; 6081 6082 if (brackets === 0) { 6083 break; 6084 } 6085 } 6086 } 6087 6088 push({ type: 'text', value }); 6089 continue; 6090 } 6091 6092 /** 6093 * Parentheses 6094 */ 6095 6096 if (value === CHAR_LEFT_PARENTHESES) { 6097 block = push({ type: 'paren', nodes: [] }); 6098 stack.push(block); 6099 push({ type: 'text', value }); 6100 continue; 6101 } 6102 6103 if (value === CHAR_RIGHT_PARENTHESES) { 6104 if (block.type !== 'paren') { 6105 push({ type: 'text', value }); 6106 continue; 6107 } 6108 block = stack.pop(); 6109 push({ type: 'text', value }); 6110 block = stack[stack.length - 1]; 6111 continue; 6112 } 6113 6114 /** 6115 * Quotes: '|"|` 6116 */ 6117 6118 if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { 6119 const open = value; 6120 let next; 6121 6122 if (options.keepQuotes !== true) { 6123 value = ''; 6124 } 6125 6126 while (index < length && (next = advance())) { 6127 if (next === CHAR_BACKSLASH) { 6128 value += next + advance(); 6129 continue; 6130 } 6131 6132 if (next === open) { 6133 if (options.keepQuotes === true) value += next; 6134 break; 6135 } 6136 6137 value += next; 6138 } 6139 6140 push({ type: 'text', value }); 6141 continue; 6142 } 6143 6144 /** 6145 * Left curly brace: '{' 6146 */ 6147 6148 if (value === CHAR_LEFT_CURLY_BRACE) { 6149 depth++; 6150 6151 const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; 6152 const brace = { 6153 type: 'brace', 6154 open: true, 6155 close: false, 6156 dollar, 6157 depth, 6158 commas: 0, 6159 ranges: 0, 6160 nodes: [] 6161 }; 6162 6163 block = push(brace); 6164 stack.push(block); 6165 push({ type: 'open', value }); 6166 continue; 6167 } 6168 6169 /** 6170 * Right curly brace: '}' 6171 */ 6172 6173 if (value === CHAR_RIGHT_CURLY_BRACE) { 6174 if (block.type !== 'brace') { 6175 push({ type: 'text', value }); 6176 continue; 6177 } 6178 6179 const type = 'close'; 6180 block = stack.pop(); 6181 block.close = true; 6182 6183 push({ type, value }); 6184 depth--; 6185 6186 block = stack[stack.length - 1]; 6187 continue; 6188 } 6189 6190 /** 6191 * Comma: ',' 6192 */ 6193 6194 if (value === CHAR_COMMA && depth > 0) { 6195 if (block.ranges > 0) { 6196 block.ranges = 0; 6197 const open = block.nodes.shift(); 6198 block.nodes = [open, { type: 'text', value: stringify(block) }]; 6199 } 6200 6201 push({ type: 'comma', value }); 6202 block.commas++; 6203 continue; 6204 } 6205 6206 /** 6207 * Dot: '.' 6208 */ 6209 6210 if (value === CHAR_DOT && depth > 0 && block.commas === 0) { 6211 const siblings = block.nodes; 6212 6213 if (depth === 0 || siblings.length === 0) { 6214 push({ type: 'text', value }); 6215 continue; 6216 } 6217 6218 if (prev.type === 'dot') { 6219 block.range = []; 6220 prev.value += value; 6221 prev.type = 'range'; 6222 6223 if (block.nodes.length !== 3 && block.nodes.length !== 5) { 6224 block.invalid = true; 6225 block.ranges = 0; 6226 prev.type = 'text'; 6227 continue; 6228 } 6229 6230 block.ranges++; 6231 block.args = []; 6232 continue; 6233 } 6234 6235 if (prev.type === 'range') { 6236 siblings.pop(); 6237 6238 const before = siblings[siblings.length - 1]; 6239 before.value += prev.value + value; 6240 prev = before; 6241 block.ranges--; 6242 continue; 6243 } 6244 6245 push({ type: 'dot', value }); 6246 continue; 6247 } 6248 6249 /** 6250 * Text 6251 */ 6252 6253 push({ type: 'text', value }); 6254 } 6255 6256 // Mark imbalanced braces and brackets as invalid 6257 do { 6258 block = stack.pop(); 6259 6260 if (block.type !== 'root') { 6261 block.nodes.forEach(node => { 6262 if (!node.nodes) { 6263 if (node.type === 'open') node.isOpen = true; 6264 if (node.type === 'close') node.isClose = true; 6265 if (!node.nodes) node.type = 'text'; 6266 node.invalid = true; 6267 } 6268 }); 6269 6270 // get the location of the block on parent.nodes (block's siblings) 6271 const parent = stack[stack.length - 1]; 6272 const index = parent.nodes.indexOf(block); 6273 // replace the (invalid) block with it's nodes 6274 parent.nodes.splice(index, 1, ...block.nodes); 6275 } 6276 } while (stack.length > 0); 6277 6278 push({ type: 'eos' }); 6279 return ast; 6280 }; 6281 6282 parse_1 = parse; 6283 return parse_1; 6284 } 6285 6286 var braces_1; 6287 var hasRequiredBraces; 6288 6289 function requireBraces () { 6290 if (hasRequiredBraces) return braces_1; 6291 hasRequiredBraces = 1; 6292 6293 const stringify = /*@__PURE__*/ requireStringify(); 6294 const compile = /*@__PURE__*/ requireCompile(); 6295 const expand = /*@__PURE__*/ requireExpand(); 6296 const parse = /*@__PURE__*/ requireParse(); 6297 6298 /** 6299 * Expand the given pattern or create a regex-compatible string. 6300 * 6301 * ```js 6302 * const braces = require('braces'); 6303 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] 6304 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] 6305 * ``` 6306 * @param {String} `str` 6307 * @param {Object} `options` 6308 * @return {String} 6309 * @api public 6310 */ 6311 6312 const braces = (input, options = {}) => { 6313 let output = []; 6314 6315 if (Array.isArray(input)) { 6316 for (const pattern of input) { 6317 const result = braces.create(pattern, options); 6318 if (Array.isArray(result)) { 6319 output.push(...result); 6320 } else { 6321 output.push(result); 6322 } 6323 } 6324 } else { 6325 output = [].concat(braces.create(input, options)); 6326 } 6327 6328 if (options && options.expand === true && options.nodupes === true) { 6329 output = [...new Set(output)]; 6330 } 6331 return output; 6332 }; 6333 6334 /** 6335 * Parse the given `str` with the given `options`. 6336 * 6337 * ```js 6338 * // braces.parse(pattern, [, options]); 6339 * const ast = braces.parse('a/{b,c}/d'); 6340 * console.log(ast); 6341 * ``` 6342 * @param {String} pattern Brace pattern to parse 6343 * @param {Object} options 6344 * @return {Object} Returns an AST 6345 * @api public 6346 */ 6347 6348 braces.parse = (input, options = {}) => parse(input, options); 6349 6350 /** 6351 * Creates a braces string from an AST, or an AST node. 6352 * 6353 * ```js 6354 * const braces = require('braces'); 6355 * let ast = braces.parse('foo/{a,b}/bar'); 6356 * console.log(stringify(ast.nodes[2])); //=> '{a,b}' 6357 * ``` 6358 * @param {String} `input` Brace pattern or AST. 6359 * @param {Object} `options` 6360 * @return {Array} Returns an array of expanded values. 6361 * @api public 6362 */ 6363 6364 braces.stringify = (input, options = {}) => { 6365 if (typeof input === 'string') { 6366 return stringify(braces.parse(input, options), options); 6367 } 6368 return stringify(input, options); 6369 }; 6370 6371 /** 6372 * Compiles a brace pattern into a regex-compatible, optimized string. 6373 * This method is called by the main [braces](#braces) function by default. 6374 * 6375 * ```js 6376 * const braces = require('braces'); 6377 * console.log(braces.compile('a/{b,c}/d')); 6378 * //=> ['a/(b|c)/d'] 6379 * ``` 6380 * @param {String} `input` Brace pattern or AST. 6381 * @param {Object} `options` 6382 * @return {Array} Returns an array of expanded values. 6383 * @api public 6384 */ 6385 6386 braces.compile = (input, options = {}) => { 6387 if (typeof input === 'string') { 6388 input = braces.parse(input, options); 6389 } 6390 return compile(input, options); 6391 }; 6392 6393 /** 6394 * Expands a brace pattern into an array. This method is called by the 6395 * main [braces](#braces) function when `options.expand` is true. Before 6396 * using this method it's recommended that you read the [performance notes](#performance)) 6397 * and advantages of using [.compile](#compile) instead. 6398 * 6399 * ```js 6400 * const braces = require('braces'); 6401 * console.log(braces.expand('a/{b,c}/d')); 6402 * //=> ['a/b/d', 'a/c/d']; 6403 * ``` 6404 * @param {String} `pattern` Brace pattern 6405 * @param {Object} `options` 6406 * @return {Array} Returns an array of expanded values. 6407 * @api public 6408 */ 6409 6410 braces.expand = (input, options = {}) => { 6411 if (typeof input === 'string') { 6412 input = braces.parse(input, options); 6413 } 6414 6415 let result = expand(input, options); 6416 6417 // filter out empty strings if specified 6418 if (options.noempty === true) { 6419 result = result.filter(Boolean); 6420 } 6421 6422 // filter out duplicates if specified 6423 if (options.nodupes === true) { 6424 result = [...new Set(result)]; 6425 } 6426 6427 return result; 6428 }; 6429 6430 /** 6431 * Processes a brace pattern and returns either an expanded array 6432 * (if `options.expand` is true), a highly optimized regex-compatible string. 6433 * This method is called by the main [braces](#braces) function. 6434 * 6435 * ```js 6436 * const braces = require('braces'); 6437 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) 6438 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' 6439 * ``` 6440 * @param {String} `pattern` Brace pattern 6441 * @param {Object} `options` 6442 * @return {Array} Returns an array of expanded values. 6443 * @api public 6444 */ 6445 6446 braces.create = (input, options = {}) => { 6447 if (input === '' || input.length < 3) { 6448 return [input]; 6449 } 6450 6451 return options.expand !== true 6452 ? braces.compile(input, options) 6453 : braces.expand(input, options); 6454 }; 6455 6456 /** 6457 * Expose "braces" 6458 */ 6459 6460 braces_1 = braces; 6461 return braces_1; 6462 } 2099 6463 2100 6464 const require$$0 = [ … … 2362 6726 ]; 2363 6727 2364 var binaryExtensions$1 = require$$0; 2365 2366 const path = require$$0$2; 2367 const binaryExtensions = binaryExtensions$1; 2368 2369 const extensions = new Set(binaryExtensions); 2370 2371 var isBinaryPath$1 = filePath => extensions.has(path.extname(filePath).slice(1).toLowerCase()); 6728 var binaryExtensions; 6729 var hasRequiredBinaryExtensions; 6730 6731 function requireBinaryExtensions () { 6732 if (hasRequiredBinaryExtensions) return binaryExtensions; 6733 hasRequiredBinaryExtensions = 1; 6734 binaryExtensions = require$$0; 6735 return binaryExtensions; 6736 } 6737 6738 var isBinaryPath; 6739 var hasRequiredIsBinaryPath; 6740 6741 function requireIsBinaryPath () { 6742 if (hasRequiredIsBinaryPath) return isBinaryPath; 6743 hasRequiredIsBinaryPath = 1; 6744 const path = require$$0$1; 6745 const binaryExtensions = /*@__PURE__*/ requireBinaryExtensions(); 6746 6747 const extensions = new Set(binaryExtensions); 6748 6749 isBinaryPath = filePath => extensions.has(path.extname(filePath).slice(1).toLowerCase()); 6750 return isBinaryPath; 6751 } 2372 6752 2373 6753 var constants = {}; 2374 6754 2375 (function (exports) { 2376 2377 const {sep} = require$$0$2; 2378 const {platform} = process; 2379 const os = require$$2$1; 2380 2381 exports.EV_ALL = 'all'; 2382 exports.EV_READY = 'ready'; 2383 exports.EV_ADD = 'add'; 2384 exports.EV_CHANGE = 'change'; 2385 exports.EV_ADD_DIR = 'addDir'; 2386 exports.EV_UNLINK = 'unlink'; 2387 exports.EV_UNLINK_DIR = 'unlinkDir'; 2388 exports.EV_RAW = 'raw'; 2389 exports.EV_ERROR = 'error'; 2390 2391 exports.STR_DATA = 'data'; 2392 exports.STR_END = 'end'; 2393 exports.STR_CLOSE = 'close'; 2394 2395 exports.FSEVENT_CREATED = 'created'; 2396 exports.FSEVENT_MODIFIED = 'modified'; 2397 exports.FSEVENT_DELETED = 'deleted'; 2398 exports.FSEVENT_MOVED = 'moved'; 2399 exports.FSEVENT_CLONED = 'cloned'; 2400 exports.FSEVENT_UNKNOWN = 'unknown'; 2401 exports.FSEVENT_FLAG_MUST_SCAN_SUBDIRS = 1; 2402 exports.FSEVENT_TYPE_FILE = 'file'; 2403 exports.FSEVENT_TYPE_DIRECTORY = 'directory'; 2404 exports.FSEVENT_TYPE_SYMLINK = 'symlink'; 2405 2406 exports.KEY_LISTENERS = 'listeners'; 2407 exports.KEY_ERR = 'errHandlers'; 2408 exports.KEY_RAW = 'rawEmitters'; 2409 exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW]; 2410 2411 exports.DOT_SLASH = `.${sep}`; 2412 2413 exports.BACK_SLASH_RE = /\\/g; 2414 exports.DOUBLE_SLASH_RE = /\/\//; 2415 exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/; 2416 exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; 2417 exports.REPLACER_RE = /^\.[/\\]/; 2418 2419 exports.SLASH = '/'; 2420 exports.SLASH_SLASH = '//'; 2421 exports.BRACE_START = '{'; 2422 exports.BANG = '!'; 2423 exports.ONE_DOT = '.'; 2424 exports.TWO_DOTS = '..'; 2425 exports.STAR = '*'; 2426 exports.GLOBSTAR = '**'; 2427 exports.ROOT_GLOBSTAR = '/**/*'; 2428 exports.SLASH_GLOBSTAR = '/**'; 2429 exports.DIR_SUFFIX = 'Dir'; 2430 exports.ANYMATCH_OPTS = {dot: true}; 2431 exports.STRING_TYPE = 'string'; 2432 exports.FUNCTION_TYPE = 'function'; 2433 exports.EMPTY_STR = ''; 2434 exports.EMPTY_FN = () => {}; 2435 exports.IDENTITY_FN = val => val; 2436 2437 exports.isWindows = platform === 'win32'; 2438 exports.isMacos = platform === 'darwin'; 2439 exports.isLinux = platform === 'linux'; 2440 exports.isIBMi = os.type() === 'OS400'; 2441 } (constants)); 2442 2443 const fs$2 = require$$0$1; 2444 const sysPath$2 = require$$0$2; 2445 const { promisify: promisify$2 } = require$$2; 2446 const isBinaryPath = isBinaryPath$1; 2447 const { 2448 isWindows: isWindows$1, 2449 isLinux, 2450 EMPTY_FN: EMPTY_FN$2, 2451 EMPTY_STR: EMPTY_STR$1, 2452 KEY_LISTENERS, 2453 KEY_ERR, 2454 KEY_RAW, 2455 HANDLER_KEYS, 2456 EV_CHANGE: EV_CHANGE$2, 2457 EV_ADD: EV_ADD$2, 2458 EV_ADD_DIR: EV_ADD_DIR$2, 2459 EV_ERROR: EV_ERROR$2, 2460 STR_DATA: STR_DATA$1, 2461 STR_END: STR_END$2, 2462 BRACE_START: BRACE_START$1, 2463 STAR 2464 } = constants; 2465 2466 const THROTTLE_MODE_WATCH = 'watch'; 2467 2468 const open = promisify$2(fs$2.open); 2469 const stat$2 = promisify$2(fs$2.stat); 2470 const lstat$1 = promisify$2(fs$2.lstat); 2471 const close = promisify$2(fs$2.close); 2472 const fsrealpath = promisify$2(fs$2.realpath); 2473 2474 const statMethods$1 = { lstat: lstat$1, stat: stat$2 }; 2475 2476 // TODO: emit errors properly. Example: EMFILE on Macos. 2477 const foreach = (val, fn) => { 2478 if (val instanceof Set) { 2479 val.forEach(fn); 2480 } else { 2481 fn(val); 2482 } 2483 }; 2484 2485 const addAndConvert = (main, prop, item) => { 2486 let container = main[prop]; 2487 if (!(container instanceof Set)) { 2488 main[prop] = container = new Set([container]); 2489 } 2490 container.add(item); 2491 }; 2492 2493 const clearItem = cont => key => { 2494 const set = cont[key]; 2495 if (set instanceof Set) { 2496 set.clear(); 2497 } else { 2498 delete cont[key]; 2499 } 2500 }; 2501 2502 const delFromSet = (main, prop, item) => { 2503 const container = main[prop]; 2504 if (container instanceof Set) { 2505 container.delete(item); 2506 } else if (container === item) { 2507 delete main[prop]; 2508 } 2509 }; 2510 2511 const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val; 2512 2513 /** 2514 * @typedef {String} Path 2515 */ 2516 2517 // fs_watch helpers 2518 2519 // object to hold per-process fs_watch instances 2520 // (may be shared across chokidar FSWatcher instances) 2521 2522 /** 2523 * @typedef {Object} FsWatchContainer 2524 * @property {Set} listeners 2525 * @property {Set} errHandlers 2526 * @property {Set} rawEmitters 2527 * @property {fs.FSWatcher=} watcher 2528 * @property {Boolean=} watcherUnusable 2529 */ 2530 2531 /** 2532 * @type {Map<String,FsWatchContainer>} 2533 */ 2534 const FsWatchInstances = new Map(); 2535 2536 /** 2537 * Instantiates the fs_watch interface 2538 * @param {String} path to be watched 2539 * @param {Object} options to be passed to fs_watch 2540 * @param {Function} listener main event handler 2541 * @param {Function} errHandler emits info about errors 2542 * @param {Function} emitRaw emits raw event data 2543 * @returns {fs.FSWatcher} new fsevents instance 2544 */ 2545 function createFsWatchInstance(path, options, listener, errHandler, emitRaw) { 2546 const handleEvent = (rawEvent, evPath) => { 2547 listener(path); 2548 emitRaw(rawEvent, evPath, {watchedPath: path}); 2549 2550 // emit based on events occurring for files from a directory's watcher in 2551 // case the file's watcher misses it (and rely on throttling to de-dupe) 2552 if (evPath && path !== evPath) { 2553 fsWatchBroadcast( 2554 sysPath$2.resolve(path, evPath), KEY_LISTENERS, sysPath$2.join(path, evPath) 2555 ); 2556 } 2557 }; 2558 try { 2559 return fs$2.watch(path, options, handleEvent); 2560 } catch (error) { 2561 errHandler(error); 2562 } 6755 var hasRequiredConstants; 6756 6757 function requireConstants () { 6758 if (hasRequiredConstants) return constants; 6759 hasRequiredConstants = 1; 6760 (function (exports) { 6761 6762 const {sep} = require$$0$1; 6763 const {platform} = process; 6764 const os = require$$2$1; 6765 6766 exports.EV_ALL = 'all'; 6767 exports.EV_READY = 'ready'; 6768 exports.EV_ADD = 'add'; 6769 exports.EV_CHANGE = 'change'; 6770 exports.EV_ADD_DIR = 'addDir'; 6771 exports.EV_UNLINK = 'unlink'; 6772 exports.EV_UNLINK_DIR = 'unlinkDir'; 6773 exports.EV_RAW = 'raw'; 6774 exports.EV_ERROR = 'error'; 6775 6776 exports.STR_DATA = 'data'; 6777 exports.STR_END = 'end'; 6778 exports.STR_CLOSE = 'close'; 6779 6780 exports.FSEVENT_CREATED = 'created'; 6781 exports.FSEVENT_MODIFIED = 'modified'; 6782 exports.FSEVENT_DELETED = 'deleted'; 6783 exports.FSEVENT_MOVED = 'moved'; 6784 exports.FSEVENT_CLONED = 'cloned'; 6785 exports.FSEVENT_UNKNOWN = 'unknown'; 6786 exports.FSEVENT_FLAG_MUST_SCAN_SUBDIRS = 1; 6787 exports.FSEVENT_TYPE_FILE = 'file'; 6788 exports.FSEVENT_TYPE_DIRECTORY = 'directory'; 6789 exports.FSEVENT_TYPE_SYMLINK = 'symlink'; 6790 6791 exports.KEY_LISTENERS = 'listeners'; 6792 exports.KEY_ERR = 'errHandlers'; 6793 exports.KEY_RAW = 'rawEmitters'; 6794 exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW]; 6795 6796 exports.DOT_SLASH = `.${sep}`; 6797 6798 exports.BACK_SLASH_RE = /\\/g; 6799 exports.DOUBLE_SLASH_RE = /\/\//; 6800 exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/; 6801 exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; 6802 exports.REPLACER_RE = /^\.[/\\]/; 6803 6804 exports.SLASH = '/'; 6805 exports.SLASH_SLASH = '//'; 6806 exports.BRACE_START = '{'; 6807 exports.BANG = '!'; 6808 exports.ONE_DOT = '.'; 6809 exports.TWO_DOTS = '..'; 6810 exports.STAR = '*'; 6811 exports.GLOBSTAR = '**'; 6812 exports.ROOT_GLOBSTAR = '/**/*'; 6813 exports.SLASH_GLOBSTAR = '/**'; 6814 exports.DIR_SUFFIX = 'Dir'; 6815 exports.ANYMATCH_OPTS = {dot: true}; 6816 exports.STRING_TYPE = 'string'; 6817 exports.FUNCTION_TYPE = 'function'; 6818 exports.EMPTY_STR = ''; 6819 exports.EMPTY_FN = () => {}; 6820 exports.IDENTITY_FN = val => val; 6821 6822 exports.isWindows = platform === 'win32'; 6823 exports.isMacos = platform === 'darwin'; 6824 exports.isLinux = platform === 'linux'; 6825 exports.isIBMi = os.type() === 'OS400'; 6826 } (constants)); 6827 return constants; 2563 6828 } 2564 6829 2565 /** 2566 * Helper for passing fs_watch event data to a collection of listeners 2567 * @param {Path} fullPath absolute path bound to fs_watch instance 2568 * @param {String} type listener type 2569 * @param {*=} val1 arguments to be passed to listeners 2570 * @param {*=} val2 2571 * @param {*=} val3 2572 */ 2573 const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => { 2574 const cont = FsWatchInstances.get(fullPath); 2575 if (!cont) return; 2576 foreach(cont[type], (listener) => { 2577 listener(val1, val2, val3); 2578 }); 2579 }; 2580 2581 /** 2582 * Instantiates the fs_watch interface or binds listeners 2583 * to an existing one covering the same file system entry 2584 * @param {String} path 2585 * @param {String} fullPath absolute path 2586 * @param {Object} options to be passed to fs_watch 2587 * @param {Object} handlers container for event listener functions 2588 */ 2589 const setFsWatchListener = (path, fullPath, options, handlers) => { 2590 const {listener, errHandler, rawEmitter} = handlers; 2591 let cont = FsWatchInstances.get(fullPath); 2592 2593 /** @type {fs.FSWatcher=} */ 2594 let watcher; 2595 if (!options.persistent) { 2596 watcher = createFsWatchInstance( 2597 path, options, listener, errHandler, rawEmitter 2598 ); 2599 return watcher.close.bind(watcher); 2600 } 2601 if (cont) { 2602 addAndConvert(cont, KEY_LISTENERS, listener); 2603 addAndConvert(cont, KEY_ERR, errHandler); 2604 addAndConvert(cont, KEY_RAW, rawEmitter); 2605 } else { 2606 watcher = createFsWatchInstance( 2607 path, 2608 options, 2609 fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), 2610 errHandler, // no need to use broadcast here 2611 fsWatchBroadcast.bind(null, fullPath, KEY_RAW) 2612 ); 2613 if (!watcher) return; 2614 watcher.on(EV_ERROR$2, async (error) => { 2615 const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); 2616 cont.watcherUnusable = true; // documented since Node 10.4.1 2617 // Workaround for https://github.com/joyent/node/issues/4337 2618 if (isWindows$1 && error.code === 'EPERM') { 2619 try { 2620 const fd = await open(path, 'r'); 2621 await close(fd); 2622 broadcastErr(error); 2623 } catch (err) {} 2624 } else { 2625 broadcastErr(error); 2626 } 2627 }); 2628 cont = { 2629 listeners: listener, 2630 errHandlers: errHandler, 2631 rawEmitters: rawEmitter, 2632 watcher 2633 }; 2634 FsWatchInstances.set(fullPath, cont); 2635 } 2636 // const index = cont.listeners.indexOf(listener); 2637 2638 // removes this instance's listeners and closes the underlying fs_watch 2639 // instance if there are no more listeners left 2640 return () => { 2641 delFromSet(cont, KEY_LISTENERS, listener); 2642 delFromSet(cont, KEY_ERR, errHandler); 2643 delFromSet(cont, KEY_RAW, rawEmitter); 2644 if (isEmptySet(cont.listeners)) { 2645 // Check to protect against issue gh-730. 2646 // if (cont.watcherUnusable) { 2647 cont.watcher.close(); 2648 // } 2649 FsWatchInstances.delete(fullPath); 2650 HANDLER_KEYS.forEach(clearItem(cont)); 2651 cont.watcher = undefined; 2652 Object.freeze(cont); 2653 } 2654 }; 2655 }; 2656 2657 // fs_watchFile helpers 2658 2659 // object to hold per-process fs_watchFile instances 2660 // (may be shared across chokidar FSWatcher instances) 2661 const FsWatchFileInstances = new Map(); 2662 2663 /** 2664 * Instantiates the fs_watchFile interface or binds listeners 2665 * to an existing one covering the same file system entry 2666 * @param {String} path to be watched 2667 * @param {String} fullPath absolute path 2668 * @param {Object} options options to be passed to fs_watchFile 2669 * @param {Object} handlers container for event listener functions 2670 * @returns {Function} closer 2671 */ 2672 const setFsWatchFileListener = (path, fullPath, options, handlers) => { 2673 const {listener, rawEmitter} = handlers; 2674 let cont = FsWatchFileInstances.get(fullPath); 2675 2676 const copts = cont && cont.options; 2677 if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { 2678 fs$2.unwatchFile(fullPath); 2679 cont = undefined; 2680 } 2681 2682 /* eslint-enable no-unused-vars, prefer-destructuring */ 2683 2684 if (cont) { 2685 addAndConvert(cont, KEY_LISTENERS, listener); 2686 addAndConvert(cont, KEY_RAW, rawEmitter); 2687 } else { 2688 // TODO 2689 // listeners.add(listener); 2690 // rawEmitters.add(rawEmitter); 2691 cont = { 2692 listeners: listener, 2693 rawEmitters: rawEmitter, 2694 options, 2695 watcher: fs$2.watchFile(fullPath, options, (curr, prev) => { 2696 foreach(cont.rawEmitters, (rawEmitter) => { 2697 rawEmitter(EV_CHANGE$2, fullPath, {curr, prev}); 2698 }); 2699 const currmtime = curr.mtimeMs; 2700 if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { 2701 foreach(cont.listeners, (listener) => listener(path, curr)); 2702 } 2703 }) 2704 }; 2705 FsWatchFileInstances.set(fullPath, cont); 2706 } 2707 // const index = cont.listeners.indexOf(listener); 2708 2709 // Removes this instance's listeners and closes the underlying fs_watchFile 2710 // instance if there are no more listeners left. 2711 return () => { 2712 delFromSet(cont, KEY_LISTENERS, listener); 2713 delFromSet(cont, KEY_RAW, rawEmitter); 2714 if (isEmptySet(cont.listeners)) { 2715 FsWatchFileInstances.delete(fullPath); 2716 fs$2.unwatchFile(fullPath); 2717 cont.options = cont.watcher = undefined; 2718 Object.freeze(cont); 2719 } 2720 }; 2721 }; 2722 2723 /** 2724 * @mixin 2725 */ 2726 let NodeFsHandler$1 = class NodeFsHandler { 2727 2728 /** 2729 * @param {import("../index").FSWatcher} fsW 2730 */ 2731 constructor(fsW) { 2732 this.fsw = fsW; 2733 this._boundHandleError = (error) => fsW._handleError(error); 6830 var nodefsHandler; 6831 var hasRequiredNodefsHandler; 6832 6833 function requireNodefsHandler () { 6834 if (hasRequiredNodefsHandler) return nodefsHandler; 6835 hasRequiredNodefsHandler = 1; 6836 6837 const fs = require$$0$2; 6838 const sysPath = require$$0$1; 6839 const { promisify } = require$$2; 6840 const isBinaryPath = /*@__PURE__*/ requireIsBinaryPath(); 6841 const { 6842 isWindows, 6843 isLinux, 6844 EMPTY_FN, 6845 EMPTY_STR, 6846 KEY_LISTENERS, 6847 KEY_ERR, 6848 KEY_RAW, 6849 HANDLER_KEYS, 6850 EV_CHANGE, 6851 EV_ADD, 6852 EV_ADD_DIR, 6853 EV_ERROR, 6854 STR_DATA, 6855 STR_END, 6856 BRACE_START, 6857 STAR 6858 } = /*@__PURE__*/ requireConstants(); 6859 6860 const THROTTLE_MODE_WATCH = 'watch'; 6861 6862 const open = promisify(fs.open); 6863 const stat = promisify(fs.stat); 6864 const lstat = promisify(fs.lstat); 6865 const close = promisify(fs.close); 6866 const fsrealpath = promisify(fs.realpath); 6867 6868 const statMethods = { lstat, stat }; 6869 6870 // TODO: emit errors properly. Example: EMFILE on Macos. 6871 const foreach = (val, fn) => { 6872 if (val instanceof Set) { 6873 val.forEach(fn); 6874 } else { 6875 fn(val); 6876 } 6877 }; 6878 6879 const addAndConvert = (main, prop, item) => { 6880 let container = main[prop]; 6881 if (!(container instanceof Set)) { 6882 main[prop] = container = new Set([container]); 6883 } 6884 container.add(item); 6885 }; 6886 6887 const clearItem = cont => key => { 6888 const set = cont[key]; 6889 if (set instanceof Set) { 6890 set.clear(); 6891 } else { 6892 delete cont[key]; 6893 } 6894 }; 6895 6896 const delFromSet = (main, prop, item) => { 6897 const container = main[prop]; 6898 if (container instanceof Set) { 6899 container.delete(item); 6900 } else if (container === item) { 6901 delete main[prop]; 6902 } 6903 }; 6904 6905 const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val; 6906 6907 /** 6908 * @typedef {String} Path 6909 */ 6910 6911 // fs_watch helpers 6912 6913 // object to hold per-process fs_watch instances 6914 // (may be shared across chokidar FSWatcher instances) 6915 6916 /** 6917 * @typedef {Object} FsWatchContainer 6918 * @property {Set} listeners 6919 * @property {Set} errHandlers 6920 * @property {Set} rawEmitters 6921 * @property {fs.FSWatcher=} watcher 6922 * @property {Boolean=} watcherUnusable 6923 */ 6924 6925 /** 6926 * @type {Map<String,FsWatchContainer>} 6927 */ 6928 const FsWatchInstances = new Map(); 6929 6930 /** 6931 * Instantiates the fs_watch interface 6932 * @param {String} path to be watched 6933 * @param {Object} options to be passed to fs_watch 6934 * @param {Function} listener main event handler 6935 * @param {Function} errHandler emits info about errors 6936 * @param {Function} emitRaw emits raw event data 6937 * @returns {fs.FSWatcher} new fsevents instance 6938 */ 6939 function createFsWatchInstance(path, options, listener, errHandler, emitRaw) { 6940 const handleEvent = (rawEvent, evPath) => { 6941 listener(path); 6942 emitRaw(rawEvent, evPath, {watchedPath: path}); 6943 6944 // emit based on events occurring for files from a directory's watcher in 6945 // case the file's watcher misses it (and rely on throttling to de-dupe) 6946 if (evPath && path !== evPath) { 6947 fsWatchBroadcast( 6948 sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath) 6949 ); 6950 } 6951 }; 6952 try { 6953 return fs.watch(path, options, handleEvent); 6954 } catch (error) { 6955 errHandler(error); 6956 } 6957 } 6958 6959 /** 6960 * Helper for passing fs_watch event data to a collection of listeners 6961 * @param {Path} fullPath absolute path bound to fs_watch instance 6962 * @param {String} type listener type 6963 * @param {*=} val1 arguments to be passed to listeners 6964 * @param {*=} val2 6965 * @param {*=} val3 6966 */ 6967 const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => { 6968 const cont = FsWatchInstances.get(fullPath); 6969 if (!cont) return; 6970 foreach(cont[type], (listener) => { 6971 listener(val1, val2, val3); 6972 }); 6973 }; 6974 6975 /** 6976 * Instantiates the fs_watch interface or binds listeners 6977 * to an existing one covering the same file system entry 6978 * @param {String} path 6979 * @param {String} fullPath absolute path 6980 * @param {Object} options to be passed to fs_watch 6981 * @param {Object} handlers container for event listener functions 6982 */ 6983 const setFsWatchListener = (path, fullPath, options, handlers) => { 6984 const {listener, errHandler, rawEmitter} = handlers; 6985 let cont = FsWatchInstances.get(fullPath); 6986 6987 /** @type {fs.FSWatcher=} */ 6988 let watcher; 6989 if (!options.persistent) { 6990 watcher = createFsWatchInstance( 6991 path, options, listener, errHandler, rawEmitter 6992 ); 6993 return watcher.close.bind(watcher); 6994 } 6995 if (cont) { 6996 addAndConvert(cont, KEY_LISTENERS, listener); 6997 addAndConvert(cont, KEY_ERR, errHandler); 6998 addAndConvert(cont, KEY_RAW, rawEmitter); 6999 } else { 7000 watcher = createFsWatchInstance( 7001 path, 7002 options, 7003 fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), 7004 errHandler, // no need to use broadcast here 7005 fsWatchBroadcast.bind(null, fullPath, KEY_RAW) 7006 ); 7007 if (!watcher) return; 7008 watcher.on(EV_ERROR, async (error) => { 7009 const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); 7010 cont.watcherUnusable = true; // documented since Node 10.4.1 7011 // Workaround for https://github.com/joyent/node/issues/4337 7012 if (isWindows && error.code === 'EPERM') { 7013 try { 7014 const fd = await open(path, 'r'); 7015 await close(fd); 7016 broadcastErr(error); 7017 } catch (err) {} 7018 } else { 7019 broadcastErr(error); 7020 } 7021 }); 7022 cont = { 7023 listeners: listener, 7024 errHandlers: errHandler, 7025 rawEmitters: rawEmitter, 7026 watcher 7027 }; 7028 FsWatchInstances.set(fullPath, cont); 7029 } 7030 // const index = cont.listeners.indexOf(listener); 7031 7032 // removes this instance's listeners and closes the underlying fs_watch 7033 // instance if there are no more listeners left 7034 return () => { 7035 delFromSet(cont, KEY_LISTENERS, listener); 7036 delFromSet(cont, KEY_ERR, errHandler); 7037 delFromSet(cont, KEY_RAW, rawEmitter); 7038 if (isEmptySet(cont.listeners)) { 7039 // Check to protect against issue gh-730. 7040 // if (cont.watcherUnusable) { 7041 cont.watcher.close(); 7042 // } 7043 FsWatchInstances.delete(fullPath); 7044 HANDLER_KEYS.forEach(clearItem(cont)); 7045 cont.watcher = undefined; 7046 Object.freeze(cont); 7047 } 7048 }; 7049 }; 7050 7051 // fs_watchFile helpers 7052 7053 // object to hold per-process fs_watchFile instances 7054 // (may be shared across chokidar FSWatcher instances) 7055 const FsWatchFileInstances = new Map(); 7056 7057 /** 7058 * Instantiates the fs_watchFile interface or binds listeners 7059 * to an existing one covering the same file system entry 7060 * @param {String} path to be watched 7061 * @param {String} fullPath absolute path 7062 * @param {Object} options options to be passed to fs_watchFile 7063 * @param {Object} handlers container for event listener functions 7064 * @returns {Function} closer 7065 */ 7066 const setFsWatchFileListener = (path, fullPath, options, handlers) => { 7067 const {listener, rawEmitter} = handlers; 7068 let cont = FsWatchFileInstances.get(fullPath); 7069 7070 const copts = cont && cont.options; 7071 if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { 7072 fs.unwatchFile(fullPath); 7073 cont = undefined; 7074 } 7075 7076 /* eslint-enable no-unused-vars, prefer-destructuring */ 7077 7078 if (cont) { 7079 addAndConvert(cont, KEY_LISTENERS, listener); 7080 addAndConvert(cont, KEY_RAW, rawEmitter); 7081 } else { 7082 // TODO 7083 // listeners.add(listener); 7084 // rawEmitters.add(rawEmitter); 7085 cont = { 7086 listeners: listener, 7087 rawEmitters: rawEmitter, 7088 options, 7089 watcher: fs.watchFile(fullPath, options, (curr, prev) => { 7090 foreach(cont.rawEmitters, (rawEmitter) => { 7091 rawEmitter(EV_CHANGE, fullPath, {curr, prev}); 7092 }); 7093 const currmtime = curr.mtimeMs; 7094 if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { 7095 foreach(cont.listeners, (listener) => listener(path, curr)); 7096 } 7097 }) 7098 }; 7099 FsWatchFileInstances.set(fullPath, cont); 7100 } 7101 // const index = cont.listeners.indexOf(listener); 7102 7103 // Removes this instance's listeners and closes the underlying fs_watchFile 7104 // instance if there are no more listeners left. 7105 return () => { 7106 delFromSet(cont, KEY_LISTENERS, listener); 7107 delFromSet(cont, KEY_RAW, rawEmitter); 7108 if (isEmptySet(cont.listeners)) { 7109 FsWatchFileInstances.delete(fullPath); 7110 fs.unwatchFile(fullPath); 7111 cont.options = cont.watcher = undefined; 7112 Object.freeze(cont); 7113 } 7114 }; 7115 }; 7116 7117 /** 7118 * @mixin 7119 */ 7120 class NodeFsHandler { 7121 7122 /** 7123 * @param {import("../index").FSWatcher} fsW 7124 */ 7125 constructor(fsW) { 7126 this.fsw = fsW; 7127 this._boundHandleError = (error) => fsW._handleError(error); 7128 } 7129 7130 /** 7131 * Watch file for changes with fs_watchFile or fs_watch. 7132 * @param {String} path to file or dir 7133 * @param {Function} listener on fs change 7134 * @returns {Function} closer for the watcher instance 7135 */ 7136 _watchWithNodeFs(path, listener) { 7137 const opts = this.fsw.options; 7138 const directory = sysPath.dirname(path); 7139 const basename = sysPath.basename(path); 7140 const parent = this.fsw._getWatchedDir(directory); 7141 parent.add(basename); 7142 const absolutePath = sysPath.resolve(path); 7143 const options = {persistent: opts.persistent}; 7144 if (!listener) listener = EMPTY_FN; 7145 7146 let closer; 7147 if (opts.usePolling) { 7148 options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ? 7149 opts.binaryInterval : opts.interval; 7150 closer = setFsWatchFileListener(path, absolutePath, options, { 7151 listener, 7152 rawEmitter: this.fsw._emitRaw 7153 }); 7154 } else { 7155 closer = setFsWatchListener(path, absolutePath, options, { 7156 listener, 7157 errHandler: this._boundHandleError, 7158 rawEmitter: this.fsw._emitRaw 7159 }); 7160 } 7161 return closer; 7162 } 7163 7164 /** 7165 * Watch a file and emit add event if warranted. 7166 * @param {Path} file Path 7167 * @param {fs.Stats} stats result of fs_stat 7168 * @param {Boolean} initialAdd was the file added at watch instantiation? 7169 * @returns {Function} closer for the watcher instance 7170 */ 7171 _handleFile(file, stats, initialAdd) { 7172 if (this.fsw.closed) { 7173 return; 7174 } 7175 const dirname = sysPath.dirname(file); 7176 const basename = sysPath.basename(file); 7177 const parent = this.fsw._getWatchedDir(dirname); 7178 // stats is always present 7179 let prevStats = stats; 7180 7181 // if the file is already being watched, do nothing 7182 if (parent.has(basename)) return; 7183 7184 const listener = async (path, newStats) => { 7185 if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return; 7186 if (!newStats || newStats.mtimeMs === 0) { 7187 try { 7188 const newStats = await stat(file); 7189 if (this.fsw.closed) return; 7190 // Check that change event was not fired because of changed only accessTime. 7191 const at = newStats.atimeMs; 7192 const mt = newStats.mtimeMs; 7193 if (!at || at <= mt || mt !== prevStats.mtimeMs) { 7194 this.fsw._emit(EV_CHANGE, file, newStats); 7195 } 7196 if (isLinux && prevStats.ino !== newStats.ino) { 7197 this.fsw._closeFile(path); 7198 prevStats = newStats; 7199 this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener)); 7200 } else { 7201 prevStats = newStats; 7202 } 7203 } catch (error) { 7204 // Fix issues where mtime is null but file is still present 7205 this.fsw._remove(dirname, basename); 7206 } 7207 // add is about to be emitted if file not already tracked in parent 7208 } else if (parent.has(basename)) { 7209 // Check that change event was not fired because of changed only accessTime. 7210 const at = newStats.atimeMs; 7211 const mt = newStats.mtimeMs; 7212 if (!at || at <= mt || mt !== prevStats.mtimeMs) { 7213 this.fsw._emit(EV_CHANGE, file, newStats); 7214 } 7215 prevStats = newStats; 7216 } 7217 }; 7218 // kick off the watcher 7219 const closer = this._watchWithNodeFs(file, listener); 7220 7221 // emit an add event if we're supposed to 7222 if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { 7223 if (!this.fsw._throttle(EV_ADD, file, 0)) return; 7224 this.fsw._emit(EV_ADD, file, stats); 7225 } 7226 7227 return closer; 7228 } 7229 7230 /** 7231 * Handle symlinks encountered while reading a dir. 7232 * @param {Object} entry returned by readdirp 7233 * @param {String} directory path of dir being read 7234 * @param {String} path of this item 7235 * @param {String} item basename of this item 7236 * @returns {Promise<Boolean>} true if no more processing is needed for this entry. 7237 */ 7238 async _handleSymlink(entry, directory, path, item) { 7239 if (this.fsw.closed) { 7240 return; 7241 } 7242 const full = entry.fullPath; 7243 const dir = this.fsw._getWatchedDir(directory); 7244 7245 if (!this.fsw.options.followSymlinks) { 7246 // watch symlink directly (don't follow) and detect changes 7247 this.fsw._incrReadyCount(); 7248 7249 let linkPath; 7250 try { 7251 linkPath = await fsrealpath(path); 7252 } catch (e) { 7253 this.fsw._emitReady(); 7254 return true; 7255 } 7256 7257 if (this.fsw.closed) return; 7258 if (dir.has(item)) { 7259 if (this.fsw._symlinkPaths.get(full) !== linkPath) { 7260 this.fsw._symlinkPaths.set(full, linkPath); 7261 this.fsw._emit(EV_CHANGE, path, entry.stats); 7262 } 7263 } else { 7264 dir.add(item); 7265 this.fsw._symlinkPaths.set(full, linkPath); 7266 this.fsw._emit(EV_ADD, path, entry.stats); 7267 } 7268 this.fsw._emitReady(); 7269 return true; 7270 } 7271 7272 // don't follow the same symlink more than once 7273 if (this.fsw._symlinkPaths.has(full)) { 7274 return true; 7275 } 7276 7277 this.fsw._symlinkPaths.set(full, true); 7278 } 7279 7280 _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { 7281 // Normalize the directory name on Windows 7282 directory = sysPath.join(directory, EMPTY_STR); 7283 7284 if (!wh.hasGlob) { 7285 throttler = this.fsw._throttle('readdir', directory, 1000); 7286 if (!throttler) return; 7287 } 7288 7289 const previous = this.fsw._getWatchedDir(wh.path); 7290 const current = new Set(); 7291 7292 let stream = this.fsw._readdirp(directory, { 7293 fileFilter: entry => wh.filterPath(entry), 7294 directoryFilter: entry => wh.filterDir(entry), 7295 depth: 0 7296 }).on(STR_DATA, async (entry) => { 7297 if (this.fsw.closed) { 7298 stream = undefined; 7299 return; 7300 } 7301 const item = entry.path; 7302 let path = sysPath.join(directory, item); 7303 current.add(item); 7304 7305 if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) { 7306 return; 7307 } 7308 7309 if (this.fsw.closed) { 7310 stream = undefined; 7311 return; 7312 } 7313 // Files that present in current directory snapshot 7314 // but absent in previous are added to watch list and 7315 // emit `add` event. 7316 if (item === target || !target && !previous.has(item)) { 7317 this.fsw._incrReadyCount(); 7318 7319 // ensure relativeness of path is preserved in case of watcher reuse 7320 path = sysPath.join(dir, sysPath.relative(dir, path)); 7321 7322 this._addToNodeFs(path, initialAdd, wh, depth + 1); 7323 } 7324 }).on(EV_ERROR, this._boundHandleError); 7325 7326 return new Promise(resolve => 7327 stream.once(STR_END, () => { 7328 if (this.fsw.closed) { 7329 stream = undefined; 7330 return; 7331 } 7332 const wasThrottled = throttler ? throttler.clear() : false; 7333 7334 resolve(); 7335 7336 // Files that absent in current directory snapshot 7337 // but present in previous emit `remove` event 7338 // and are removed from @watched[directory]. 7339 previous.getChildren().filter((item) => { 7340 return item !== directory && 7341 !current.has(item) && 7342 // in case of intersecting globs; 7343 // a path may have been filtered out of this readdir, but 7344 // shouldn't be removed because it matches a different glob 7345 (!wh.hasGlob || wh.filterPath({ 7346 fullPath: sysPath.resolve(directory, item) 7347 })); 7348 }).forEach((item) => { 7349 this.fsw._remove(directory, item); 7350 }); 7351 7352 stream = undefined; 7353 7354 // one more time for any missed in case changes came in extremely quickly 7355 if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler); 7356 }) 7357 ); 7358 } 7359 7360 /** 7361 * Read directory to add / remove files from `@watched` list and re-read it on change. 7362 * @param {String} dir fs path 7363 * @param {fs.Stats} stats 7364 * @param {Boolean} initialAdd 7365 * @param {Number} depth relative to user-supplied path 7366 * @param {String} target child path targeted for watch 7367 * @param {Object} wh Common watch helpers for this path 7368 * @param {String} realpath 7369 * @returns {Promise<Function>} closer for the watcher instance. 7370 */ 7371 async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) { 7372 const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir)); 7373 const tracked = parentDir.has(sysPath.basename(dir)); 7374 if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { 7375 if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR, dir, stats); 7376 } 7377 7378 // ensure dir is tracked (harmless if redundant) 7379 parentDir.add(sysPath.basename(dir)); 7380 this.fsw._getWatchedDir(dir); 7381 let throttler; 7382 let closer; 7383 7384 const oDepth = this.fsw.options.depth; 7385 if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) { 7386 if (!target) { 7387 await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); 7388 if (this.fsw.closed) return; 7389 } 7390 7391 closer = this._watchWithNodeFs(dir, (dirPath, stats) => { 7392 // if current directory is removed, do nothing 7393 if (stats && stats.mtimeMs === 0) return; 7394 7395 this._handleRead(dirPath, false, wh, target, dir, depth, throttler); 7396 }); 7397 } 7398 return closer; 7399 } 7400 7401 /** 7402 * Handle added file, directory, or glob pattern. 7403 * Delegates call to _handleFile / _handleDir after checks. 7404 * @param {String} path to file or ir 7405 * @param {Boolean} initialAdd was the file added at watch instantiation? 7406 * @param {Object} priorWh depth relative to user-supplied path 7407 * @param {Number} depth Child path actually targeted for watch 7408 * @param {String=} target Child path actually targeted for watch 7409 * @returns {Promise} 7410 */ 7411 async _addToNodeFs(path, initialAdd, priorWh, depth, target) { 7412 const ready = this.fsw._emitReady; 7413 if (this.fsw._isIgnored(path) || this.fsw.closed) { 7414 ready(); 7415 return false; 7416 } 7417 7418 const wh = this.fsw._getWatchHelpers(path, depth); 7419 if (!wh.hasGlob && priorWh) { 7420 wh.hasGlob = priorWh.hasGlob; 7421 wh.globFilter = priorWh.globFilter; 7422 wh.filterPath = entry => priorWh.filterPath(entry); 7423 wh.filterDir = entry => priorWh.filterDir(entry); 7424 } 7425 7426 // evaluate what is at the path we're being asked to watch 7427 try { 7428 const stats = await statMethods[wh.statMethod](wh.watchPath); 7429 if (this.fsw.closed) return; 7430 if (this.fsw._isIgnored(wh.watchPath, stats)) { 7431 ready(); 7432 return false; 7433 } 7434 7435 const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START); 7436 let closer; 7437 if (stats.isDirectory()) { 7438 const absPath = sysPath.resolve(path); 7439 const targetPath = follow ? await fsrealpath(path) : path; 7440 if (this.fsw.closed) return; 7441 closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); 7442 if (this.fsw.closed) return; 7443 // preserve this symlink's target path 7444 if (absPath !== targetPath && targetPath !== undefined) { 7445 this.fsw._symlinkPaths.set(absPath, targetPath); 7446 } 7447 } else if (stats.isSymbolicLink()) { 7448 const targetPath = follow ? await fsrealpath(path) : path; 7449 if (this.fsw.closed) return; 7450 const parent = sysPath.dirname(wh.watchPath); 7451 this.fsw._getWatchedDir(parent).add(wh.watchPath); 7452 this.fsw._emit(EV_ADD, wh.watchPath, stats); 7453 closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath); 7454 if (this.fsw.closed) return; 7455 7456 // preserve this symlink's target path 7457 if (targetPath !== undefined) { 7458 this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath); 7459 } 7460 } else { 7461 closer = this._handleFile(wh.watchPath, stats, initialAdd); 7462 } 7463 ready(); 7464 7465 this.fsw._addPathCloser(path, closer); 7466 return false; 7467 7468 } catch (error) { 7469 if (this.fsw._handleError(error)) { 7470 ready(); 7471 return path; 7472 } 7473 } 7474 } 7475 7476 } 7477 7478 nodefsHandler = NodeFsHandler; 7479 return nodefsHandler; 2734 7480 } 2735 7481 2736 /** 2737 * Watch file for changes with fs_watchFile or fs_watch. 2738 * @param {String} path to file or dir 2739 * @param {Function} listener on fs change 2740 * @returns {Function} closer for the watcher instance 2741 */ 2742 _watchWithNodeFs(path, listener) { 2743 const opts = this.fsw.options; 2744 const directory = sysPath$2.dirname(path); 2745 const basename = sysPath$2.basename(path); 2746 const parent = this.fsw._getWatchedDir(directory); 2747 parent.add(basename); 2748 const absolutePath = sysPath$2.resolve(path); 2749 const options = {persistent: opts.persistent}; 2750 if (!listener) listener = EMPTY_FN$2; 2751 2752 let closer; 2753 if (opts.usePolling) { 2754 options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ? 2755 opts.binaryInterval : opts.interval; 2756 closer = setFsWatchFileListener(path, absolutePath, options, { 2757 listener, 2758 rawEmitter: this.fsw._emitRaw 2759 }); 2760 } else { 2761 closer = setFsWatchListener(path, absolutePath, options, { 2762 listener, 2763 errHandler: this._boundHandleError, 2764 rawEmitter: this.fsw._emitRaw 2765 }); 2766 } 2767 return closer; 7482 var fseventsHandler = {exports: {}}; 7483 7484 const require$$3 = /*@__PURE__*/rollup.getAugmentedNamespace(fseventsImporter.fseventsImporter); 7485 7486 var hasRequiredFseventsHandler; 7487 7488 function requireFseventsHandler () { 7489 if (hasRequiredFseventsHandler) return fseventsHandler.exports; 7490 hasRequiredFseventsHandler = 1; 7491 7492 const fs = require$$0$2; 7493 const sysPath = require$$0$1; 7494 const { promisify } = require$$2; 7495 7496 let fsevents; 7497 try { 7498 fsevents = require$$3.getFsEvents(); 7499 } catch (error) { 7500 if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error); 7501 } 7502 7503 if (fsevents) { 7504 // TODO: real check 7505 const mtch = process.version.match(/v(\d+)\.(\d+)/); 7506 if (mtch && mtch[1] && mtch[2]) { 7507 const maj = Number.parseInt(mtch[1], 10); 7508 const min = Number.parseInt(mtch[2], 10); 7509 if (maj === 8 && min < 16) { 7510 fsevents = undefined; 7511 } 7512 } 7513 } 7514 7515 const { 7516 EV_ADD, 7517 EV_CHANGE, 7518 EV_ADD_DIR, 7519 EV_UNLINK, 7520 EV_ERROR, 7521 STR_DATA, 7522 STR_END, 7523 FSEVENT_CREATED, 7524 FSEVENT_MODIFIED, 7525 FSEVENT_DELETED, 7526 FSEVENT_MOVED, 7527 // FSEVENT_CLONED, 7528 FSEVENT_UNKNOWN, 7529 FSEVENT_FLAG_MUST_SCAN_SUBDIRS, 7530 FSEVENT_TYPE_FILE, 7531 FSEVENT_TYPE_DIRECTORY, 7532 FSEVENT_TYPE_SYMLINK, 7533 7534 ROOT_GLOBSTAR, 7535 DIR_SUFFIX, 7536 DOT_SLASH, 7537 FUNCTION_TYPE, 7538 EMPTY_FN, 7539 IDENTITY_FN 7540 } = /*@__PURE__*/ requireConstants(); 7541 7542 const Depth = (value) => isNaN(value) ? {} : {depth: value}; 7543 7544 const stat = promisify(fs.stat); 7545 const lstat = promisify(fs.lstat); 7546 const realpath = promisify(fs.realpath); 7547 7548 const statMethods = { stat, lstat }; 7549 7550 /** 7551 * @typedef {String} Path 7552 */ 7553 7554 /** 7555 * @typedef {Object} FsEventsWatchContainer 7556 * @property {Set<Function>} listeners 7557 * @property {Function} rawEmitter 7558 * @property {{stop: Function}} watcher 7559 */ 7560 7561 // fsevents instance helper functions 7562 /** 7563 * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances) 7564 * @type {Map<Path,FsEventsWatchContainer>} 7565 */ 7566 const FSEventsWatchers = new Map(); 7567 7568 // Threshold of duplicate path prefixes at which to start 7569 // consolidating going forward 7570 const consolidateThreshhold = 10; 7571 7572 const wrongEventFlags = new Set([ 7573 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912 7574 ]); 7575 7576 /** 7577 * Instantiates the fsevents interface 7578 * @param {Path} path path to be watched 7579 * @param {Function} callback called when fsevents is bound and ready 7580 * @returns {{stop: Function}} new fsevents instance 7581 */ 7582 const createFSEventsInstance = (path, callback) => { 7583 const stop = fsevents.watch(path, callback); 7584 return {stop}; 7585 }; 7586 7587 /** 7588 * Instantiates the fsevents interface or binds listeners to an existing one covering 7589 * the same file tree. 7590 * @param {Path} path - to be watched 7591 * @param {Path} realPath - real path for symlinks 7592 * @param {Function} listener - called when fsevents emits events 7593 * @param {Function} rawEmitter - passes data to listeners of the 'raw' event 7594 * @returns {Function} closer 7595 */ 7596 function setFSEventsListener(path, realPath, listener, rawEmitter) { 7597 let watchPath = sysPath.extname(realPath) ? sysPath.dirname(realPath) : realPath; 7598 7599 const parentPath = sysPath.dirname(watchPath); 7600 let cont = FSEventsWatchers.get(watchPath); 7601 7602 // If we've accumulated a substantial number of paths that 7603 // could have been consolidated by watching one directory 7604 // above the current one, create a watcher on the parent 7605 // path instead, so that we do consolidate going forward. 7606 if (couldConsolidate(parentPath)) { 7607 watchPath = parentPath; 7608 } 7609 7610 const resolvedPath = sysPath.resolve(path); 7611 const hasSymlink = resolvedPath !== realPath; 7612 7613 const filteredListener = (fullPath, flags, info) => { 7614 if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath); 7615 if ( 7616 fullPath === resolvedPath || 7617 !fullPath.indexOf(resolvedPath + sysPath.sep) 7618 ) listener(fullPath, flags, info); 7619 }; 7620 7621 // check if there is already a watcher on a parent path 7622 // modifies `watchPath` to the parent path when it finds a match 7623 let watchedParent = false; 7624 for (const watchedPath of FSEventsWatchers.keys()) { 7625 if (realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep) === 0) { 7626 watchPath = watchedPath; 7627 cont = FSEventsWatchers.get(watchPath); 7628 watchedParent = true; 7629 break; 7630 } 7631 } 7632 7633 if (cont || watchedParent) { 7634 cont.listeners.add(filteredListener); 7635 } else { 7636 cont = { 7637 listeners: new Set([filteredListener]), 7638 rawEmitter, 7639 watcher: createFSEventsInstance(watchPath, (fullPath, flags) => { 7640 if (!cont.listeners.size) return; 7641 if (flags & FSEVENT_FLAG_MUST_SCAN_SUBDIRS) return; 7642 const info = fsevents.getInfo(fullPath, flags); 7643 cont.listeners.forEach(list => { 7644 list(fullPath, flags, info); 7645 }); 7646 7647 cont.rawEmitter(info.event, fullPath, info); 7648 }) 7649 }; 7650 FSEventsWatchers.set(watchPath, cont); 7651 } 7652 7653 // removes this instance's listeners and closes the underlying fsevents 7654 // instance if there are no more listeners left 7655 return () => { 7656 const lst = cont.listeners; 7657 7658 lst.delete(filteredListener); 7659 if (!lst.size) { 7660 FSEventsWatchers.delete(watchPath); 7661 if (cont.watcher) return cont.watcher.stop().then(() => { 7662 cont.rawEmitter = cont.watcher = undefined; 7663 Object.freeze(cont); 7664 }); 7665 } 7666 }; 7667 } 7668 7669 // Decide whether or not we should start a new higher-level 7670 // parent watcher 7671 const couldConsolidate = (path) => { 7672 let count = 0; 7673 for (const watchPath of FSEventsWatchers.keys()) { 7674 if (watchPath.indexOf(path) === 0) { 7675 count++; 7676 if (count >= consolidateThreshhold) { 7677 return true; 7678 } 7679 } 7680 } 7681 7682 return false; 7683 }; 7684 7685 // returns boolean indicating whether fsevents can be used 7686 const canUse = () => fsevents && FSEventsWatchers.size < 128; 7687 7688 // determines subdirectory traversal levels from root to path 7689 const calcDepth = (path, root) => { 7690 let i = 0; 7691 while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++; 7692 return i; 7693 }; 7694 7695 // returns boolean indicating whether the fsevents' event info has the same type 7696 // as the one returned by fs.stat 7697 const sameTypes = (info, stats) => ( 7698 info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() || 7699 info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() || 7700 info.type === FSEVENT_TYPE_FILE && stats.isFile() 7701 ); 7702 7703 /** 7704 * @mixin 7705 */ 7706 class FsEventsHandler { 7707 7708 /** 7709 * @param {import('../index').FSWatcher} fsw 7710 */ 7711 constructor(fsw) { 7712 this.fsw = fsw; 7713 } 7714 checkIgnored(path, stats) { 7715 const ipaths = this.fsw._ignoredPaths; 7716 if (this.fsw._isIgnored(path, stats)) { 7717 ipaths.add(path); 7718 if (stats && stats.isDirectory()) { 7719 ipaths.add(path + ROOT_GLOBSTAR); 7720 } 7721 return true; 7722 } 7723 7724 ipaths.delete(path); 7725 ipaths.delete(path + ROOT_GLOBSTAR); 7726 } 7727 7728 addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) { 7729 const event = watchedDir.has(item) ? EV_CHANGE : EV_ADD; 7730 this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts); 7731 } 7732 7733 async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) { 7734 try { 7735 const stats = await stat(path); 7736 if (this.fsw.closed) return; 7737 if (sameTypes(info, stats)) { 7738 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7739 } else { 7740 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts); 7741 } 7742 } catch (error) { 7743 if (error.code === 'EACCES') { 7744 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7745 } else { 7746 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts); 7747 } 7748 } 7749 } 7750 7751 handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) { 7752 if (this.fsw.closed || this.checkIgnored(path)) return; 7753 7754 if (event === EV_UNLINK) { 7755 const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY; 7756 // suppress unlink events on never before seen files 7757 if (isDirectory || watchedDir.has(item)) { 7758 this.fsw._remove(parent, item, isDirectory); 7759 } 7760 } else { 7761 if (event === EV_ADD) { 7762 // track new directories 7763 if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path); 7764 7765 if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) { 7766 // push symlinks back to the top of the stack to get handled 7767 const curDepth = opts.depth === undefined ? 7768 undefined : calcDepth(fullPath, realPath) + 1; 7769 return this._addToFsEvents(path, false, true, curDepth); 7770 } 7771 7772 // track new paths 7773 // (other than symlinks being followed, which will be tracked soon) 7774 this.fsw._getWatchedDir(parent).add(item); 7775 } 7776 /** 7777 * @type {'add'|'addDir'|'unlink'|'unlinkDir'} 7778 */ 7779 const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event; 7780 this.fsw._emit(eventName, path); 7781 if (eventName === EV_ADD_DIR) this._addToFsEvents(path, false, true); 7782 } 7783 } 7784 7785 /** 7786 * Handle symlinks encountered during directory scan 7787 * @param {String} watchPath - file/dir path to be watched with fsevents 7788 * @param {String} realPath - real path (in case of symlinks) 7789 * @param {Function} transform - path transformer 7790 * @param {Function} globFilter - path filter in case a glob pattern was provided 7791 * @returns {Function} closer for the watcher instance 7792 */ 7793 _watchWithFsEvents(watchPath, realPath, transform, globFilter) { 7794 if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return; 7795 const opts = this.fsw.options; 7796 const watchCallback = async (fullPath, flags, info) => { 7797 if (this.fsw.closed) return; 7798 if ( 7799 opts.depth !== undefined && 7800 calcDepth(fullPath, realPath) > opts.depth 7801 ) return; 7802 const path = transform(sysPath.join( 7803 watchPath, sysPath.relative(watchPath, fullPath) 7804 )); 7805 if (globFilter && !globFilter(path)) return; 7806 // ensure directories are tracked 7807 const parent = sysPath.dirname(path); 7808 const item = sysPath.basename(path); 7809 const watchedDir = this.fsw._getWatchedDir( 7810 info.type === FSEVENT_TYPE_DIRECTORY ? path : parent 7811 ); 7812 7813 // correct for wrong events emitted 7814 if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) { 7815 if (typeof opts.ignored === FUNCTION_TYPE) { 7816 let stats; 7817 try { 7818 stats = await stat(path); 7819 } catch (error) {} 7820 if (this.fsw.closed) return; 7821 if (this.checkIgnored(path, stats)) return; 7822 if (sameTypes(info, stats)) { 7823 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7824 } else { 7825 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts); 7826 } 7827 } else { 7828 this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7829 } 7830 } else { 7831 switch (info.event) { 7832 case FSEVENT_CREATED: 7833 case FSEVENT_MODIFIED: 7834 return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7835 case FSEVENT_DELETED: 7836 case FSEVENT_MOVED: 7837 return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7838 } 7839 } 7840 }; 7841 7842 const closer = setFSEventsListener( 7843 watchPath, 7844 realPath, 7845 watchCallback, 7846 this.fsw._emitRaw 7847 ); 7848 7849 this.fsw._emitReady(); 7850 return closer; 7851 } 7852 7853 /** 7854 * Handle symlinks encountered during directory scan 7855 * @param {String} linkPath path to symlink 7856 * @param {String} fullPath absolute path to the symlink 7857 * @param {Function} transform pre-existing path transformer 7858 * @param {Number} curDepth level of subdirectories traversed to where symlink is 7859 * @returns {Promise<void>} 7860 */ 7861 async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) { 7862 // don't follow the same symlink more than once 7863 if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return; 7864 7865 this.fsw._symlinkPaths.set(fullPath, true); 7866 this.fsw._incrReadyCount(); 7867 7868 try { 7869 const linkTarget = await realpath(linkPath); 7870 if (this.fsw.closed) return; 7871 if (this.fsw._isIgnored(linkTarget)) { 7872 return this.fsw._emitReady(); 7873 } 7874 7875 this.fsw._incrReadyCount(); 7876 7877 // add the linkTarget for watching with a wrapper for transform 7878 // that causes emitted paths to incorporate the link's path 7879 this._addToFsEvents(linkTarget || linkPath, (path) => { 7880 let aliasedPath = linkPath; 7881 if (linkTarget && linkTarget !== DOT_SLASH) { 7882 aliasedPath = path.replace(linkTarget, linkPath); 7883 } else if (path !== DOT_SLASH) { 7884 aliasedPath = sysPath.join(linkPath, path); 7885 } 7886 return transform(aliasedPath); 7887 }, false, curDepth); 7888 } catch(error) { 7889 if (this.fsw._handleError(error)) { 7890 return this.fsw._emitReady(); 7891 } 7892 } 7893 } 7894 7895 /** 7896 * 7897 * @param {Path} newPath 7898 * @param {fs.Stats} stats 7899 */ 7900 emitAdd(newPath, stats, processPath, opts, forceAdd) { 7901 const pp = processPath(newPath); 7902 const isDir = stats.isDirectory(); 7903 const dirObj = this.fsw._getWatchedDir(sysPath.dirname(pp)); 7904 const base = sysPath.basename(pp); 7905 7906 // ensure empty dirs get tracked 7907 if (isDir) this.fsw._getWatchedDir(pp); 7908 if (dirObj.has(base)) return; 7909 dirObj.add(base); 7910 7911 if (!opts.ignoreInitial || forceAdd === true) { 7912 this.fsw._emit(isDir ? EV_ADD_DIR : EV_ADD, pp, stats); 7913 } 7914 } 7915 7916 initWatch(realPath, path, wh, processPath) { 7917 if (this.fsw.closed) return; 7918 const closer = this._watchWithFsEvents( 7919 wh.watchPath, 7920 sysPath.resolve(realPath || wh.watchPath), 7921 processPath, 7922 wh.globFilter 7923 ); 7924 this.fsw._addPathCloser(path, closer); 7925 } 7926 7927 /** 7928 * Handle added path with fsevents 7929 * @param {String} path file/dir path or glob pattern 7930 * @param {Function|Boolean=} transform converts working path to what the user expects 7931 * @param {Boolean=} forceAdd ensure add is emitted 7932 * @param {Number=} priorDepth Level of subdirectories already traversed. 7933 * @returns {Promise<void>} 7934 */ 7935 async _addToFsEvents(path, transform, forceAdd, priorDepth) { 7936 if (this.fsw.closed) { 7937 return; 7938 } 7939 const opts = this.fsw.options; 7940 const processPath = typeof transform === FUNCTION_TYPE ? transform : IDENTITY_FN; 7941 7942 const wh = this.fsw._getWatchHelpers(path); 7943 7944 // evaluate what is at the path we're being asked to watch 7945 try { 7946 const stats = await statMethods[wh.statMethod](wh.watchPath); 7947 if (this.fsw.closed) return; 7948 if (this.fsw._isIgnored(wh.watchPath, stats)) { 7949 throw null; 7950 } 7951 if (stats.isDirectory()) { 7952 // emit addDir unless this is a glob parent 7953 if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd); 7954 7955 // don't recurse further if it would exceed depth setting 7956 if (priorDepth && priorDepth > opts.depth) return; 7957 7958 // scan the contents of the dir 7959 this.fsw._readdirp(wh.watchPath, { 7960 fileFilter: entry => wh.filterPath(entry), 7961 directoryFilter: entry => wh.filterDir(entry), 7962 ...Depth(opts.depth - (priorDepth || 0)) 7963 }).on(STR_DATA, (entry) => { 7964 // need to check filterPath on dirs b/c filterDir is less restrictive 7965 if (this.fsw.closed) { 7966 return; 7967 } 7968 if (entry.stats.isDirectory() && !wh.filterPath(entry)) return; 7969 7970 const joinedPath = sysPath.join(wh.watchPath, entry.path); 7971 const {fullPath} = entry; 7972 7973 if (wh.followSymlinks && entry.stats.isSymbolicLink()) { 7974 // preserve the current depth here since it can't be derived from 7975 // real paths past the symlink 7976 const curDepth = opts.depth === undefined ? 7977 undefined : calcDepth(joinedPath, sysPath.resolve(wh.watchPath)) + 1; 7978 7979 this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth); 7980 } else { 7981 this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd); 7982 } 7983 }).on(EV_ERROR, EMPTY_FN).on(STR_END, () => { 7984 this.fsw._emitReady(); 7985 }); 7986 } else { 7987 this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd); 7988 this.fsw._emitReady(); 7989 } 7990 } catch (error) { 7991 if (!error || this.fsw._handleError(error)) { 7992 // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__- 7993 this.fsw._emitReady(); 7994 this.fsw._emitReady(); 7995 } 7996 } 7997 7998 if (opts.persistent && forceAdd !== true) { 7999 if (typeof transform === FUNCTION_TYPE) { 8000 // realpath has already been resolved 8001 this.initWatch(undefined, path, wh, processPath); 8002 } else { 8003 let realPath; 8004 try { 8005 realPath = await realpath(wh.watchPath); 8006 } catch (e) {} 8007 this.initWatch(realPath, path, wh, processPath); 8008 } 8009 } 8010 } 8011 8012 } 8013 8014 fseventsHandler.exports = FsEventsHandler; 8015 fseventsHandler.exports.canUse = canUse; 8016 return fseventsHandler.exports; 2768 8017 } 2769 8018 2770 /** 2771 * Watch a file and emit add event if warranted. 2772 * @param {Path} file Path 2773 * @param {fs.Stats} stats result of fs_stat 2774 * @param {Boolean} initialAdd was the file added at watch instantiation? 2775 * @returns {Function} closer for the watcher instance 2776 */ 2777 _handleFile(file, stats, initialAdd) { 2778 if (this.fsw.closed) { 2779 return; 2780 } 2781 const dirname = sysPath$2.dirname(file); 2782 const basename = sysPath$2.basename(file); 2783 const parent = this.fsw._getWatchedDir(dirname); 2784 // stats is always present 2785 let prevStats = stats; 2786 2787 // if the file is already being watched, do nothing 2788 if (parent.has(basename)) return; 2789 2790 const listener = async (path, newStats) => { 2791 if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return; 2792 if (!newStats || newStats.mtimeMs === 0) { 2793 try { 2794 const newStats = await stat$2(file); 2795 if (this.fsw.closed) return; 2796 // Check that change event was not fired because of changed only accessTime. 2797 const at = newStats.atimeMs; 2798 const mt = newStats.mtimeMs; 2799 if (!at || at <= mt || mt !== prevStats.mtimeMs) { 2800 this.fsw._emit(EV_CHANGE$2, file, newStats); 2801 } 2802 if (isLinux && prevStats.ino !== newStats.ino) { 2803 this.fsw._closeFile(path); 2804 prevStats = newStats; 2805 this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener)); 2806 } else { 2807 prevStats = newStats; 2808 } 2809 } catch (error) { 2810 // Fix issues where mtime is null but file is still present 2811 this.fsw._remove(dirname, basename); 2812 } 2813 // add is about to be emitted if file not already tracked in parent 2814 } else if (parent.has(basename)) { 2815 // Check that change event was not fired because of changed only accessTime. 2816 const at = newStats.atimeMs; 2817 const mt = newStats.mtimeMs; 2818 if (!at || at <= mt || mt !== prevStats.mtimeMs) { 2819 this.fsw._emit(EV_CHANGE$2, file, newStats); 2820 } 2821 prevStats = newStats; 2822 } 2823 }; 2824 // kick off the watcher 2825 const closer = this._watchWithNodeFs(file, listener); 2826 2827 // emit an add event if we're supposed to 2828 if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { 2829 if (!this.fsw._throttle(EV_ADD$2, file, 0)) return; 2830 this.fsw._emit(EV_ADD$2, file, stats); 2831 } 2832 2833 return closer; 8019 var hasRequiredChokidar; 8020 8021 function requireChokidar () { 8022 if (hasRequiredChokidar) return chokidar$1; 8023 hasRequiredChokidar = 1; 8024 8025 const { EventEmitter } = require$$0$3; 8026 const fs = require$$0$2; 8027 const sysPath = require$$0$1; 8028 const { promisify } = require$$2; 8029 const readdirp = /*@__PURE__*/ requireReaddirp(); 8030 const anymatch = /*@__PURE__*/ requireAnymatch().default; 8031 const globParent = /*@__PURE__*/ requireGlobParent(); 8032 const isGlob = /*@__PURE__*/ requireIsGlob(); 8033 const braces = /*@__PURE__*/ requireBraces(); 8034 const normalizePath = /*@__PURE__*/ requireNormalizePath(); 8035 8036 const NodeFsHandler = /*@__PURE__*/ requireNodefsHandler(); 8037 const FsEventsHandler = /*@__PURE__*/ requireFseventsHandler(); 8038 const { 8039 EV_ALL, 8040 EV_READY, 8041 EV_ADD, 8042 EV_CHANGE, 8043 EV_UNLINK, 8044 EV_ADD_DIR, 8045 EV_UNLINK_DIR, 8046 EV_RAW, 8047 EV_ERROR, 8048 8049 STR_CLOSE, 8050 STR_END, 8051 8052 BACK_SLASH_RE, 8053 DOUBLE_SLASH_RE, 8054 SLASH_OR_BACK_SLASH_RE, 8055 DOT_RE, 8056 REPLACER_RE, 8057 8058 SLASH, 8059 SLASH_SLASH, 8060 BRACE_START, 8061 BANG, 8062 ONE_DOT, 8063 TWO_DOTS, 8064 GLOBSTAR, 8065 SLASH_GLOBSTAR, 8066 ANYMATCH_OPTS, 8067 STRING_TYPE, 8068 FUNCTION_TYPE, 8069 EMPTY_STR, 8070 EMPTY_FN, 8071 8072 isWindows, 8073 isMacos, 8074 isIBMi 8075 } = /*@__PURE__*/ requireConstants(); 8076 8077 const stat = promisify(fs.stat); 8078 const readdir = promisify(fs.readdir); 8079 8080 /** 8081 * @typedef {String} Path 8082 * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName 8083 * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType 8084 */ 8085 8086 /** 8087 * 8088 * @typedef {Object} WatchHelpers 8089 * @property {Boolean} followSymlinks 8090 * @property {'stat'|'lstat'} statMethod 8091 * @property {Path} path 8092 * @property {Path} watchPath 8093 * @property {Function} entryPath 8094 * @property {Boolean} hasGlob 8095 * @property {Object} globFilter 8096 * @property {Function} filterPath 8097 * @property {Function} filterDir 8098 */ 8099 8100 const arrify = (value = []) => Array.isArray(value) ? value : [value]; 8101 const flatten = (list, result = []) => { 8102 list.forEach(item => { 8103 if (Array.isArray(item)) { 8104 flatten(item, result); 8105 } else { 8106 result.push(item); 8107 } 8108 }); 8109 return result; 8110 }; 8111 8112 const unifyPaths = (paths_) => { 8113 /** 8114 * @type {Array<String>} 8115 */ 8116 const paths = flatten(arrify(paths_)); 8117 if (!paths.every(p => typeof p === STRING_TYPE)) { 8118 throw new TypeError(`Non-string provided as watch path: ${paths}`); 8119 } 8120 return paths.map(normalizePathToUnix); 8121 }; 8122 8123 // If SLASH_SLASH occurs at the beginning of path, it is not replaced 8124 // because "//StoragePC/DrivePool/Movies" is a valid network path 8125 const toUnix = (string) => { 8126 let str = string.replace(BACK_SLASH_RE, SLASH); 8127 let prepend = false; 8128 if (str.startsWith(SLASH_SLASH)) { 8129 prepend = true; 8130 } 8131 while (str.match(DOUBLE_SLASH_RE)) { 8132 str = str.replace(DOUBLE_SLASH_RE, SLASH); 8133 } 8134 if (prepend) { 8135 str = SLASH + str; 8136 } 8137 return str; 8138 }; 8139 8140 // Our version of upath.normalize 8141 // TODO: this is not equal to path-normalize module - investigate why 8142 const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path))); 8143 8144 const normalizeIgnored = (cwd = EMPTY_STR) => (path) => { 8145 if (typeof path !== STRING_TYPE) return path; 8146 return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path)); 8147 }; 8148 8149 const getAbsolutePath = (path, cwd) => { 8150 if (sysPath.isAbsolute(path)) { 8151 return path; 8152 } 8153 if (path.startsWith(BANG)) { 8154 return BANG + sysPath.join(cwd, path.slice(1)); 8155 } 8156 return sysPath.join(cwd, path); 8157 }; 8158 8159 const undef = (opts, key) => opts[key] === undefined; 8160 8161 /** 8162 * Directory entry. 8163 * @property {Path} path 8164 * @property {Set<Path>} items 8165 */ 8166 class DirEntry { 8167 /** 8168 * @param {Path} dir 8169 * @param {Function} removeWatcher 8170 */ 8171 constructor(dir, removeWatcher) { 8172 this.path = dir; 8173 this._removeWatcher = removeWatcher; 8174 /** @type {Set<Path>} */ 8175 this.items = new Set(); 8176 } 8177 8178 add(item) { 8179 const {items} = this; 8180 if (!items) return; 8181 if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item); 8182 } 8183 8184 async remove(item) { 8185 const {items} = this; 8186 if (!items) return; 8187 items.delete(item); 8188 if (items.size > 0) return; 8189 8190 const dir = this.path; 8191 try { 8192 await readdir(dir); 8193 } catch (err) { 8194 if (this._removeWatcher) { 8195 this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir)); 8196 } 8197 } 8198 } 8199 8200 has(item) { 8201 const {items} = this; 8202 if (!items) return; 8203 return items.has(item); 8204 } 8205 8206 /** 8207 * @returns {Array<String>} 8208 */ 8209 getChildren() { 8210 const {items} = this; 8211 if (!items) return; 8212 return [...items.values()]; 8213 } 8214 8215 dispose() { 8216 this.items.clear(); 8217 delete this.path; 8218 delete this._removeWatcher; 8219 delete this.items; 8220 Object.freeze(this); 8221 } 8222 } 8223 8224 const STAT_METHOD_F = 'stat'; 8225 const STAT_METHOD_L = 'lstat'; 8226 class WatchHelper { 8227 constructor(path, watchPath, follow, fsw) { 8228 this.fsw = fsw; 8229 this.path = path = path.replace(REPLACER_RE, EMPTY_STR); 8230 this.watchPath = watchPath; 8231 this.fullWatchPath = sysPath.resolve(watchPath); 8232 this.hasGlob = watchPath !== path; 8233 /** @type {object|boolean} */ 8234 if (path === EMPTY_STR) this.hasGlob = false; 8235 this.globSymlink = this.hasGlob && follow ? undefined : false; 8236 this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false; 8237 this.dirParts = this.getDirParts(path); 8238 this.dirParts.forEach((parts) => { 8239 if (parts.length > 1) parts.pop(); 8240 }); 8241 this.followSymlinks = follow; 8242 this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; 8243 } 8244 8245 checkGlobSymlink(entry) { 8246 // only need to resolve once 8247 // first entry should always have entry.parentDir === EMPTY_STR 8248 if (this.globSymlink === undefined) { 8249 this.globSymlink = entry.fullParentDir === this.fullWatchPath ? 8250 false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath}; 8251 } 8252 8253 if (this.globSymlink) { 8254 return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath); 8255 } 8256 8257 return entry.fullPath; 8258 } 8259 8260 entryPath(entry) { 8261 return sysPath.join(this.watchPath, 8262 sysPath.relative(this.watchPath, this.checkGlobSymlink(entry)) 8263 ); 8264 } 8265 8266 filterPath(entry) { 8267 const {stats} = entry; 8268 if (stats && stats.isSymbolicLink()) return this.filterDir(entry); 8269 const resolvedPath = this.entryPath(entry); 8270 const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ? 8271 this.globFilter(resolvedPath) : true; 8272 return matchesGlob && 8273 this.fsw._isntIgnored(resolvedPath, stats) && 8274 this.fsw._hasReadPermissions(stats); 8275 } 8276 8277 getDirParts(path) { 8278 if (!this.hasGlob) return []; 8279 const parts = []; 8280 const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path]; 8281 expandedPath.forEach((path) => { 8282 parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE)); 8283 }); 8284 return parts; 8285 } 8286 8287 filterDir(entry) { 8288 if (this.hasGlob) { 8289 const entryParts = this.getDirParts(this.checkGlobSymlink(entry)); 8290 let globstar = false; 8291 this.unmatchedGlob = !this.dirParts.some((parts) => { 8292 return parts.every((part, i) => { 8293 if (part === GLOBSTAR) globstar = true; 8294 return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS); 8295 }); 8296 }); 8297 } 8298 return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats); 8299 } 8300 } 8301 8302 /** 8303 * Watches files & directories for changes. Emitted events: 8304 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` 8305 * 8306 * new FSWatcher() 8307 * .add(directories) 8308 * .on('add', path => log('File', path, 'was added')) 8309 */ 8310 class FSWatcher extends EventEmitter { 8311 // Not indenting methods for history sake; for now. 8312 constructor(_opts) { 8313 super(); 8314 8315 const opts = {}; 8316 if (_opts) Object.assign(opts, _opts); // for frozen objects 8317 8318 /** @type {Map<String, DirEntry>} */ 8319 this._watched = new Map(); 8320 /** @type {Map<String, Array>} */ 8321 this._closers = new Map(); 8322 /** @type {Set<String>} */ 8323 this._ignoredPaths = new Set(); 8324 8325 /** @type {Map<ThrottleType, Map>} */ 8326 this._throttled = new Map(); 8327 8328 /** @type {Map<Path, String|Boolean>} */ 8329 this._symlinkPaths = new Map(); 8330 8331 this._streams = new Set(); 8332 this.closed = false; 8333 8334 // Set up default options. 8335 if (undef(opts, 'persistent')) opts.persistent = true; 8336 if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false; 8337 if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false; 8338 if (undef(opts, 'interval')) opts.interval = 100; 8339 if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300; 8340 if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false; 8341 opts.enableBinaryInterval = opts.binaryInterval !== opts.interval; 8342 8343 // Enable fsevents on OS X when polling isn't explicitly enabled. 8344 if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling; 8345 8346 // If we can't use fsevents, ensure the options reflect it's disabled. 8347 const canUseFsEvents = FsEventsHandler.canUse(); 8348 if (!canUseFsEvents) opts.useFsEvents = false; 8349 8350 // Use polling on Mac if not using fsevents. 8351 // Other platforms use non-polling fs_watch. 8352 if (undef(opts, 'usePolling') && !opts.useFsEvents) { 8353 opts.usePolling = isMacos; 8354 } 8355 8356 // Always default to polling on IBM i because fs.watch() is not available on IBM i. 8357 if(isIBMi) { 8358 opts.usePolling = true; 8359 } 8360 8361 // Global override (useful for end-developers that need to force polling for all 8362 // instances of chokidar, regardless of usage/dependency depth) 8363 const envPoll = process.env.CHOKIDAR_USEPOLLING; 8364 if (envPoll !== undefined) { 8365 const envLower = envPoll.toLowerCase(); 8366 8367 if (envLower === 'false' || envLower === '0') { 8368 opts.usePolling = false; 8369 } else if (envLower === 'true' || envLower === '1') { 8370 opts.usePolling = true; 8371 } else { 8372 opts.usePolling = !!envLower; 8373 } 8374 } 8375 const envInterval = process.env.CHOKIDAR_INTERVAL; 8376 if (envInterval) { 8377 opts.interval = Number.parseInt(envInterval, 10); 8378 } 8379 8380 // Editor atomic write normalization enabled by default with fs.watch 8381 if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents; 8382 if (opts.atomic) this._pendingUnlinks = new Map(); 8383 8384 if (undef(opts, 'followSymlinks')) opts.followSymlinks = true; 8385 8386 if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false; 8387 if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {}; 8388 const awf = opts.awaitWriteFinish; 8389 if (awf) { 8390 if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000; 8391 if (!awf.pollInterval) awf.pollInterval = 100; 8392 this._pendingWrites = new Map(); 8393 } 8394 if (opts.ignored) opts.ignored = arrify(opts.ignored); 8395 8396 let readyCalls = 0; 8397 this._emitReady = () => { 8398 readyCalls++; 8399 if (readyCalls >= this._readyCount) { 8400 this._emitReady = EMPTY_FN; 8401 this._readyEmitted = true; 8402 // use process.nextTick to allow time for listener to be bound 8403 process.nextTick(() => this.emit(EV_READY)); 8404 } 8405 }; 8406 this._emitRaw = (...args) => this.emit(EV_RAW, ...args); 8407 this._readyEmitted = false; 8408 this.options = opts; 8409 8410 // Initialize with proper watcher. 8411 if (opts.useFsEvents) { 8412 this._fsEventsHandler = new FsEventsHandler(this); 8413 } else { 8414 this._nodeFsHandler = new NodeFsHandler(this); 8415 } 8416 8417 // You’re frozen when your heart’s not open. 8418 Object.freeze(opts); 8419 } 8420 8421 // Public methods 8422 8423 /** 8424 * Adds paths to be watched on an existing FSWatcher instance 8425 * @param {Path|Array<Path>} paths_ 8426 * @param {String=} _origAdd private; for handling non-existent paths to be watched 8427 * @param {Boolean=} _internal private; indicates a non-user add 8428 * @returns {FSWatcher} for chaining 8429 */ 8430 add(paths_, _origAdd, _internal) { 8431 const {cwd, disableGlobbing} = this.options; 8432 this.closed = false; 8433 let paths = unifyPaths(paths_); 8434 if (cwd) { 8435 paths = paths.map((path) => { 8436 const absPath = getAbsolutePath(path, cwd); 8437 8438 // Check `path` instead of `absPath` because the cwd portion can't be a glob 8439 if (disableGlobbing || !isGlob(path)) { 8440 return absPath; 8441 } 8442 return normalizePath(absPath); 8443 }); 8444 } 8445 8446 // set aside negated glob strings 8447 paths = paths.filter((path) => { 8448 if (path.startsWith(BANG)) { 8449 this._ignoredPaths.add(path.slice(1)); 8450 return false; 8451 } 8452 8453 // if a path is being added that was previously ignored, stop ignoring it 8454 this._ignoredPaths.delete(path); 8455 this._ignoredPaths.delete(path + SLASH_GLOBSTAR); 8456 8457 // reset the cached userIgnored anymatch fn 8458 // to make ignoredPaths changes effective 8459 this._userIgnored = undefined; 8460 8461 return true; 8462 }); 8463 8464 if (this.options.useFsEvents && this._fsEventsHandler) { 8465 if (!this._readyCount) this._readyCount = paths.length; 8466 if (this.options.persistent) this._readyCount += paths.length; 8467 paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path)); 8468 } else { 8469 if (!this._readyCount) this._readyCount = 0; 8470 this._readyCount += paths.length; 8471 Promise.all( 8472 paths.map(async path => { 8473 const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd); 8474 if (res) this._emitReady(); 8475 return res; 8476 }) 8477 ).then(results => { 8478 if (this.closed) return; 8479 results.filter(item => item).forEach(item => { 8480 this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item)); 8481 }); 8482 }); 8483 } 8484 8485 return this; 8486 } 8487 8488 /** 8489 * Close watchers or start ignoring events from specified paths. 8490 * @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs 8491 * @returns {FSWatcher} for chaining 8492 */ 8493 unwatch(paths_) { 8494 if (this.closed) return this; 8495 const paths = unifyPaths(paths_); 8496 const {cwd} = this.options; 8497 8498 paths.forEach((path) => { 8499 // convert to absolute path unless relative path already matches 8500 if (!sysPath.isAbsolute(path) && !this._closers.has(path)) { 8501 if (cwd) path = sysPath.join(cwd, path); 8502 path = sysPath.resolve(path); 8503 } 8504 8505 this._closePath(path); 8506 8507 this._ignoredPaths.add(path); 8508 if (this._watched.has(path)) { 8509 this._ignoredPaths.add(path + SLASH_GLOBSTAR); 8510 } 8511 8512 // reset the cached userIgnored anymatch fn 8513 // to make ignoredPaths changes effective 8514 this._userIgnored = undefined; 8515 }); 8516 8517 return this; 8518 } 8519 8520 /** 8521 * Close watchers and remove all listeners from watched paths. 8522 * @returns {Promise<void>}. 8523 */ 8524 close() { 8525 if (this.closed) return this._closePromise; 8526 this.closed = true; 8527 8528 // Memory management. 8529 this.removeAllListeners(); 8530 const closers = []; 8531 this._closers.forEach(closerList => closerList.forEach(closer => { 8532 const promise = closer(); 8533 if (promise instanceof Promise) closers.push(promise); 8534 })); 8535 this._streams.forEach(stream => stream.destroy()); 8536 this._userIgnored = undefined; 8537 this._readyCount = 0; 8538 this._readyEmitted = false; 8539 this._watched.forEach(dirent => dirent.dispose()); 8540 ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => { 8541 this[`_${key}`].clear(); 8542 }); 8543 8544 this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve(); 8545 return this._closePromise; 8546 } 8547 8548 /** 8549 * Expose list of watched paths 8550 * @returns {Object} for chaining 8551 */ 8552 getWatched() { 8553 const watchList = {}; 8554 this._watched.forEach((entry, dir) => { 8555 const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir; 8556 watchList[key || ONE_DOT] = entry.getChildren().sort(); 8557 }); 8558 return watchList; 8559 } 8560 8561 emitWithAll(event, args) { 8562 this.emit(...args); 8563 if (event !== EV_ERROR) this.emit(EV_ALL, ...args); 8564 } 8565 8566 // Common helpers 8567 // -------------- 8568 8569 /** 8570 * Normalize and emit events. 8571 * Calling _emit DOES NOT MEAN emit() would be called! 8572 * @param {EventName} event Type of event 8573 * @param {Path} path File or directory path 8574 * @param {*=} val1 arguments to be passed with event 8575 * @param {*=} val2 8576 * @param {*=} val3 8577 * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag 8578 */ 8579 async _emit(event, path, val1, val2, val3) { 8580 if (this.closed) return; 8581 8582 const opts = this.options; 8583 if (isWindows) path = sysPath.normalize(path); 8584 if (opts.cwd) path = sysPath.relative(opts.cwd, path); 8585 /** @type Array<any> */ 8586 const args = [event, path]; 8587 if (val3 !== undefined) args.push(val1, val2, val3); 8588 else if (val2 !== undefined) args.push(val1, val2); 8589 else if (val1 !== undefined) args.push(val1); 8590 8591 const awf = opts.awaitWriteFinish; 8592 let pw; 8593 if (awf && (pw = this._pendingWrites.get(path))) { 8594 pw.lastChange = new Date(); 8595 return this; 8596 } 8597 8598 if (opts.atomic) { 8599 if (event === EV_UNLINK) { 8600 this._pendingUnlinks.set(path, args); 8601 setTimeout(() => { 8602 this._pendingUnlinks.forEach((entry, path) => { 8603 this.emit(...entry); 8604 this.emit(EV_ALL, ...entry); 8605 this._pendingUnlinks.delete(path); 8606 }); 8607 }, typeof opts.atomic === 'number' ? opts.atomic : 100); 8608 return this; 8609 } 8610 if (event === EV_ADD && this._pendingUnlinks.has(path)) { 8611 event = args[0] = EV_CHANGE; 8612 this._pendingUnlinks.delete(path); 8613 } 8614 } 8615 8616 if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) { 8617 const awfEmit = (err, stats) => { 8618 if (err) { 8619 event = args[0] = EV_ERROR; 8620 args[1] = err; 8621 this.emitWithAll(event, args); 8622 } else if (stats) { 8623 // if stats doesn't exist the file must have been deleted 8624 if (args.length > 2) { 8625 args[2] = stats; 8626 } else { 8627 args.push(stats); 8628 } 8629 this.emitWithAll(event, args); 8630 } 8631 }; 8632 8633 this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit); 8634 return this; 8635 } 8636 8637 if (event === EV_CHANGE) { 8638 const isThrottled = !this._throttle(EV_CHANGE, path, 50); 8639 if (isThrottled) return this; 8640 } 8641 8642 if (opts.alwaysStat && val1 === undefined && 8643 (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE) 8644 ) { 8645 const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path; 8646 let stats; 8647 try { 8648 stats = await stat(fullPath); 8649 } catch (err) {} 8650 // Suppress event when fs_stat fails, to avoid sending undefined 'stat' 8651 if (!stats || this.closed) return; 8652 args.push(stats); 8653 } 8654 this.emitWithAll(event, args); 8655 8656 return this; 8657 } 8658 8659 /** 8660 * Common handler for errors 8661 * @param {Error} error 8662 * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag 8663 */ 8664 _handleError(error) { 8665 const code = error && error.code; 8666 if (error && code !== 'ENOENT' && code !== 'ENOTDIR' && 8667 (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES')) 8668 ) { 8669 this.emit(EV_ERROR, error); 8670 } 8671 return error || this.closed; 8672 } 8673 8674 /** 8675 * Helper utility for throttling 8676 * @param {ThrottleType} actionType type being throttled 8677 * @param {Path} path being acted upon 8678 * @param {Number} timeout duration of time to suppress duplicate actions 8679 * @returns {Object|false} tracking object or false if action should be suppressed 8680 */ 8681 _throttle(actionType, path, timeout) { 8682 if (!this._throttled.has(actionType)) { 8683 this._throttled.set(actionType, new Map()); 8684 } 8685 8686 /** @type {Map<Path, Object>} */ 8687 const action = this._throttled.get(actionType); 8688 /** @type {Object} */ 8689 const actionPath = action.get(path); 8690 8691 if (actionPath) { 8692 actionPath.count++; 8693 return false; 8694 } 8695 8696 let timeoutObject; 8697 const clear = () => { 8698 const item = action.get(path); 8699 const count = item ? item.count : 0; 8700 action.delete(path); 8701 clearTimeout(timeoutObject); 8702 if (item) clearTimeout(item.timeoutObject); 8703 return count; 8704 }; 8705 timeoutObject = setTimeout(clear, timeout); 8706 const thr = {timeoutObject, clear, count: 0}; 8707 action.set(path, thr); 8708 return thr; 8709 } 8710 8711 _incrReadyCount() { 8712 return this._readyCount++; 8713 } 8714 8715 /** 8716 * Awaits write operation to finish. 8717 * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. 8718 * @param {Path} path being acted upon 8719 * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished 8720 * @param {EventName} event 8721 * @param {Function} awfEmit Callback to be called when ready for event to be emitted. 8722 */ 8723 _awaitWriteFinish(path, threshold, event, awfEmit) { 8724 let timeoutHandler; 8725 8726 let fullPath = path; 8727 if (this.options.cwd && !sysPath.isAbsolute(path)) { 8728 fullPath = sysPath.join(this.options.cwd, path); 8729 } 8730 8731 const now = new Date(); 8732 8733 const awaitWriteFinish = (prevStat) => { 8734 fs.stat(fullPath, (err, curStat) => { 8735 if (err || !this._pendingWrites.has(path)) { 8736 if (err && err.code !== 'ENOENT') awfEmit(err); 8737 return; 8738 } 8739 8740 const now = Number(new Date()); 8741 8742 if (prevStat && curStat.size !== prevStat.size) { 8743 this._pendingWrites.get(path).lastChange = now; 8744 } 8745 const pw = this._pendingWrites.get(path); 8746 const df = now - pw.lastChange; 8747 8748 if (df >= threshold) { 8749 this._pendingWrites.delete(path); 8750 awfEmit(undefined, curStat); 8751 } else { 8752 timeoutHandler = setTimeout( 8753 awaitWriteFinish, 8754 this.options.awaitWriteFinish.pollInterval, 8755 curStat 8756 ); 8757 } 8758 }); 8759 }; 8760 8761 if (!this._pendingWrites.has(path)) { 8762 this._pendingWrites.set(path, { 8763 lastChange: now, 8764 cancelWait: () => { 8765 this._pendingWrites.delete(path); 8766 clearTimeout(timeoutHandler); 8767 return event; 8768 } 8769 }); 8770 timeoutHandler = setTimeout( 8771 awaitWriteFinish, 8772 this.options.awaitWriteFinish.pollInterval 8773 ); 8774 } 8775 } 8776 8777 _getGlobIgnored() { 8778 return [...this._ignoredPaths.values()]; 8779 } 8780 8781 /** 8782 * Determines whether user has asked to ignore this path. 8783 * @param {Path} path filepath or dir 8784 * @param {fs.Stats=} stats result of fs.stat 8785 * @returns {Boolean} 8786 */ 8787 _isIgnored(path, stats) { 8788 if (this.options.atomic && DOT_RE.test(path)) return true; 8789 if (!this._userIgnored) { 8790 const {cwd} = this.options; 8791 const ign = this.options.ignored; 8792 8793 const ignored = ign && ign.map(normalizeIgnored(cwd)); 8794 const paths = arrify(ignored) 8795 .filter((path) => typeof path === STRING_TYPE && !isGlob(path)) 8796 .map((path) => path + SLASH_GLOBSTAR); 8797 const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths); 8798 this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS); 8799 } 8800 8801 return this._userIgnored([path, stats]); 8802 } 8803 8804 _isntIgnored(path, stat) { 8805 return !this._isIgnored(path, stat); 8806 } 8807 8808 /** 8809 * Provides a set of common helpers and properties relating to symlink and glob handling. 8810 * @param {Path} path file, directory, or glob pattern being watched 8811 * @param {Number=} depth at any depth > 0, this isn't a glob 8812 * @returns {WatchHelper} object containing helpers for this path 8813 */ 8814 _getWatchHelpers(path, depth) { 8815 const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path); 8816 const follow = this.options.followSymlinks; 8817 8818 return new WatchHelper(path, watchPath, follow, this); 8819 } 8820 8821 // Directory helpers 8822 // ----------------- 8823 8824 /** 8825 * Provides directory tracking objects 8826 * @param {String} directory path of the directory 8827 * @returns {DirEntry} the directory's tracking object 8828 */ 8829 _getWatchedDir(directory) { 8830 if (!this._boundRemove) this._boundRemove = this._remove.bind(this); 8831 const dir = sysPath.resolve(directory); 8832 if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove)); 8833 return this._watched.get(dir); 8834 } 8835 8836 // File helpers 8837 // ------------ 8838 8839 /** 8840 * Check for read permissions. 8841 * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405 8842 * @param {fs.Stats} stats - object, result of fs_stat 8843 * @returns {Boolean} indicates whether the file can be read 8844 */ 8845 _hasReadPermissions(stats) { 8846 if (this.options.ignorePermissionErrors) return true; 8847 8848 // stats.mode may be bigint 8849 const md = stats && Number.parseInt(stats.mode, 10); 8850 const st = md & 0o777; 8851 const it = Number.parseInt(st.toString(8)[0], 10); 8852 return Boolean(4 & it); 8853 } 8854 8855 /** 8856 * Handles emitting unlink events for 8857 * files and directories, and via recursion, for 8858 * files and directories within directories that are unlinked 8859 * @param {String} directory within which the following item is located 8860 * @param {String} item base path of item/directory 8861 * @returns {void} 8862 */ 8863 _remove(directory, item, isDirectory) { 8864 // if what is being deleted is a directory, get that directory's paths 8865 // for recursive deleting and cleaning of watched object 8866 // if it is not a directory, nestedDirectoryChildren will be empty array 8867 const path = sysPath.join(directory, item); 8868 const fullPath = sysPath.resolve(path); 8869 isDirectory = isDirectory != null 8870 ? isDirectory 8871 : this._watched.has(path) || this._watched.has(fullPath); 8872 8873 // prevent duplicate handling in case of arriving here nearly simultaneously 8874 // via multiple paths (such as _handleFile and _handleDir) 8875 if (!this._throttle('remove', path, 100)) return; 8876 8877 // if the only watched file is removed, watch for its return 8878 if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) { 8879 this.add(directory, item, true); 8880 } 8881 8882 // This will create a new entry in the watched object in either case 8883 // so we got to do the directory check beforehand 8884 const wp = this._getWatchedDir(path); 8885 const nestedDirectoryChildren = wp.getChildren(); 8886 8887 // Recursively remove children directories / files. 8888 nestedDirectoryChildren.forEach(nested => this._remove(path, nested)); 8889 8890 // Check if item was on the watched list and remove it 8891 const parent = this._getWatchedDir(directory); 8892 const wasTracked = parent.has(item); 8893 parent.remove(item); 8894 8895 // Fixes issue #1042 -> Relative paths were detected and added as symlinks 8896 // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612), 8897 // but never removed from the map in case the path was deleted. 8898 // This leads to an incorrect state if the path was recreated: 8899 // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553 8900 if (this._symlinkPaths.has(fullPath)) { 8901 this._symlinkPaths.delete(fullPath); 8902 } 8903 8904 // If we wait for this file to be fully written, cancel the wait. 8905 let relPath = path; 8906 if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path); 8907 if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { 8908 const event = this._pendingWrites.get(relPath).cancelWait(); 8909 if (event === EV_ADD) return; 8910 } 8911 8912 // The Entry will either be a directory that just got removed 8913 // or a bogus entry to a file, in either case we have to remove it 8914 this._watched.delete(path); 8915 this._watched.delete(fullPath); 8916 const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK; 8917 if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path); 8918 8919 // Avoid conflicts if we later create another file with the same name 8920 if (!this.options.useFsEvents) { 8921 this._closePath(path); 8922 } 8923 } 8924 8925 /** 8926 * Closes all watchers for a path 8927 * @param {Path} path 8928 */ 8929 _closePath(path) { 8930 this._closeFile(path); 8931 const dir = sysPath.dirname(path); 8932 this._getWatchedDir(dir).remove(sysPath.basename(path)); 8933 } 8934 8935 /** 8936 * Closes only file-specific watchers 8937 * @param {Path} path 8938 */ 8939 _closeFile(path) { 8940 const closers = this._closers.get(path); 8941 if (!closers) return; 8942 closers.forEach(closer => closer()); 8943 this._closers.delete(path); 8944 } 8945 8946 /** 8947 * 8948 * @param {Path} path 8949 * @param {Function} closer 8950 */ 8951 _addPathCloser(path, closer) { 8952 if (!closer) return; 8953 let list = this._closers.get(path); 8954 if (!list) { 8955 list = []; 8956 this._closers.set(path, list); 8957 } 8958 list.push(closer); 8959 } 8960 8961 _readdirp(root, opts) { 8962 if (this.closed) return; 8963 const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts}; 8964 let stream = readdirp(root, options); 8965 this._streams.add(stream); 8966 stream.once(STR_CLOSE, () => { 8967 stream = undefined; 8968 }); 8969 stream.once(STR_END, () => { 8970 if (stream) { 8971 this._streams.delete(stream); 8972 stream = undefined; 8973 } 8974 }); 8975 return stream; 8976 } 8977 8978 } 8979 8980 // Export FSWatcher class 8981 chokidar$1.FSWatcher = FSWatcher; 8982 8983 /** 8984 * Instantiates watcher with paths to be tracked. 8985 * @param {String|Array<String>} paths file/directory paths and/or globs 8986 * @param {Object=} options chokidar opts 8987 * @returns an instance of FSWatcher for chaining. 8988 */ 8989 const watch = (paths, options) => { 8990 const watcher = new FSWatcher(options); 8991 watcher.add(paths); 8992 return watcher; 8993 }; 8994 8995 chokidar$1.watch = watch; 8996 return chokidar$1; 2834 8997 } 2835 8998 2836 /** 2837 * Handle symlinks encountered while reading a dir. 2838 * @param {Object} entry returned by readdirp 2839 * @param {String} directory path of dir being read 2840 * @param {String} path of this item 2841 * @param {String} item basename of this item 2842 * @returns {Promise<Boolean>} true if no more processing is needed for this entry. 2843 */ 2844 async _handleSymlink(entry, directory, path, item) { 2845 if (this.fsw.closed) { 2846 return; 2847 } 2848 const full = entry.fullPath; 2849 const dir = this.fsw._getWatchedDir(directory); 2850 2851 if (!this.fsw.options.followSymlinks) { 2852 // watch symlink directly (don't follow) and detect changes 2853 this.fsw._incrReadyCount(); 2854 2855 let linkPath; 2856 try { 2857 linkPath = await fsrealpath(path); 2858 } catch (e) { 2859 this.fsw._emitReady(); 2860 return true; 2861 } 2862 2863 if (this.fsw.closed) return; 2864 if (dir.has(item)) { 2865 if (this.fsw._symlinkPaths.get(full) !== linkPath) { 2866 this.fsw._symlinkPaths.set(full, linkPath); 2867 this.fsw._emit(EV_CHANGE$2, path, entry.stats); 2868 } 2869 } else { 2870 dir.add(item); 2871 this.fsw._symlinkPaths.set(full, linkPath); 2872 this.fsw._emit(EV_ADD$2, path, entry.stats); 2873 } 2874 this.fsw._emitReady(); 2875 return true; 2876 } 2877 2878 // don't follow the same symlink more than once 2879 if (this.fsw._symlinkPaths.has(full)) { 2880 return true; 2881 } 2882 2883 this.fsw._symlinkPaths.set(full, true); 2884 } 2885 2886 _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { 2887 // Normalize the directory name on Windows 2888 directory = sysPath$2.join(directory, EMPTY_STR$1); 2889 2890 if (!wh.hasGlob) { 2891 throttler = this.fsw._throttle('readdir', directory, 1000); 2892 if (!throttler) return; 2893 } 2894 2895 const previous = this.fsw._getWatchedDir(wh.path); 2896 const current = new Set(); 2897 2898 let stream = this.fsw._readdirp(directory, { 2899 fileFilter: entry => wh.filterPath(entry), 2900 directoryFilter: entry => wh.filterDir(entry), 2901 depth: 0 2902 }).on(STR_DATA$1, async (entry) => { 2903 if (this.fsw.closed) { 2904 stream = undefined; 2905 return; 2906 } 2907 const item = entry.path; 2908 let path = sysPath$2.join(directory, item); 2909 current.add(item); 2910 2911 if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) { 2912 return; 2913 } 2914 2915 if (this.fsw.closed) { 2916 stream = undefined; 2917 return; 2918 } 2919 // Files that present in current directory snapshot 2920 // but absent in previous are added to watch list and 2921 // emit `add` event. 2922 if (item === target || !target && !previous.has(item)) { 2923 this.fsw._incrReadyCount(); 2924 2925 // ensure relativeness of path is preserved in case of watcher reuse 2926 path = sysPath$2.join(dir, sysPath$2.relative(dir, path)); 2927 2928 this._addToNodeFs(path, initialAdd, wh, depth + 1); 2929 } 2930 }).on(EV_ERROR$2, this._boundHandleError); 2931 2932 return new Promise(resolve => 2933 stream.once(STR_END$2, () => { 2934 if (this.fsw.closed) { 2935 stream = undefined; 2936 return; 2937 } 2938 const wasThrottled = throttler ? throttler.clear() : false; 2939 2940 resolve(); 2941 2942 // Files that absent in current directory snapshot 2943 // but present in previous emit `remove` event 2944 // and are removed from @watched[directory]. 2945 previous.getChildren().filter((item) => { 2946 return item !== directory && 2947 !current.has(item) && 2948 // in case of intersecting globs; 2949 // a path may have been filtered out of this readdir, but 2950 // shouldn't be removed because it matches a different glob 2951 (!wh.hasGlob || wh.filterPath({ 2952 fullPath: sysPath$2.resolve(directory, item) 2953 })); 2954 }).forEach((item) => { 2955 this.fsw._remove(directory, item); 2956 }); 2957 2958 stream = undefined; 2959 2960 // one more time for any missed in case changes came in extremely quickly 2961 if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler); 2962 }) 2963 ); 2964 } 2965 2966 /** 2967 * Read directory to add / remove files from `@watched` list and re-read it on change. 2968 * @param {String} dir fs path 2969 * @param {fs.Stats} stats 2970 * @param {Boolean} initialAdd 2971 * @param {Number} depth relative to user-supplied path 2972 * @param {String} target child path targeted for watch 2973 * @param {Object} wh Common watch helpers for this path 2974 * @param {String} realpath 2975 * @returns {Promise<Function>} closer for the watcher instance. 2976 */ 2977 async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) { 2978 const parentDir = this.fsw._getWatchedDir(sysPath$2.dirname(dir)); 2979 const tracked = parentDir.has(sysPath$2.basename(dir)); 2980 if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { 2981 if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR$2, dir, stats); 2982 } 2983 2984 // ensure dir is tracked (harmless if redundant) 2985 parentDir.add(sysPath$2.basename(dir)); 2986 this.fsw._getWatchedDir(dir); 2987 let throttler; 2988 let closer; 2989 2990 const oDepth = this.fsw.options.depth; 2991 if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) { 2992 if (!target) { 2993 await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); 2994 if (this.fsw.closed) return; 2995 } 2996 2997 closer = this._watchWithNodeFs(dir, (dirPath, stats) => { 2998 // if current directory is removed, do nothing 2999 if (stats && stats.mtimeMs === 0) return; 3000 3001 this._handleRead(dirPath, false, wh, target, dir, depth, throttler); 3002 }); 3003 } 3004 return closer; 3005 } 3006 3007 /** 3008 * Handle added file, directory, or glob pattern. 3009 * Delegates call to _handleFile / _handleDir after checks. 3010 * @param {String} path to file or ir 3011 * @param {Boolean} initialAdd was the file added at watch instantiation? 3012 * @param {Object} priorWh depth relative to user-supplied path 3013 * @param {Number} depth Child path actually targeted for watch 3014 * @param {String=} target Child path actually targeted for watch 3015 * @returns {Promise} 3016 */ 3017 async _addToNodeFs(path, initialAdd, priorWh, depth, target) { 3018 const ready = this.fsw._emitReady; 3019 if (this.fsw._isIgnored(path) || this.fsw.closed) { 3020 ready(); 3021 return false; 3022 } 3023 3024 const wh = this.fsw._getWatchHelpers(path, depth); 3025 if (!wh.hasGlob && priorWh) { 3026 wh.hasGlob = priorWh.hasGlob; 3027 wh.globFilter = priorWh.globFilter; 3028 wh.filterPath = entry => priorWh.filterPath(entry); 3029 wh.filterDir = entry => priorWh.filterDir(entry); 3030 } 3031 3032 // evaluate what is at the path we're being asked to watch 3033 try { 3034 const stats = await statMethods$1[wh.statMethod](wh.watchPath); 3035 if (this.fsw.closed) return; 3036 if (this.fsw._isIgnored(wh.watchPath, stats)) { 3037 ready(); 3038 return false; 3039 } 3040 3041 const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START$1); 3042 let closer; 3043 if (stats.isDirectory()) { 3044 const absPath = sysPath$2.resolve(path); 3045 const targetPath = follow ? await fsrealpath(path) : path; 3046 if (this.fsw.closed) return; 3047 closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); 3048 if (this.fsw.closed) return; 3049 // preserve this symlink's target path 3050 if (absPath !== targetPath && targetPath !== undefined) { 3051 this.fsw._symlinkPaths.set(absPath, targetPath); 3052 } 3053 } else if (stats.isSymbolicLink()) { 3054 const targetPath = follow ? await fsrealpath(path) : path; 3055 if (this.fsw.closed) return; 3056 const parent = sysPath$2.dirname(wh.watchPath); 3057 this.fsw._getWatchedDir(parent).add(wh.watchPath); 3058 this.fsw._emit(EV_ADD$2, wh.watchPath, stats); 3059 closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath); 3060 if (this.fsw.closed) return; 3061 3062 // preserve this symlink's target path 3063 if (targetPath !== undefined) { 3064 this.fsw._symlinkPaths.set(sysPath$2.resolve(path), targetPath); 3065 } 3066 } else { 3067 closer = this._handleFile(wh.watchPath, stats, initialAdd); 3068 } 3069 ready(); 3070 3071 this.fsw._addPathCloser(path, closer); 3072 return false; 3073 3074 } catch (error) { 3075 if (this.fsw._handleError(error)) { 3076 ready(); 3077 return path; 3078 } 3079 } 3080 } 3081 3082 }; 3083 3084 var nodefsHandler = NodeFsHandler$1; 3085 3086 var fseventsHandler = {exports: {}}; 3087 3088 const require$$3 = /*@__PURE__*/rollup.getAugmentedNamespace(fseventsImporter.fseventsImporter); 3089 3090 const fs$1 = require$$0$1; 3091 const sysPath$1 = require$$0$2; 3092 const { promisify: promisify$1 } = require$$2; 3093 3094 let fsevents; 3095 try { 3096 fsevents = require$$3.getFsEvents(); 3097 } catch (error) { 3098 if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error); 3099 } 3100 3101 if (fsevents) { 3102 // TODO: real check 3103 const mtch = process.version.match(/v(\d+)\.(\d+)/); 3104 if (mtch && mtch[1] && mtch[2]) { 3105 const maj = Number.parseInt(mtch[1], 10); 3106 const min = Number.parseInt(mtch[2], 10); 3107 if (maj === 8 && min < 16) { 3108 fsevents = undefined; 3109 } 3110 } 3111 } 3112 3113 const { 3114 EV_ADD: EV_ADD$1, 3115 EV_CHANGE: EV_CHANGE$1, 3116 EV_ADD_DIR: EV_ADD_DIR$1, 3117 EV_UNLINK: EV_UNLINK$1, 3118 EV_ERROR: EV_ERROR$1, 3119 STR_DATA, 3120 STR_END: STR_END$1, 3121 FSEVENT_CREATED, 3122 FSEVENT_MODIFIED, 3123 FSEVENT_DELETED, 3124 FSEVENT_MOVED, 3125 // FSEVENT_CLONED, 3126 FSEVENT_UNKNOWN, 3127 FSEVENT_FLAG_MUST_SCAN_SUBDIRS, 3128 FSEVENT_TYPE_FILE, 3129 FSEVENT_TYPE_DIRECTORY, 3130 FSEVENT_TYPE_SYMLINK, 3131 3132 ROOT_GLOBSTAR, 3133 DIR_SUFFIX, 3134 DOT_SLASH, 3135 FUNCTION_TYPE: FUNCTION_TYPE$1, 3136 EMPTY_FN: EMPTY_FN$1, 3137 IDENTITY_FN 3138 } = constants; 3139 3140 const Depth = (value) => isNaN(value) ? {} : {depth: value}; 3141 3142 const stat$1 = promisify$1(fs$1.stat); 3143 const lstat = promisify$1(fs$1.lstat); 3144 const realpath = promisify$1(fs$1.realpath); 3145 3146 const statMethods = { stat: stat$1, lstat }; 3147 3148 /** 3149 * @typedef {String} Path 3150 */ 3151 3152 /** 3153 * @typedef {Object} FsEventsWatchContainer 3154 * @property {Set<Function>} listeners 3155 * @property {Function} rawEmitter 3156 * @property {{stop: Function}} watcher 3157 */ 3158 3159 // fsevents instance helper functions 3160 /** 3161 * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances) 3162 * @type {Map<Path,FsEventsWatchContainer>} 3163 */ 3164 const FSEventsWatchers = new Map(); 3165 3166 // Threshold of duplicate path prefixes at which to start 3167 // consolidating going forward 3168 const consolidateThreshhold = 10; 3169 3170 const wrongEventFlags = new Set([ 3171 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912 3172 ]); 3173 3174 /** 3175 * Instantiates the fsevents interface 3176 * @param {Path} path path to be watched 3177 * @param {Function} callback called when fsevents is bound and ready 3178 * @returns {{stop: Function}} new fsevents instance 3179 */ 3180 const createFSEventsInstance = (path, callback) => { 3181 const stop = fsevents.watch(path, callback); 3182 return {stop}; 3183 }; 3184 3185 /** 3186 * Instantiates the fsevents interface or binds listeners to an existing one covering 3187 * the same file tree. 3188 * @param {Path} path - to be watched 3189 * @param {Path} realPath - real path for symlinks 3190 * @param {Function} listener - called when fsevents emits events 3191 * @param {Function} rawEmitter - passes data to listeners of the 'raw' event 3192 * @returns {Function} closer 3193 */ 3194 function setFSEventsListener(path, realPath, listener, rawEmitter) { 3195 let watchPath = sysPath$1.extname(realPath) ? sysPath$1.dirname(realPath) : realPath; 3196 3197 const parentPath = sysPath$1.dirname(watchPath); 3198 let cont = FSEventsWatchers.get(watchPath); 3199 3200 // If we've accumulated a substantial number of paths that 3201 // could have been consolidated by watching one directory 3202 // above the current one, create a watcher on the parent 3203 // path instead, so that we do consolidate going forward. 3204 if (couldConsolidate(parentPath)) { 3205 watchPath = parentPath; 3206 } 3207 3208 const resolvedPath = sysPath$1.resolve(path); 3209 const hasSymlink = resolvedPath !== realPath; 3210 3211 const filteredListener = (fullPath, flags, info) => { 3212 if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath); 3213 if ( 3214 fullPath === resolvedPath || 3215 !fullPath.indexOf(resolvedPath + sysPath$1.sep) 3216 ) listener(fullPath, flags, info); 3217 }; 3218 3219 // check if there is already a watcher on a parent path 3220 // modifies `watchPath` to the parent path when it finds a match 3221 let watchedParent = false; 3222 for (const watchedPath of FSEventsWatchers.keys()) { 3223 if (realPath.indexOf(sysPath$1.resolve(watchedPath) + sysPath$1.sep) === 0) { 3224 watchPath = watchedPath; 3225 cont = FSEventsWatchers.get(watchPath); 3226 watchedParent = true; 3227 break; 3228 } 3229 } 3230 3231 if (cont || watchedParent) { 3232 cont.listeners.add(filteredListener); 3233 } else { 3234 cont = { 3235 listeners: new Set([filteredListener]), 3236 rawEmitter, 3237 watcher: createFSEventsInstance(watchPath, (fullPath, flags) => { 3238 if (!cont.listeners.size) return; 3239 if (flags & FSEVENT_FLAG_MUST_SCAN_SUBDIRS) return; 3240 const info = fsevents.getInfo(fullPath, flags); 3241 cont.listeners.forEach(list => { 3242 list(fullPath, flags, info); 3243 }); 3244 3245 cont.rawEmitter(info.event, fullPath, info); 3246 }) 3247 }; 3248 FSEventsWatchers.set(watchPath, cont); 3249 } 3250 3251 // removes this instance's listeners and closes the underlying fsevents 3252 // instance if there are no more listeners left 3253 return () => { 3254 const lst = cont.listeners; 3255 3256 lst.delete(filteredListener); 3257 if (!lst.size) { 3258 FSEventsWatchers.delete(watchPath); 3259 if (cont.watcher) return cont.watcher.stop().then(() => { 3260 cont.rawEmitter = cont.watcher = undefined; 3261 Object.freeze(cont); 3262 }); 3263 } 3264 }; 3265 } 3266 3267 // Decide whether or not we should start a new higher-level 3268 // parent watcher 3269 const couldConsolidate = (path) => { 3270 let count = 0; 3271 for (const watchPath of FSEventsWatchers.keys()) { 3272 if (watchPath.indexOf(path) === 0) { 3273 count++; 3274 if (count >= consolidateThreshhold) { 3275 return true; 3276 } 3277 } 3278 } 3279 3280 return false; 3281 }; 3282 3283 // returns boolean indicating whether fsevents can be used 3284 const canUse = () => fsevents && FSEventsWatchers.size < 128; 3285 3286 // determines subdirectory traversal levels from root to path 3287 const calcDepth = (path, root) => { 3288 let i = 0; 3289 while (!path.indexOf(root) && (path = sysPath$1.dirname(path)) !== root) i++; 3290 return i; 3291 }; 3292 3293 // returns boolean indicating whether the fsevents' event info has the same type 3294 // as the one returned by fs.stat 3295 const sameTypes = (info, stats) => ( 3296 info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() || 3297 info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() || 3298 info.type === FSEVENT_TYPE_FILE && stats.isFile() 3299 ); 3300 3301 /** 3302 * @mixin 3303 */ 3304 let FsEventsHandler$1 = class FsEventsHandler { 3305 3306 /** 3307 * @param {import('../index').FSWatcher} fsw 3308 */ 3309 constructor(fsw) { 3310 this.fsw = fsw; 3311 } 3312 checkIgnored(path, stats) { 3313 const ipaths = this.fsw._ignoredPaths; 3314 if (this.fsw._isIgnored(path, stats)) { 3315 ipaths.add(path); 3316 if (stats && stats.isDirectory()) { 3317 ipaths.add(path + ROOT_GLOBSTAR); 3318 } 3319 return true; 3320 } 3321 3322 ipaths.delete(path); 3323 ipaths.delete(path + ROOT_GLOBSTAR); 3324 } 3325 3326 addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) { 3327 const event = watchedDir.has(item) ? EV_CHANGE$1 : EV_ADD$1; 3328 this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts); 3329 } 3330 3331 async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) { 3332 try { 3333 const stats = await stat$1(path); 3334 if (this.fsw.closed) return; 3335 if (sameTypes(info, stats)) { 3336 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3337 } else { 3338 this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); 3339 } 3340 } catch (error) { 3341 if (error.code === 'EACCES') { 3342 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3343 } else { 3344 this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); 3345 } 3346 } 3347 } 3348 3349 handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) { 3350 if (this.fsw.closed || this.checkIgnored(path)) return; 3351 3352 if (event === EV_UNLINK$1) { 3353 const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY; 3354 // suppress unlink events on never before seen files 3355 if (isDirectory || watchedDir.has(item)) { 3356 this.fsw._remove(parent, item, isDirectory); 3357 } 3358 } else { 3359 if (event === EV_ADD$1) { 3360 // track new directories 3361 if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path); 3362 3363 if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) { 3364 // push symlinks back to the top of the stack to get handled 3365 const curDepth = opts.depth === undefined ? 3366 undefined : calcDepth(fullPath, realPath) + 1; 3367 return this._addToFsEvents(path, false, true, curDepth); 3368 } 3369 3370 // track new paths 3371 // (other than symlinks being followed, which will be tracked soon) 3372 this.fsw._getWatchedDir(parent).add(item); 3373 } 3374 /** 3375 * @type {'add'|'addDir'|'unlink'|'unlinkDir'} 3376 */ 3377 const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event; 3378 this.fsw._emit(eventName, path); 3379 if (eventName === EV_ADD_DIR$1) this._addToFsEvents(path, false, true); 3380 } 3381 } 3382 3383 /** 3384 * Handle symlinks encountered during directory scan 3385 * @param {String} watchPath - file/dir path to be watched with fsevents 3386 * @param {String} realPath - real path (in case of symlinks) 3387 * @param {Function} transform - path transformer 3388 * @param {Function} globFilter - path filter in case a glob pattern was provided 3389 * @returns {Function} closer for the watcher instance 3390 */ 3391 _watchWithFsEvents(watchPath, realPath, transform, globFilter) { 3392 if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return; 3393 const opts = this.fsw.options; 3394 const watchCallback = async (fullPath, flags, info) => { 3395 if (this.fsw.closed) return; 3396 if ( 3397 opts.depth !== undefined && 3398 calcDepth(fullPath, realPath) > opts.depth 3399 ) return; 3400 const path = transform(sysPath$1.join( 3401 watchPath, sysPath$1.relative(watchPath, fullPath) 3402 )); 3403 if (globFilter && !globFilter(path)) return; 3404 // ensure directories are tracked 3405 const parent = sysPath$1.dirname(path); 3406 const item = sysPath$1.basename(path); 3407 const watchedDir = this.fsw._getWatchedDir( 3408 info.type === FSEVENT_TYPE_DIRECTORY ? path : parent 3409 ); 3410 3411 // correct for wrong events emitted 3412 if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) { 3413 if (typeof opts.ignored === FUNCTION_TYPE$1) { 3414 let stats; 3415 try { 3416 stats = await stat$1(path); 3417 } catch (error) {} 3418 if (this.fsw.closed) return; 3419 if (this.checkIgnored(path, stats)) return; 3420 if (sameTypes(info, stats)) { 3421 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3422 } else { 3423 this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); 3424 } 3425 } else { 3426 this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3427 } 3428 } else { 3429 switch (info.event) { 3430 case FSEVENT_CREATED: 3431 case FSEVENT_MODIFIED: 3432 return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3433 case FSEVENT_DELETED: 3434 case FSEVENT_MOVED: 3435 return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3436 } 3437 } 3438 }; 3439 3440 const closer = setFSEventsListener( 3441 watchPath, 3442 realPath, 3443 watchCallback, 3444 this.fsw._emitRaw 3445 ); 3446 3447 this.fsw._emitReady(); 3448 return closer; 3449 } 3450 3451 /** 3452 * Handle symlinks encountered during directory scan 3453 * @param {String} linkPath path to symlink 3454 * @param {String} fullPath absolute path to the symlink 3455 * @param {Function} transform pre-existing path transformer 3456 * @param {Number} curDepth level of subdirectories traversed to where symlink is 3457 * @returns {Promise<void>} 3458 */ 3459 async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) { 3460 // don't follow the same symlink more than once 3461 if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return; 3462 3463 this.fsw._symlinkPaths.set(fullPath, true); 3464 this.fsw._incrReadyCount(); 3465 3466 try { 3467 const linkTarget = await realpath(linkPath); 3468 if (this.fsw.closed) return; 3469 if (this.fsw._isIgnored(linkTarget)) { 3470 return this.fsw._emitReady(); 3471 } 3472 3473 this.fsw._incrReadyCount(); 3474 3475 // add the linkTarget for watching with a wrapper for transform 3476 // that causes emitted paths to incorporate the link's path 3477 this._addToFsEvents(linkTarget || linkPath, (path) => { 3478 let aliasedPath = linkPath; 3479 if (linkTarget && linkTarget !== DOT_SLASH) { 3480 aliasedPath = path.replace(linkTarget, linkPath); 3481 } else if (path !== DOT_SLASH) { 3482 aliasedPath = sysPath$1.join(linkPath, path); 3483 } 3484 return transform(aliasedPath); 3485 }, false, curDepth); 3486 } catch(error) { 3487 if (this.fsw._handleError(error)) { 3488 return this.fsw._emitReady(); 3489 } 3490 } 3491 } 3492 3493 /** 3494 * 3495 * @param {Path} newPath 3496 * @param {fs.Stats} stats 3497 */ 3498 emitAdd(newPath, stats, processPath, opts, forceAdd) { 3499 const pp = processPath(newPath); 3500 const isDir = stats.isDirectory(); 3501 const dirObj = this.fsw._getWatchedDir(sysPath$1.dirname(pp)); 3502 const base = sysPath$1.basename(pp); 3503 3504 // ensure empty dirs get tracked 3505 if (isDir) this.fsw._getWatchedDir(pp); 3506 if (dirObj.has(base)) return; 3507 dirObj.add(base); 3508 3509 if (!opts.ignoreInitial || forceAdd === true) { 3510 this.fsw._emit(isDir ? EV_ADD_DIR$1 : EV_ADD$1, pp, stats); 3511 } 3512 } 3513 3514 initWatch(realPath, path, wh, processPath) { 3515 if (this.fsw.closed) return; 3516 const closer = this._watchWithFsEvents( 3517 wh.watchPath, 3518 sysPath$1.resolve(realPath || wh.watchPath), 3519 processPath, 3520 wh.globFilter 3521 ); 3522 this.fsw._addPathCloser(path, closer); 3523 } 3524 3525 /** 3526 * Handle added path with fsevents 3527 * @param {String} path file/dir path or glob pattern 3528 * @param {Function|Boolean=} transform converts working path to what the user expects 3529 * @param {Boolean=} forceAdd ensure add is emitted 3530 * @param {Number=} priorDepth Level of subdirectories already traversed. 3531 * @returns {Promise<void>} 3532 */ 3533 async _addToFsEvents(path, transform, forceAdd, priorDepth) { 3534 if (this.fsw.closed) { 3535 return; 3536 } 3537 const opts = this.fsw.options; 3538 const processPath = typeof transform === FUNCTION_TYPE$1 ? transform : IDENTITY_FN; 3539 3540 const wh = this.fsw._getWatchHelpers(path); 3541 3542 // evaluate what is at the path we're being asked to watch 3543 try { 3544 const stats = await statMethods[wh.statMethod](wh.watchPath); 3545 if (this.fsw.closed) return; 3546 if (this.fsw._isIgnored(wh.watchPath, stats)) { 3547 throw null; 3548 } 3549 if (stats.isDirectory()) { 3550 // emit addDir unless this is a glob parent 3551 if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd); 3552 3553 // don't recurse further if it would exceed depth setting 3554 if (priorDepth && priorDepth > opts.depth) return; 3555 3556 // scan the contents of the dir 3557 this.fsw._readdirp(wh.watchPath, { 3558 fileFilter: entry => wh.filterPath(entry), 3559 directoryFilter: entry => wh.filterDir(entry), 3560 ...Depth(opts.depth - (priorDepth || 0)) 3561 }).on(STR_DATA, (entry) => { 3562 // need to check filterPath on dirs b/c filterDir is less restrictive 3563 if (this.fsw.closed) { 3564 return; 3565 } 3566 if (entry.stats.isDirectory() && !wh.filterPath(entry)) return; 3567 3568 const joinedPath = sysPath$1.join(wh.watchPath, entry.path); 3569 const {fullPath} = entry; 3570 3571 if (wh.followSymlinks && entry.stats.isSymbolicLink()) { 3572 // preserve the current depth here since it can't be derived from 3573 // real paths past the symlink 3574 const curDepth = opts.depth === undefined ? 3575 undefined : calcDepth(joinedPath, sysPath$1.resolve(wh.watchPath)) + 1; 3576 3577 this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth); 3578 } else { 3579 this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd); 3580 } 3581 }).on(EV_ERROR$1, EMPTY_FN$1).on(STR_END$1, () => { 3582 this.fsw._emitReady(); 3583 }); 3584 } else { 3585 this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd); 3586 this.fsw._emitReady(); 3587 } 3588 } catch (error) { 3589 if (!error || this.fsw._handleError(error)) { 3590 // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__- 3591 this.fsw._emitReady(); 3592 this.fsw._emitReady(); 3593 } 3594 } 3595 3596 if (opts.persistent && forceAdd !== true) { 3597 if (typeof transform === FUNCTION_TYPE$1) { 3598 // realpath has already been resolved 3599 this.initWatch(undefined, path, wh, processPath); 3600 } else { 3601 let realPath; 3602 try { 3603 realPath = await realpath(wh.watchPath); 3604 } catch (e) {} 3605 this.initWatch(realPath, path, wh, processPath); 3606 } 3607 } 3608 } 3609 3610 }; 3611 3612 fseventsHandler.exports = FsEventsHandler$1; 3613 fseventsHandler.exports.canUse = canUse; 3614 3615 var fseventsHandlerExports = fseventsHandler.exports; 3616 3617 const { EventEmitter } = require$$0$3; 3618 const fs = require$$0$1; 3619 const sysPath = require$$0$2; 3620 const { promisify } = require$$2; 3621 const readdirp = readdirp_1; 3622 const anymatch = anymatchExports.default; 3623 const globParent = globParent$1; 3624 const isGlob = isGlob$2; 3625 const braces = braces_1; 3626 const normalizePath = normalizePath$2; 3627 3628 const NodeFsHandler = nodefsHandler; 3629 const FsEventsHandler = fseventsHandlerExports; 3630 const { 3631 EV_ALL, 3632 EV_READY, 3633 EV_ADD, 3634 EV_CHANGE, 3635 EV_UNLINK, 3636 EV_ADD_DIR, 3637 EV_UNLINK_DIR, 3638 EV_RAW, 3639 EV_ERROR, 3640 3641 STR_CLOSE, 3642 STR_END, 3643 3644 BACK_SLASH_RE, 3645 DOUBLE_SLASH_RE, 3646 SLASH_OR_BACK_SLASH_RE, 3647 DOT_RE, 3648 REPLACER_RE, 3649 3650 SLASH, 3651 SLASH_SLASH, 3652 BRACE_START, 3653 BANG, 3654 ONE_DOT, 3655 TWO_DOTS, 3656 GLOBSTAR, 3657 SLASH_GLOBSTAR, 3658 ANYMATCH_OPTS, 3659 STRING_TYPE, 3660 FUNCTION_TYPE, 3661 EMPTY_STR, 3662 EMPTY_FN, 3663 3664 isWindows, 3665 isMacos, 3666 isIBMi 3667 } = constants; 3668 3669 const stat = promisify(fs.stat); 3670 const readdir = promisify(fs.readdir); 3671 3672 /** 3673 * @typedef {String} Path 3674 * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName 3675 * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType 3676 */ 3677 3678 /** 3679 * 3680 * @typedef {Object} WatchHelpers 3681 * @property {Boolean} followSymlinks 3682 * @property {'stat'|'lstat'} statMethod 3683 * @property {Path} path 3684 * @property {Path} watchPath 3685 * @property {Function} entryPath 3686 * @property {Boolean} hasGlob 3687 * @property {Object} globFilter 3688 * @property {Function} filterPath 3689 * @property {Function} filterDir 3690 */ 3691 3692 const arrify = (value = []) => Array.isArray(value) ? value : [value]; 3693 const flatten = (list, result = []) => { 3694 list.forEach(item => { 3695 if (Array.isArray(item)) { 3696 flatten(item, result); 3697 } else { 3698 result.push(item); 3699 } 3700 }); 3701 return result; 3702 }; 3703 3704 const unifyPaths = (paths_) => { 3705 /** 3706 * @type {Array<String>} 3707 */ 3708 const paths = flatten(arrify(paths_)); 3709 if (!paths.every(p => typeof p === STRING_TYPE)) { 3710 throw new TypeError(`Non-string provided as watch path: ${paths}`); 3711 } 3712 return paths.map(normalizePathToUnix); 3713 }; 3714 3715 // If SLASH_SLASH occurs at the beginning of path, it is not replaced 3716 // because "//StoragePC/DrivePool/Movies" is a valid network path 3717 const toUnix = (string) => { 3718 let str = string.replace(BACK_SLASH_RE, SLASH); 3719 let prepend = false; 3720 if (str.startsWith(SLASH_SLASH)) { 3721 prepend = true; 3722 } 3723 while (str.match(DOUBLE_SLASH_RE)) { 3724 str = str.replace(DOUBLE_SLASH_RE, SLASH); 3725 } 3726 if (prepend) { 3727 str = SLASH + str; 3728 } 3729 return str; 3730 }; 3731 3732 // Our version of upath.normalize 3733 // TODO: this is not equal to path-normalize module - investigate why 3734 const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path))); 3735 3736 const normalizeIgnored = (cwd = EMPTY_STR) => (path) => { 3737 if (typeof path !== STRING_TYPE) return path; 3738 return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path)); 3739 }; 3740 3741 const getAbsolutePath = (path, cwd) => { 3742 if (sysPath.isAbsolute(path)) { 3743 return path; 3744 } 3745 if (path.startsWith(BANG)) { 3746 return BANG + sysPath.join(cwd, path.slice(1)); 3747 } 3748 return sysPath.join(cwd, path); 3749 }; 3750 3751 const undef = (opts, key) => opts[key] === undefined; 3752 3753 /** 3754 * Directory entry. 3755 * @property {Path} path 3756 * @property {Set<Path>} items 3757 */ 3758 class DirEntry { 3759 /** 3760 * @param {Path} dir 3761 * @param {Function} removeWatcher 3762 */ 3763 constructor(dir, removeWatcher) { 3764 this.path = dir; 3765 this._removeWatcher = removeWatcher; 3766 /** @type {Set<Path>} */ 3767 this.items = new Set(); 3768 } 3769 3770 add(item) { 3771 const {items} = this; 3772 if (!items) return; 3773 if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item); 3774 } 3775 3776 async remove(item) { 3777 const {items} = this; 3778 if (!items) return; 3779 items.delete(item); 3780 if (items.size > 0) return; 3781 3782 const dir = this.path; 3783 try { 3784 await readdir(dir); 3785 } catch (err) { 3786 if (this._removeWatcher) { 3787 this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir)); 3788 } 3789 } 3790 } 3791 3792 has(item) { 3793 const {items} = this; 3794 if (!items) return; 3795 return items.has(item); 3796 } 3797 3798 /** 3799 * @returns {Array<String>} 3800 */ 3801 getChildren() { 3802 const {items} = this; 3803 if (!items) return; 3804 return [...items.values()]; 3805 } 3806 3807 dispose() { 3808 this.items.clear(); 3809 delete this.path; 3810 delete this._removeWatcher; 3811 delete this.items; 3812 Object.freeze(this); 3813 } 3814 } 3815 3816 const STAT_METHOD_F = 'stat'; 3817 const STAT_METHOD_L = 'lstat'; 3818 class WatchHelper { 3819 constructor(path, watchPath, follow, fsw) { 3820 this.fsw = fsw; 3821 this.path = path = path.replace(REPLACER_RE, EMPTY_STR); 3822 this.watchPath = watchPath; 3823 this.fullWatchPath = sysPath.resolve(watchPath); 3824 this.hasGlob = watchPath !== path; 3825 /** @type {object|boolean} */ 3826 if (path === EMPTY_STR) this.hasGlob = false; 3827 this.globSymlink = this.hasGlob && follow ? undefined : false; 3828 this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false; 3829 this.dirParts = this.getDirParts(path); 3830 this.dirParts.forEach((parts) => { 3831 if (parts.length > 1) parts.pop(); 3832 }); 3833 this.followSymlinks = follow; 3834 this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; 3835 } 3836 3837 checkGlobSymlink(entry) { 3838 // only need to resolve once 3839 // first entry should always have entry.parentDir === EMPTY_STR 3840 if (this.globSymlink === undefined) { 3841 this.globSymlink = entry.fullParentDir === this.fullWatchPath ? 3842 false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath}; 3843 } 3844 3845 if (this.globSymlink) { 3846 return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath); 3847 } 3848 3849 return entry.fullPath; 3850 } 3851 3852 entryPath(entry) { 3853 return sysPath.join(this.watchPath, 3854 sysPath.relative(this.watchPath, this.checkGlobSymlink(entry)) 3855 ); 3856 } 3857 3858 filterPath(entry) { 3859 const {stats} = entry; 3860 if (stats && stats.isSymbolicLink()) return this.filterDir(entry); 3861 const resolvedPath = this.entryPath(entry); 3862 const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ? 3863 this.globFilter(resolvedPath) : true; 3864 return matchesGlob && 3865 this.fsw._isntIgnored(resolvedPath, stats) && 3866 this.fsw._hasReadPermissions(stats); 3867 } 3868 3869 getDirParts(path) { 3870 if (!this.hasGlob) return []; 3871 const parts = []; 3872 const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path]; 3873 expandedPath.forEach((path) => { 3874 parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE)); 3875 }); 3876 return parts; 3877 } 3878 3879 filterDir(entry) { 3880 if (this.hasGlob) { 3881 const entryParts = this.getDirParts(this.checkGlobSymlink(entry)); 3882 let globstar = false; 3883 this.unmatchedGlob = !this.dirParts.some((parts) => { 3884 return parts.every((part, i) => { 3885 if (part === GLOBSTAR) globstar = true; 3886 return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS); 3887 }); 3888 }); 3889 } 3890 return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats); 3891 } 3892 } 3893 3894 /** 3895 * Watches files & directories for changes. Emitted events: 3896 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` 3897 * 3898 * new FSWatcher() 3899 * .add(directories) 3900 * .on('add', path => log('File', path, 'was added')) 3901 */ 3902 class FSWatcher extends EventEmitter { 3903 // Not indenting methods for history sake; for now. 3904 constructor(_opts) { 3905 super(); 3906 3907 const opts = {}; 3908 if (_opts) Object.assign(opts, _opts); // for frozen objects 3909 3910 /** @type {Map<String, DirEntry>} */ 3911 this._watched = new Map(); 3912 /** @type {Map<String, Array>} */ 3913 this._closers = new Map(); 3914 /** @type {Set<String>} */ 3915 this._ignoredPaths = new Set(); 3916 3917 /** @type {Map<ThrottleType, Map>} */ 3918 this._throttled = new Map(); 3919 3920 /** @type {Map<Path, String|Boolean>} */ 3921 this._symlinkPaths = new Map(); 3922 3923 this._streams = new Set(); 3924 this.closed = false; 3925 3926 // Set up default options. 3927 if (undef(opts, 'persistent')) opts.persistent = true; 3928 if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false; 3929 if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false; 3930 if (undef(opts, 'interval')) opts.interval = 100; 3931 if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300; 3932 if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false; 3933 opts.enableBinaryInterval = opts.binaryInterval !== opts.interval; 3934 3935 // Enable fsevents on OS X when polling isn't explicitly enabled. 3936 if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling; 3937 3938 // If we can't use fsevents, ensure the options reflect it's disabled. 3939 const canUseFsEvents = FsEventsHandler.canUse(); 3940 if (!canUseFsEvents) opts.useFsEvents = false; 3941 3942 // Use polling on Mac if not using fsevents. 3943 // Other platforms use non-polling fs_watch. 3944 if (undef(opts, 'usePolling') && !opts.useFsEvents) { 3945 opts.usePolling = isMacos; 3946 } 3947 3948 // Always default to polling on IBM i because fs.watch() is not available on IBM i. 3949 if(isIBMi) { 3950 opts.usePolling = true; 3951 } 3952 3953 // Global override (useful for end-developers that need to force polling for all 3954 // instances of chokidar, regardless of usage/dependency depth) 3955 const envPoll = process.env.CHOKIDAR_USEPOLLING; 3956 if (envPoll !== undefined) { 3957 const envLower = envPoll.toLowerCase(); 3958 3959 if (envLower === 'false' || envLower === '0') { 3960 opts.usePolling = false; 3961 } else if (envLower === 'true' || envLower === '1') { 3962 opts.usePolling = true; 3963 } else { 3964 opts.usePolling = !!envLower; 3965 } 3966 } 3967 const envInterval = process.env.CHOKIDAR_INTERVAL; 3968 if (envInterval) { 3969 opts.interval = Number.parseInt(envInterval, 10); 3970 } 3971 3972 // Editor atomic write normalization enabled by default with fs.watch 3973 if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents; 3974 if (opts.atomic) this._pendingUnlinks = new Map(); 3975 3976 if (undef(opts, 'followSymlinks')) opts.followSymlinks = true; 3977 3978 if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false; 3979 if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {}; 3980 const awf = opts.awaitWriteFinish; 3981 if (awf) { 3982 if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000; 3983 if (!awf.pollInterval) awf.pollInterval = 100; 3984 this._pendingWrites = new Map(); 3985 } 3986 if (opts.ignored) opts.ignored = arrify(opts.ignored); 3987 3988 let readyCalls = 0; 3989 this._emitReady = () => { 3990 readyCalls++; 3991 if (readyCalls >= this._readyCount) { 3992 this._emitReady = EMPTY_FN; 3993 this._readyEmitted = true; 3994 // use process.nextTick to allow time for listener to be bound 3995 process.nextTick(() => this.emit(EV_READY)); 3996 } 3997 }; 3998 this._emitRaw = (...args) => this.emit(EV_RAW, ...args); 3999 this._readyEmitted = false; 4000 this.options = opts; 4001 4002 // Initialize with proper watcher. 4003 if (opts.useFsEvents) { 4004 this._fsEventsHandler = new FsEventsHandler(this); 4005 } else { 4006 this._nodeFsHandler = new NodeFsHandler(this); 4007 } 4008 4009 // You’re frozen when your heart’s not open. 4010 Object.freeze(opts); 4011 } 4012 4013 // Public methods 4014 4015 /** 4016 * Adds paths to be watched on an existing FSWatcher instance 4017 * @param {Path|Array<Path>} paths_ 4018 * @param {String=} _origAdd private; for handling non-existent paths to be watched 4019 * @param {Boolean=} _internal private; indicates a non-user add 4020 * @returns {FSWatcher} for chaining 4021 */ 4022 add(paths_, _origAdd, _internal) { 4023 const {cwd, disableGlobbing} = this.options; 4024 this.closed = false; 4025 let paths = unifyPaths(paths_); 4026 if (cwd) { 4027 paths = paths.map((path) => { 4028 const absPath = getAbsolutePath(path, cwd); 4029 4030 // Check `path` instead of `absPath` because the cwd portion can't be a glob 4031 if (disableGlobbing || !isGlob(path)) { 4032 return absPath; 4033 } 4034 return normalizePath(absPath); 4035 }); 4036 } 4037 4038 // set aside negated glob strings 4039 paths = paths.filter((path) => { 4040 if (path.startsWith(BANG)) { 4041 this._ignoredPaths.add(path.slice(1)); 4042 return false; 4043 } 4044 4045 // if a path is being added that was previously ignored, stop ignoring it 4046 this._ignoredPaths.delete(path); 4047 this._ignoredPaths.delete(path + SLASH_GLOBSTAR); 4048 4049 // reset the cached userIgnored anymatch fn 4050 // to make ignoredPaths changes effective 4051 this._userIgnored = undefined; 4052 4053 return true; 4054 }); 4055 4056 if (this.options.useFsEvents && this._fsEventsHandler) { 4057 if (!this._readyCount) this._readyCount = paths.length; 4058 if (this.options.persistent) this._readyCount += paths.length; 4059 paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path)); 4060 } else { 4061 if (!this._readyCount) this._readyCount = 0; 4062 this._readyCount += paths.length; 4063 Promise.all( 4064 paths.map(async path => { 4065 const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd); 4066 if (res) this._emitReady(); 4067 return res; 4068 }) 4069 ).then(results => { 4070 if (this.closed) return; 4071 results.filter(item => item).forEach(item => { 4072 this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item)); 4073 }); 4074 }); 4075 } 4076 4077 return this; 4078 } 4079 4080 /** 4081 * Close watchers or start ignoring events from specified paths. 4082 * @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs 4083 * @returns {FSWatcher} for chaining 4084 */ 4085 unwatch(paths_) { 4086 if (this.closed) return this; 4087 const paths = unifyPaths(paths_); 4088 const {cwd} = this.options; 4089 4090 paths.forEach((path) => { 4091 // convert to absolute path unless relative path already matches 4092 if (!sysPath.isAbsolute(path) && !this._closers.has(path)) { 4093 if (cwd) path = sysPath.join(cwd, path); 4094 path = sysPath.resolve(path); 4095 } 4096 4097 this._closePath(path); 4098 4099 this._ignoredPaths.add(path); 4100 if (this._watched.has(path)) { 4101 this._ignoredPaths.add(path + SLASH_GLOBSTAR); 4102 } 4103 4104 // reset the cached userIgnored anymatch fn 4105 // to make ignoredPaths changes effective 4106 this._userIgnored = undefined; 4107 }); 4108 4109 return this; 4110 } 4111 4112 /** 4113 * Close watchers and remove all listeners from watched paths. 4114 * @returns {Promise<void>}. 4115 */ 4116 close() { 4117 if (this.closed) return this._closePromise; 4118 this.closed = true; 4119 4120 // Memory management. 4121 this.removeAllListeners(); 4122 const closers = []; 4123 this._closers.forEach(closerList => closerList.forEach(closer => { 4124 const promise = closer(); 4125 if (promise instanceof Promise) closers.push(promise); 4126 })); 4127 this._streams.forEach(stream => stream.destroy()); 4128 this._userIgnored = undefined; 4129 this._readyCount = 0; 4130 this._readyEmitted = false; 4131 this._watched.forEach(dirent => dirent.dispose()); 4132 ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => { 4133 this[`_${key}`].clear(); 4134 }); 4135 4136 this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve(); 4137 return this._closePromise; 4138 } 4139 4140 /** 4141 * Expose list of watched paths 4142 * @returns {Object} for chaining 4143 */ 4144 getWatched() { 4145 const watchList = {}; 4146 this._watched.forEach((entry, dir) => { 4147 const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir; 4148 watchList[key || ONE_DOT] = entry.getChildren().sort(); 4149 }); 4150 return watchList; 4151 } 4152 4153 emitWithAll(event, args) { 4154 this.emit(...args); 4155 if (event !== EV_ERROR) this.emit(EV_ALL, ...args); 4156 } 4157 4158 // Common helpers 4159 // -------------- 4160 4161 /** 4162 * Normalize and emit events. 4163 * Calling _emit DOES NOT MEAN emit() would be called! 4164 * @param {EventName} event Type of event 4165 * @param {Path} path File or directory path 4166 * @param {*=} val1 arguments to be passed with event 4167 * @param {*=} val2 4168 * @param {*=} val3 4169 * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag 4170 */ 4171 async _emit(event, path, val1, val2, val3) { 4172 if (this.closed) return; 4173 4174 const opts = this.options; 4175 if (isWindows) path = sysPath.normalize(path); 4176 if (opts.cwd) path = sysPath.relative(opts.cwd, path); 4177 /** @type Array<any> */ 4178 const args = [event, path]; 4179 if (val3 !== undefined) args.push(val1, val2, val3); 4180 else if (val2 !== undefined) args.push(val1, val2); 4181 else if (val1 !== undefined) args.push(val1); 4182 4183 const awf = opts.awaitWriteFinish; 4184 let pw; 4185 if (awf && (pw = this._pendingWrites.get(path))) { 4186 pw.lastChange = new Date(); 4187 return this; 4188 } 4189 4190 if (opts.atomic) { 4191 if (event === EV_UNLINK) { 4192 this._pendingUnlinks.set(path, args); 4193 setTimeout(() => { 4194 this._pendingUnlinks.forEach((entry, path) => { 4195 this.emit(...entry); 4196 this.emit(EV_ALL, ...entry); 4197 this._pendingUnlinks.delete(path); 4198 }); 4199 }, typeof opts.atomic === 'number' ? opts.atomic : 100); 4200 return this; 4201 } 4202 if (event === EV_ADD && this._pendingUnlinks.has(path)) { 4203 event = args[0] = EV_CHANGE; 4204 this._pendingUnlinks.delete(path); 4205 } 4206 } 4207 4208 if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) { 4209 const awfEmit = (err, stats) => { 4210 if (err) { 4211 event = args[0] = EV_ERROR; 4212 args[1] = err; 4213 this.emitWithAll(event, args); 4214 } else if (stats) { 4215 // if stats doesn't exist the file must have been deleted 4216 if (args.length > 2) { 4217 args[2] = stats; 4218 } else { 4219 args.push(stats); 4220 } 4221 this.emitWithAll(event, args); 4222 } 4223 }; 4224 4225 this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit); 4226 return this; 4227 } 4228 4229 if (event === EV_CHANGE) { 4230 const isThrottled = !this._throttle(EV_CHANGE, path, 50); 4231 if (isThrottled) return this; 4232 } 4233 4234 if (opts.alwaysStat && val1 === undefined && 4235 (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE) 4236 ) { 4237 const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path; 4238 let stats; 4239 try { 4240 stats = await stat(fullPath); 4241 } catch (err) {} 4242 // Suppress event when fs_stat fails, to avoid sending undefined 'stat' 4243 if (!stats || this.closed) return; 4244 args.push(stats); 4245 } 4246 this.emitWithAll(event, args); 4247 4248 return this; 4249 } 4250 4251 /** 4252 * Common handler for errors 4253 * @param {Error} error 4254 * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag 4255 */ 4256 _handleError(error) { 4257 const code = error && error.code; 4258 if (error && code !== 'ENOENT' && code !== 'ENOTDIR' && 4259 (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES')) 4260 ) { 4261 this.emit(EV_ERROR, error); 4262 } 4263 return error || this.closed; 4264 } 4265 4266 /** 4267 * Helper utility for throttling 4268 * @param {ThrottleType} actionType type being throttled 4269 * @param {Path} path being acted upon 4270 * @param {Number} timeout duration of time to suppress duplicate actions 4271 * @returns {Object|false} tracking object or false if action should be suppressed 4272 */ 4273 _throttle(actionType, path, timeout) { 4274 if (!this._throttled.has(actionType)) { 4275 this._throttled.set(actionType, new Map()); 4276 } 4277 4278 /** @type {Map<Path, Object>} */ 4279 const action = this._throttled.get(actionType); 4280 /** @type {Object} */ 4281 const actionPath = action.get(path); 4282 4283 if (actionPath) { 4284 actionPath.count++; 4285 return false; 4286 } 4287 4288 let timeoutObject; 4289 const clear = () => { 4290 const item = action.get(path); 4291 const count = item ? item.count : 0; 4292 action.delete(path); 4293 clearTimeout(timeoutObject); 4294 if (item) clearTimeout(item.timeoutObject); 4295 return count; 4296 }; 4297 timeoutObject = setTimeout(clear, timeout); 4298 const thr = {timeoutObject, clear, count: 0}; 4299 action.set(path, thr); 4300 return thr; 4301 } 4302 4303 _incrReadyCount() { 4304 return this._readyCount++; 4305 } 4306 4307 /** 4308 * Awaits write operation to finish. 4309 * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. 4310 * @param {Path} path being acted upon 4311 * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished 4312 * @param {EventName} event 4313 * @param {Function} awfEmit Callback to be called when ready for event to be emitted. 4314 */ 4315 _awaitWriteFinish(path, threshold, event, awfEmit) { 4316 let timeoutHandler; 4317 4318 let fullPath = path; 4319 if (this.options.cwd && !sysPath.isAbsolute(path)) { 4320 fullPath = sysPath.join(this.options.cwd, path); 4321 } 4322 4323 const now = new Date(); 4324 4325 const awaitWriteFinish = (prevStat) => { 4326 fs.stat(fullPath, (err, curStat) => { 4327 if (err || !this._pendingWrites.has(path)) { 4328 if (err && err.code !== 'ENOENT') awfEmit(err); 4329 return; 4330 } 4331 4332 const now = Number(new Date()); 4333 4334 if (prevStat && curStat.size !== prevStat.size) { 4335 this._pendingWrites.get(path).lastChange = now; 4336 } 4337 const pw = this._pendingWrites.get(path); 4338 const df = now - pw.lastChange; 4339 4340 if (df >= threshold) { 4341 this._pendingWrites.delete(path); 4342 awfEmit(undefined, curStat); 4343 } else { 4344 timeoutHandler = setTimeout( 4345 awaitWriteFinish, 4346 this.options.awaitWriteFinish.pollInterval, 4347 curStat 4348 ); 4349 } 4350 }); 4351 }; 4352 4353 if (!this._pendingWrites.has(path)) { 4354 this._pendingWrites.set(path, { 4355 lastChange: now, 4356 cancelWait: () => { 4357 this._pendingWrites.delete(path); 4358 clearTimeout(timeoutHandler); 4359 return event; 4360 } 4361 }); 4362 timeoutHandler = setTimeout( 4363 awaitWriteFinish, 4364 this.options.awaitWriteFinish.pollInterval 4365 ); 4366 } 4367 } 4368 4369 _getGlobIgnored() { 4370 return [...this._ignoredPaths.values()]; 4371 } 4372 4373 /** 4374 * Determines whether user has asked to ignore this path. 4375 * @param {Path} path filepath or dir 4376 * @param {fs.Stats=} stats result of fs.stat 4377 * @returns {Boolean} 4378 */ 4379 _isIgnored(path, stats) { 4380 if (this.options.atomic && DOT_RE.test(path)) return true; 4381 if (!this._userIgnored) { 4382 const {cwd} = this.options; 4383 const ign = this.options.ignored; 4384 4385 const ignored = ign && ign.map(normalizeIgnored(cwd)); 4386 const paths = arrify(ignored) 4387 .filter((path) => typeof path === STRING_TYPE && !isGlob(path)) 4388 .map((path) => path + SLASH_GLOBSTAR); 4389 const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths); 4390 this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS); 4391 } 4392 4393 return this._userIgnored([path, stats]); 4394 } 4395 4396 _isntIgnored(path, stat) { 4397 return !this._isIgnored(path, stat); 4398 } 4399 4400 /** 4401 * Provides a set of common helpers and properties relating to symlink and glob handling. 4402 * @param {Path} path file, directory, or glob pattern being watched 4403 * @param {Number=} depth at any depth > 0, this isn't a glob 4404 * @returns {WatchHelper} object containing helpers for this path 4405 */ 4406 _getWatchHelpers(path, depth) { 4407 const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path); 4408 const follow = this.options.followSymlinks; 4409 4410 return new WatchHelper(path, watchPath, follow, this); 4411 } 4412 4413 // Directory helpers 4414 // ----------------- 4415 4416 /** 4417 * Provides directory tracking objects 4418 * @param {String} directory path of the directory 4419 * @returns {DirEntry} the directory's tracking object 4420 */ 4421 _getWatchedDir(directory) { 4422 if (!this._boundRemove) this._boundRemove = this._remove.bind(this); 4423 const dir = sysPath.resolve(directory); 4424 if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove)); 4425 return this._watched.get(dir); 4426 } 4427 4428 // File helpers 4429 // ------------ 4430 4431 /** 4432 * Check for read permissions. 4433 * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405 4434 * @param {fs.Stats} stats - object, result of fs_stat 4435 * @returns {Boolean} indicates whether the file can be read 4436 */ 4437 _hasReadPermissions(stats) { 4438 if (this.options.ignorePermissionErrors) return true; 4439 4440 // stats.mode may be bigint 4441 const md = stats && Number.parseInt(stats.mode, 10); 4442 const st = md & 0o777; 4443 const it = Number.parseInt(st.toString(8)[0], 10); 4444 return Boolean(4 & it); 4445 } 4446 4447 /** 4448 * Handles emitting unlink events for 4449 * files and directories, and via recursion, for 4450 * files and directories within directories that are unlinked 4451 * @param {String} directory within which the following item is located 4452 * @param {String} item base path of item/directory 4453 * @returns {void} 4454 */ 4455 _remove(directory, item, isDirectory) { 4456 // if what is being deleted is a directory, get that directory's paths 4457 // for recursive deleting and cleaning of watched object 4458 // if it is not a directory, nestedDirectoryChildren will be empty array 4459 const path = sysPath.join(directory, item); 4460 const fullPath = sysPath.resolve(path); 4461 isDirectory = isDirectory != null 4462 ? isDirectory 4463 : this._watched.has(path) || this._watched.has(fullPath); 4464 4465 // prevent duplicate handling in case of arriving here nearly simultaneously 4466 // via multiple paths (such as _handleFile and _handleDir) 4467 if (!this._throttle('remove', path, 100)) return; 4468 4469 // if the only watched file is removed, watch for its return 4470 if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) { 4471 this.add(directory, item, true); 4472 } 4473 4474 // This will create a new entry in the watched object in either case 4475 // so we got to do the directory check beforehand 4476 const wp = this._getWatchedDir(path); 4477 const nestedDirectoryChildren = wp.getChildren(); 4478 4479 // Recursively remove children directories / files. 4480 nestedDirectoryChildren.forEach(nested => this._remove(path, nested)); 4481 4482 // Check if item was on the watched list and remove it 4483 const parent = this._getWatchedDir(directory); 4484 const wasTracked = parent.has(item); 4485 parent.remove(item); 4486 4487 // Fixes issue #1042 -> Relative paths were detected and added as symlinks 4488 // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612), 4489 // but never removed from the map in case the path was deleted. 4490 // This leads to an incorrect state if the path was recreated: 4491 // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553 4492 if (this._symlinkPaths.has(fullPath)) { 4493 this._symlinkPaths.delete(fullPath); 4494 } 4495 4496 // If we wait for this file to be fully written, cancel the wait. 4497 let relPath = path; 4498 if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path); 4499 if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { 4500 const event = this._pendingWrites.get(relPath).cancelWait(); 4501 if (event === EV_ADD) return; 4502 } 4503 4504 // The Entry will either be a directory that just got removed 4505 // or a bogus entry to a file, in either case we have to remove it 4506 this._watched.delete(path); 4507 this._watched.delete(fullPath); 4508 const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK; 4509 if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path); 4510 4511 // Avoid conflicts if we later create another file with the same name 4512 if (!this.options.useFsEvents) { 4513 this._closePath(path); 4514 } 4515 } 4516 4517 /** 4518 * Closes all watchers for a path 4519 * @param {Path} path 4520 */ 4521 _closePath(path) { 4522 this._closeFile(path); 4523 const dir = sysPath.dirname(path); 4524 this._getWatchedDir(dir).remove(sysPath.basename(path)); 4525 } 4526 4527 /** 4528 * Closes only file-specific watchers 4529 * @param {Path} path 4530 */ 4531 _closeFile(path) { 4532 const closers = this._closers.get(path); 4533 if (!closers) return; 4534 closers.forEach(closer => closer()); 4535 this._closers.delete(path); 4536 } 4537 4538 /** 4539 * 4540 * @param {Path} path 4541 * @param {Function} closer 4542 */ 4543 _addPathCloser(path, closer) { 4544 if (!closer) return; 4545 let list = this._closers.get(path); 4546 if (!list) { 4547 list = []; 4548 this._closers.set(path, list); 4549 } 4550 list.push(closer); 4551 } 4552 4553 _readdirp(root, opts) { 4554 if (this.closed) return; 4555 const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts}; 4556 let stream = readdirp(root, options); 4557 this._streams.add(stream); 4558 stream.once(STR_CLOSE, () => { 4559 stream = undefined; 4560 }); 4561 stream.once(STR_END, () => { 4562 if (stream) { 4563 this._streams.delete(stream); 4564 stream = undefined; 4565 } 4566 }); 4567 return stream; 4568 } 4569 4570 } 4571 4572 // Export FSWatcher class 4573 chokidar.FSWatcher = FSWatcher; 4574 4575 /** 4576 * Instantiates watcher with paths to be tracked. 4577 * @param {String|Array<String>} paths file/directory paths and/or globs 4578 * @param {Object=} options chokidar opts 4579 * @returns an instance of FSWatcher for chaining. 4580 */ 4581 const watch = (paths, options) => { 4582 const watcher = new FSWatcher(options); 4583 watcher.add(paths); 4584 return watcher; 4585 }; 4586 4587 chokidar.watch = watch; 8999 var chokidarExports = /*@__PURE__*/ requireChokidar(); 9000 const chokidar = /*@__PURE__*/rollup.getDefaultExportFromCjs(chokidarExports); 4588 9001 4589 9002 exports.chokidar = chokidar; -
imaps-frontend/node_modules/rollup/dist/shared/loadConfigFile.js
rd565449 r0c6b92a 1 1 /* 2 2 @license 3 Rollup.js v4.2 0.04 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d53 Rollup.js v4.27.4 4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 5 5 6 6 https://github.com/rollup/rollup … … 419 419 async function requireOrImport(pluginPath) { 420 420 try { 421 // eslint-disable-next-line unicorn/prefer-module421 // eslint-disable-next-line @typescript-eslint/no-require-imports 422 422 return require(pluginPath); 423 423 } -
imaps-frontend/node_modules/rollup/dist/shared/parseAst.js
rd565449 r0c6b92a 1 1 /* 2 2 @license 3 Rollup.js v4.2 0.04 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d53 Rollup.js v4.27.4 4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 5 5 6 6 https://github.com/rollup/rollup … … 250 250 const URL_TREATING_MODULE_AS_EXTERNAL_DEPENDENCY = 'troubleshooting/#warning-treating-module-as-external-dependency'; 251 251 const URL_SOURCEMAP_IS_LIKELY_TO_BE_INCORRECT = 'troubleshooting/#warning-sourcemap-is-likely-to-be-incorrect'; 252 // configuration-options 253 const URL_JSX = 'configuration-options/#jsx'; 252 254 const URL_OUTPUT_AMD_ID = 'configuration-options/#output-amd-id'; 253 255 const URL_OUTPUT_AMD_BASEPATH = 'configuration-options/#output-amd-basepath'; … … 274 276 const URL_BUNDLE_CONFIG_AS_CJS = 'command-line-interface/#bundleconfigascjs'; 275 277 const URL_CONFIGURATION_FILES = 'command-line-interface/#configuration-files'; 278 const URL_GENERATEBUNDLE = 'plugin-development/#generatebundle'; 276 279 277 280 function error(base) { … … 322 325 prefix += `${relativeId(id)}${position}: `; 323 326 } 327 const oldMessage = log.message; 324 328 log.message = prefix + log.message; 329 tweakStackMessage(log, oldMessage); 325 330 } 326 331 // Error codes should be sorted alphabetically while errors should be sorted by 327 332 // error code below 328 const ADDON_ERROR = 'ADDON_ERROR', ALREADY_CLOSED = 'ALREADY_CLOSED', AMBIGUOUS_EXTERNAL_NAMESPACES = 'AMBIGUOUS_EXTERNAL_NAMESPACES', ANONYMOUS_PLUGIN_CACHE = 'ANONYMOUS_PLUGIN_CACHE', ASSET_NOT_FINALISED = 'ASSET_NOT_FINALISED', ASSET_NOT_FOUND = 'ASSET_NOT_FOUND', ASSET_SOURCE_ALREADY_SET = 'ASSET_SOURCE_ALREADY_SET', ASSET_SOURCE_MISSING = 'ASSET_SOURCE_MISSING', BAD_LOADER = 'BAD_LOADER', CANNOT_CALL_NAMESPACE = 'CANNOT_CALL_NAMESPACE', CANNOT_EMIT_FROM_OPTIONS_HOOK = 'CANNOT_EMIT_FROM_OPTIONS_HOOK', CHUNK_NOT_GENERATED = 'CHUNK_NOT_GENERATED', CHUNK_INVALID = 'CHUNK_INVALID', CIRCULAR_DEPENDENCY = 'CIRCULAR_DEPENDENCY', CIRCULAR_REEXPORT = 'CIRCULAR_REEXPORT', CONST_REASSIGN = 'CONST_REASSIGN', CYCLIC_CROSS_CHUNK_REEXPORT = 'CYCLIC_CROSS_CHUNK_REEXPORT', DEPRECATED_FEATURE = 'DEPRECATED_FEATURE', DUPLICATE_ARGUMENT_NAME = 'DUPLICATE_ARGUMENT_NAME', DUPLICATE_EXPORT = 'DUPLICATE_EXPORT', DUPLICATE_IMPORT_OPTIONS = 'DUPLICATE_IMPORT_OPTIONS', DUPLICATE_PLUGIN_NAME = 'DUPLICATE_PLUGIN_NAME', EMPTY_BUNDLE = 'EMPTY_BUNDLE', EVAL = 'EVAL', EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS = 'EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS', EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES = 'EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES', EXTERNAL_SYNTHETIC_EXPORTS = 'EXTERNAL_SYNTHETIC_EXPORTS', FAIL_AFTER_WARNINGS = 'FAIL_AFTER_WARNINGS', FILE_NAME_CONFLICT = 'FILE_NAME_CONFLICT', FILE_NOT_FOUND = 'FILE_NOT_FOUND', FIRST_SIDE_EFFECT = 'FIRST_SIDE_EFFECT', ILLEGAL_IDENTIFIER_AS_NAME = 'ILLEGAL_IDENTIFIER_AS_NAME', ILLEGAL_REASSIGNMENT = 'ILLEGAL_REASSIGNMENT', INCONSISTENT_IMPORT_ATTRIBUTES = 'INCONSISTENT_IMPORT_ATTRIBUTES', INVALID_ANNOTATION = 'INVALID_ANNOTATION', INPUT_HOOK_IN_OUTPUT_PLUGIN = 'INPUT_HOOK_IN_OUTPUT_PLUGIN', INVALID_CHUNK = 'INVALID_CHUNK', INVALID_CONFIG_MODULE_FORMAT = 'INVALID_CONFIG_MODULE_FORMAT', INVALID_EXPORT_OPTION = 'INVALID_EXPORT_OPTION', INVALID_EXTERNAL_ID = 'INVALID_EXTERNAL_ID', INVALID_IMPORT_ATTRIBUTE = 'INVALID_IMPORT_ATTRIBUTE', INVALID_LOG_POSITION = 'INVALID_LOG_POSITION', INVALID_OPTION = 'INVALID_OPTION', INVALID_PLUGIN_HOOK = 'INVALID_PLUGIN_HOOK', INVALID_ROLLUP_PHASE = 'INVALID_ROLLUP_PHASE', INVALID_SETASSETSOURCE = 'INVALID_SETASSETSOURCE', INVALID_TLA_FORMAT = 'INVALID_TLA_FORMAT', MISSING_CONFIG = 'MISSING_CONFIG', MISSING_EXPORT = 'MISSING_EXPORT', MISSING_EXTERNAL_CONFIG = 'MISSING_EXTERNAL_CONFIG', MISSING_GLOBAL_NAME = 'MISSING_GLOBAL_NAME', MISSING_IMPLICIT_DEPENDANT = 'MISSING_IMPLICIT_DEPENDANT', MISSING_ NAME_OPTION_FOR_IIFE_EXPORT = 'MISSING_NAME_OPTION_FOR_IIFE_EXPORT', MISSING_NODE_BUILTINS = 'MISSING_NODE_BUILTINS', MISSING_OPTION = 'MISSING_OPTION', MIXED_EXPORTS = 'MIXED_EXPORTS', MODULE_LEVEL_DIRECTIVE = 'MODULE_LEVEL_DIRECTIVE', NAMESPACE_CONFLICT = 'NAMESPACE_CONFLICT', NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE = 'NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE', ONLY_INLINE_SOURCEMAPS = 'ONLY_INLINE_SOURCEMAPS', OPTIMIZE_CHUNK_STATUS = 'OPTIMIZE_CHUNK_STATUS', PARSE_ERROR = 'PARSE_ERROR', PLUGIN_ERROR = 'PLUGIN_ERROR', REDECLARATION_ERROR = 'REDECLARATION_ERROR', SHIMMED_EXPORT = 'SHIMMED_EXPORT', SOURCEMAP_BROKEN = 'SOURCEMAP_BROKEN', SOURCEMAP_ERROR = 'SOURCEMAP_ERROR', SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT = 'SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT', THIS_IS_UNDEFINED = 'THIS_IS_UNDEFINED', UNEXPECTED_NAMED_IMPORT = 'UNEXPECTED_NAMED_IMPORT', UNKNOWN_OPTION = 'UNKNOWN_OPTION', UNRESOLVED_ENTRY = 'UNRESOLVED_ENTRY', UNRESOLVED_IMPORT = 'UNRESOLVED_IMPORT', UNUSED_EXTERNAL_IMPORT = 'UNUSED_EXTERNAL_IMPORT', VALIDATION_ERROR = 'VALIDATION_ERROR';333 const ADDON_ERROR = 'ADDON_ERROR', ALREADY_CLOSED = 'ALREADY_CLOSED', AMBIGUOUS_EXTERNAL_NAMESPACES = 'AMBIGUOUS_EXTERNAL_NAMESPACES', ANONYMOUS_PLUGIN_CACHE = 'ANONYMOUS_PLUGIN_CACHE', ASSET_NOT_FINALISED = 'ASSET_NOT_FINALISED', ASSET_NOT_FOUND = 'ASSET_NOT_FOUND', ASSET_SOURCE_ALREADY_SET = 'ASSET_SOURCE_ALREADY_SET', ASSET_SOURCE_MISSING = 'ASSET_SOURCE_MISSING', BAD_LOADER = 'BAD_LOADER', CANNOT_CALL_NAMESPACE = 'CANNOT_CALL_NAMESPACE', CANNOT_EMIT_FROM_OPTIONS_HOOK = 'CANNOT_EMIT_FROM_OPTIONS_HOOK', CHUNK_NOT_GENERATED = 'CHUNK_NOT_GENERATED', CHUNK_INVALID = 'CHUNK_INVALID', CIRCULAR_DEPENDENCY = 'CIRCULAR_DEPENDENCY', CIRCULAR_REEXPORT = 'CIRCULAR_REEXPORT', CONST_REASSIGN = 'CONST_REASSIGN', CYCLIC_CROSS_CHUNK_REEXPORT = 'CYCLIC_CROSS_CHUNK_REEXPORT', DEPRECATED_FEATURE = 'DEPRECATED_FEATURE', DUPLICATE_ARGUMENT_NAME = 'DUPLICATE_ARGUMENT_NAME', DUPLICATE_EXPORT = 'DUPLICATE_EXPORT', DUPLICATE_IMPORT_OPTIONS = 'DUPLICATE_IMPORT_OPTIONS', DUPLICATE_PLUGIN_NAME = 'DUPLICATE_PLUGIN_NAME', EMPTY_BUNDLE = 'EMPTY_BUNDLE', EVAL = 'EVAL', EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS = 'EXTERNAL_MODULES_CANNOT_BE_INCLUDED_IN_MANUAL_CHUNKS', EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES = 'EXTERNAL_MODULES_CANNOT_BE_TRANSFORMED_TO_MODULES', EXTERNAL_SYNTHETIC_EXPORTS = 'EXTERNAL_SYNTHETIC_EXPORTS', FAIL_AFTER_WARNINGS = 'FAIL_AFTER_WARNINGS', FILE_NAME_CONFLICT = 'FILE_NAME_CONFLICT', FILE_NOT_FOUND = 'FILE_NOT_FOUND', FIRST_SIDE_EFFECT = 'FIRST_SIDE_EFFECT', ILLEGAL_IDENTIFIER_AS_NAME = 'ILLEGAL_IDENTIFIER_AS_NAME', ILLEGAL_REASSIGNMENT = 'ILLEGAL_REASSIGNMENT', INCONSISTENT_IMPORT_ATTRIBUTES = 'INCONSISTENT_IMPORT_ATTRIBUTES', INVALID_ANNOTATION = 'INVALID_ANNOTATION', INPUT_HOOK_IN_OUTPUT_PLUGIN = 'INPUT_HOOK_IN_OUTPUT_PLUGIN', INVALID_CHUNK = 'INVALID_CHUNK', INVALID_CONFIG_MODULE_FORMAT = 'INVALID_CONFIG_MODULE_FORMAT', INVALID_EXPORT_OPTION = 'INVALID_EXPORT_OPTION', INVALID_EXTERNAL_ID = 'INVALID_EXTERNAL_ID', INVALID_IMPORT_ATTRIBUTE = 'INVALID_IMPORT_ATTRIBUTE', INVALID_LOG_POSITION = 'INVALID_LOG_POSITION', INVALID_OPTION = 'INVALID_OPTION', INVALID_PLUGIN_HOOK = 'INVALID_PLUGIN_HOOK', INVALID_ROLLUP_PHASE = 'INVALID_ROLLUP_PHASE', INVALID_SETASSETSOURCE = 'INVALID_SETASSETSOURCE', INVALID_TLA_FORMAT = 'INVALID_TLA_FORMAT', MISSING_CONFIG = 'MISSING_CONFIG', MISSING_EXPORT = 'MISSING_EXPORT', MISSING_EXTERNAL_CONFIG = 'MISSING_EXTERNAL_CONFIG', MISSING_GLOBAL_NAME = 'MISSING_GLOBAL_NAME', MISSING_IMPLICIT_DEPENDANT = 'MISSING_IMPLICIT_DEPENDANT', MISSING_JSX_EXPORT = 'MISSING_JSX_EXPORT', MISSING_NAME_OPTION_FOR_IIFE_EXPORT = 'MISSING_NAME_OPTION_FOR_IIFE_EXPORT', MISSING_NODE_BUILTINS = 'MISSING_NODE_BUILTINS', MISSING_OPTION = 'MISSING_OPTION', MIXED_EXPORTS = 'MIXED_EXPORTS', MODULE_LEVEL_DIRECTIVE = 'MODULE_LEVEL_DIRECTIVE', NAMESPACE_CONFLICT = 'NAMESPACE_CONFLICT', NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE = 'NO_TRANSFORM_MAP_OR_AST_WITHOUT_CODE', ONLY_INLINE_SOURCEMAPS = 'ONLY_INLINE_SOURCEMAPS', OPTIMIZE_CHUNK_STATUS = 'OPTIMIZE_CHUNK_STATUS', PARSE_ERROR = 'PARSE_ERROR', PLUGIN_ERROR = 'PLUGIN_ERROR', REDECLARATION_ERROR = 'REDECLARATION_ERROR', RESERVED_NAMESPACE = 'RESERVED_NAMESPACE', SHIMMED_EXPORT = 'SHIMMED_EXPORT', SOURCEMAP_BROKEN = 'SOURCEMAP_BROKEN', SOURCEMAP_ERROR = 'SOURCEMAP_ERROR', SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT = 'SYNTHETIC_NAMED_EXPORTS_NEED_NAMESPACE_EXPORT', THIS_IS_UNDEFINED = 'THIS_IS_UNDEFINED', UNEXPECTED_NAMED_IMPORT = 'UNEXPECTED_NAMED_IMPORT', UNKNOWN_OPTION = 'UNKNOWN_OPTION', UNRESOLVED_ENTRY = 'UNRESOLVED_ENTRY', UNRESOLVED_IMPORT = 'UNRESOLVED_IMPORT', UNUSED_EXTERNAL_IMPORT = 'UNUSED_EXTERNAL_IMPORT', VALIDATION_ERROR = 'VALIDATION_ERROR'; 329 334 function logAddonNotGenerated(message, hook, plugin) { 330 335 return { … … 560 565 }; 561 566 } 567 function tweakStackMessage(error, oldMessage) { 568 if (!error.stack) { 569 return error; 570 } 571 error.stack = error.stack.replace(oldMessage, error.message); 572 return error; 573 } 562 574 function logCannotBundleConfigAsEsm(originalError) { 563 return {575 return tweakStackMessage({ 564 576 cause: originalError, 565 577 code: INVALID_CONFIG_MODULE_FORMAT, … … 567 579 stack: originalError.stack, 568 580 url: getRollupUrl(URL_BUNDLE_CONFIG_AS_CJS) 569 } ;581 }, originalError.message); 570 582 } 571 583 function logCannotLoadConfigAsCjs(originalError) { 572 return {584 return tweakStackMessage({ 573 585 cause: originalError, 574 586 code: INVALID_CONFIG_MODULE_FORMAT, … … 576 588 stack: originalError.stack, 577 589 url: getRollupUrl(URL_BUNDLE_CONFIG_AS_CJS) 578 } ;590 }, originalError.message); 579 591 } 580 592 function logCannotLoadConfigAsEsm(originalError) { 581 return {593 return tweakStackMessage({ 582 594 cause: originalError, 583 595 code: INVALID_CONFIG_MODULE_FORMAT, … … 585 597 stack: originalError.stack, 586 598 url: getRollupUrl(URL_BUNDLE_CONFIG_AS_CJS) 587 } ;599 }, originalError.message); 588 600 } 589 601 function logInvalidExportOptionValue(optionValue) { … … 730 742 }; 731 743 } 744 function logMissingJsxExport(name, exporter, importer) { 745 return { 746 code: MISSING_JSX_EXPORT, 747 exporter, 748 id: importer, 749 message: `Export "${name}" is not defined in module "${relativeId(exporter)}" even though it is needed in "${relativeId(importer)}" to provide JSX syntax. Please check your "jsx" option.`, 750 names: [name], 751 url: getRollupUrl(URL_JSX) 752 }; 753 } 732 754 function logMissingNameOptionForIifeExport() { 733 755 return { … … 751 773 }; 752 774 } 753 // eslint-disable-next-line unicorn/prevent-abbreviations754 775 function logMissingFileOrDirOption() { 755 776 return { … … 813 834 }; 814 835 } 836 function logReservedNamespace(namespace) { 837 return { 838 code: RESERVED_NAMESPACE, 839 message: `You have overided reserved namespace "${namespace}"` 840 }; 841 } 815 842 function logModuleParseError(error, moduleId) { 816 843 let message = error.message.replace(/ \(\d+:\d+\)$/, ''); … … 821 848 message += ' (Note that you need plugins to import files that are not JavaScript)'; 822 849 } 823 return {850 return tweakStackMessage({ 824 851 cause: error, 825 852 code: PARSE_ERROR, … … 827 854 message, 828 855 stack: error.stack 829 } ;856 }, error.message); 830 857 } 831 858 function logPluginError(error, plugin, { hook, id } = {}) { … … 984 1011 } 985 1012 function warnDeprecationWithOptions(deprecation, urlSnippet, activeDeprecation, log, strictDeprecations, plugin) { 986 {1013 if (activeDeprecation || strictDeprecations) { 987 1014 const warning = logDeprecation(deprecation, urlSnippet); 988 1015 if (strictDeprecations) { … … 1012 1039 const Identifier = 'Identifier'; 1013 1040 const Literal = 'Literal'; 1041 const ObjectExpression = 'ObjectExpression'; 1014 1042 const PanicError = 'PanicError'; 1015 1043 const ParseError = 'ParseError'; … … 1095 1123 return EMPTY_ARRAY; 1096 1124 const length = buffer[position++]; 1097 const list = [];1125 const list = new Array(length); 1098 1126 for (let index = 0; index < length; index++) { 1099 list .push(convertAnnotation(buffer[position++], buffer));1127 list[index] = convertAnnotation(buffer[position++], buffer); 1100 1128 } 1101 1129 return list; … … 1548 1576 }; 1549 1577 }, 1578 function jsxAttribute(position, buffer) { 1579 const valuePosition = buffer[position + 3]; 1580 return { 1581 type: 'JSXAttribute', 1582 start: buffer[position], 1583 end: buffer[position + 1], 1584 name: convertNode(buffer[position + 2], buffer), 1585 value: valuePosition === 0 ? null : convertNode(valuePosition, buffer) 1586 }; 1587 }, 1588 function jsxClosingElement(position, buffer) { 1589 return { 1590 type: 'JSXClosingElement', 1591 start: buffer[position], 1592 end: buffer[position + 1], 1593 name: convertNode(buffer[position + 2], buffer) 1594 }; 1595 }, 1596 function jsxClosingFragment(position, buffer) { 1597 return { 1598 type: 'JSXClosingFragment', 1599 start: buffer[position], 1600 end: buffer[position + 1] 1601 }; 1602 }, 1603 function jsxElement(position, buffer) { 1604 const closingElementPosition = buffer[position + 4]; 1605 return { 1606 type: 'JSXElement', 1607 start: buffer[position], 1608 end: buffer[position + 1], 1609 openingElement: convertNode(buffer[position + 2], buffer), 1610 children: convertNodeList(buffer[position + 3], buffer), 1611 closingElement: closingElementPosition === 0 ? null : convertNode(closingElementPosition, buffer) 1612 }; 1613 }, 1614 function jsxEmptyExpression(position, buffer) { 1615 return { 1616 type: 'JSXEmptyExpression', 1617 start: buffer[position], 1618 end: buffer[position + 1] 1619 }; 1620 }, 1621 function jsxExpressionContainer(position, buffer) { 1622 return { 1623 type: 'JSXExpressionContainer', 1624 start: buffer[position], 1625 end: buffer[position + 1], 1626 expression: convertNode(buffer[position + 2], buffer) 1627 }; 1628 }, 1629 function jsxFragment(position, buffer) { 1630 return { 1631 type: 'JSXFragment', 1632 start: buffer[position], 1633 end: buffer[position + 1], 1634 openingFragment: convertNode(buffer[position + 2], buffer), 1635 children: convertNodeList(buffer[position + 3], buffer), 1636 closingFragment: convertNode(buffer[position + 4], buffer) 1637 }; 1638 }, 1639 function jsxIdentifier(position, buffer) { 1640 return { 1641 type: 'JSXIdentifier', 1642 start: buffer[position], 1643 end: buffer[position + 1], 1644 name: buffer.convertString(buffer[position + 2]) 1645 }; 1646 }, 1647 function jsxMemberExpression(position, buffer) { 1648 return { 1649 type: 'JSXMemberExpression', 1650 start: buffer[position], 1651 end: buffer[position + 1], 1652 object: convertNode(buffer[position + 2], buffer), 1653 property: convertNode(buffer[position + 3], buffer) 1654 }; 1655 }, 1656 function jsxNamespacedName(position, buffer) { 1657 return { 1658 type: 'JSXNamespacedName', 1659 start: buffer[position], 1660 end: buffer[position + 1], 1661 namespace: convertNode(buffer[position + 2], buffer), 1662 name: convertNode(buffer[position + 3], buffer) 1663 }; 1664 }, 1665 function jsxOpeningElement(position, buffer) { 1666 const flags = buffer[position + 2]; 1667 return { 1668 type: 'JSXOpeningElement', 1669 start: buffer[position], 1670 end: buffer[position + 1], 1671 selfClosing: (flags & 1) === 1, 1672 name: convertNode(buffer[position + 3], buffer), 1673 attributes: convertNodeList(buffer[position + 4], buffer) 1674 }; 1675 }, 1676 function jsxOpeningFragment(position, buffer) { 1677 return { 1678 type: 'JSXOpeningFragment', 1679 start: buffer[position], 1680 end: buffer[position + 1], 1681 attributes: [], 1682 selfClosing: false 1683 }; 1684 }, 1685 function jsxSpreadAttribute(position, buffer) { 1686 return { 1687 type: 'JSXSpreadAttribute', 1688 start: buffer[position], 1689 end: buffer[position + 1], 1690 argument: convertNode(buffer[position + 2], buffer) 1691 }; 1692 }, 1693 function jsxSpreadChild(position, buffer) { 1694 return { 1695 type: 'JSXSpreadChild', 1696 start: buffer[position], 1697 end: buffer[position + 1], 1698 expression: convertNode(buffer[position + 2], buffer) 1699 }; 1700 }, 1701 function jsxText(position, buffer) { 1702 return { 1703 type: 'JSXText', 1704 start: buffer[position], 1705 end: buffer[position + 1], 1706 value: buffer.convertString(buffer[position + 2]), 1707 raw: buffer.convertString(buffer[position + 3]) 1708 }; 1709 }, 1550 1710 function labeledStatement(position, buffer) { 1551 1711 return { … … 1941 2101 return EMPTY_ARRAY; 1942 2102 const length = buffer[position++]; 1943 const list = [];2103 const list = new Array(length); 1944 2104 for (let index = 0; index < length; index++) { 1945 2105 const nodePosition = buffer[position++]; 1946 list .push(nodePosition ? convertNode(nodePosition, buffer) : null);2106 list[index] = nodePosition ? convertNode(nodePosition, buffer) : null; 1947 2107 } 1948 2108 return list; … … 1970 2130 } 1971 2131 1972 const parseAst = (input, { allowReturnOutsideFunction = false } = {}) => convertProgram(getAstBuffer(native_js.parse(input, allowReturnOutsideFunction)));1973 const parseAstAsync = async (input, { allowReturnOutsideFunction = false, signal } = {}) => convertProgram(getAstBuffer(await native_js.parseAsync(input, allowReturnOutsideFunction, signal)));2132 const parseAst = (input, { allowReturnOutsideFunction = false, jsx = false } = {}) => convertProgram(getAstBuffer(native_js.parse(input, allowReturnOutsideFunction, jsx))); 2133 const parseAstAsync = async (input, { allowReturnOutsideFunction = false, jsx = false, signal } = {}) => convertProgram(getAstBuffer(await native_js.parseAsync(input, allowReturnOutsideFunction, jsx, signal))); 1974 2134 1975 2135 exports.ANNOTATION_KEY = ANNOTATION_KEY; … … 1992 2152 exports.LOGLEVEL_WARN = LOGLEVEL_WARN; 1993 2153 exports.Literal = Literal; 2154 exports.ObjectExpression = ObjectExpression; 1994 2155 exports.Program = Program; 1995 2156 exports.Property = Property; … … 1998 2159 exports.TemplateLiteral = TemplateLiteral; 1999 2160 exports.URL_AVOIDING_EVAL = URL_AVOIDING_EVAL; 2161 exports.URL_GENERATEBUNDLE = URL_GENERATEBUNDLE; 2162 exports.URL_JSX = URL_JSX; 2000 2163 exports.URL_NAME_IS_NOT_EXPORTED = URL_NAME_IS_NOT_EXPORTED; 2001 2164 exports.URL_OUTPUT_AMD_BASEPATH = URL_OUTPUT_AMD_BASEPATH; … … 2099 2262 exports.logMissingFileOrDirOption = logMissingFileOrDirOption; 2100 2263 exports.logMissingGlobalName = logMissingGlobalName; 2264 exports.logMissingJsxExport = logMissingJsxExport; 2101 2265 exports.logMissingNameOptionForIifeExport = logMissingNameOptionForIifeExport; 2102 2266 exports.logMissingNameOptionForUmdExport = logMissingNameOptionForUmdExport; … … 2113 2277 exports.logPluginError = logPluginError; 2114 2278 exports.logRedeclarationError = logRedeclarationError; 2279 exports.logReservedNamespace = logReservedNamespace; 2115 2280 exports.logShimmedExport = logShimmedExport; 2116 2281 exports.logSourcemapBroken = logSourcemapBroken; -
imaps-frontend/node_modules/rollup/dist/shared/rollup.js
rd565449 r0c6b92a 1 1 /* 2 2 @license 3 Rollup.js v4.2 0.04 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d53 Rollup.js v4.27.4 4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 5 5 6 6 https://github.com/rollup/rollup … … 13 13 const process$1 = require('node:process'); 14 14 const tty = require('tty'); 15 const path $2= require('node:path');15 const path = require('node:path'); 16 16 const require$$0 = require('path'); 17 17 const native_js = require('../native.js'); … … 32 32 const tty__namespace = /*#__PURE__*/_interopNamespaceDefault(tty); 33 33 34 var version = "4.2 0.0";34 var version = "4.27.4"; 35 35 36 36 function ensureArray$1(items) { … … 105 105 const hashPlaceholderOverhead = hashPlaceholderLeft.length + hashPlaceholderRight.length; 106 106 // This is the size of a 128-bits xxhash with base64url encoding 107 const MAX_HASH_SIZE = 2 2;107 const MAX_HASH_SIZE = 21; 108 108 const DEFAULT_HASH_SIZE = 8; 109 109 const getHashPlaceholderGenerator = () => { … … 166 166 const bundleEntries = Object.values(outputBundle); 167 167 for (const asset of bundleEntries) { 168 asset.type === 'asset' && asset.needsCodeReference && unreferencedAssets.add(asset.fileName); 168 if (asset.type === 'asset' && asset.needsCodeReference) { 169 unreferencedAssets.add(asset.fileName); 170 } 169 171 } 170 172 for (const chunk of bundleEntries) { 171 173 if (chunk.type === 'chunk') { 172 174 for (const referencedFile of chunk.referencedFiles) { 173 unreferencedAssets.has(referencedFile) && unreferencedAssets.delete(referencedFile); 175 if (unreferencedAssets.has(referencedFile)) { 176 unreferencedAssets.delete(referencedFile); 177 } 174 178 } 175 179 } … … 196 200 if (!reservedLowercaseBundleKeys.has(name.toLowerCase())) 197 201 return name; 198 const extension = path $2.extname(name);202 const extension = path.extname(name); 199 203 name = name.slice(0, Math.max(0, name.length - extension.length)); 200 204 let uniqueName, uniqueIndex = 1; … … 204 208 } 205 209 206 function generateAssetFileName(name, source, originalFileName, sourceHash, outputOptions, bundle) {210 function generateAssetFileName(name, names, source, originalFileName, originalFileNames, sourceHash, outputOptions, bundle, inputOptions) { 207 211 const emittedName = outputOptions.sanitizeFileName(name || 'asset'); 208 212 return makeUnique(renderNamePattern(typeof outputOptions.assetFileNames === 'function' 209 ? outputOptions.assetFileNames({ name, originalFileName, source, type: 'asset' }) 213 ? outputOptions.assetFileNames({ 214 // Additionally, this should be non-enumerable in the next major 215 get name() { 216 parseAst_js.warnDeprecation('Accessing the "name" property of emitted assets when generating the file name is deprecated. Use the "names" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, inputOptions); 217 return name; 218 }, 219 names, 220 // Additionally, this should be non-enumerable in the next major 221 get originalFileName() { 222 parseAst_js.warnDeprecation('Accessing the "originalFileName" property of emitted assets when generating the file name is deprecated. Use the "originalFileNames" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, inputOptions); 223 return originalFileName; 224 }, 225 originalFileNames, 226 source, 227 type: 'asset' 228 }) 210 229 : outputOptions.assetFileNames, 'output.assetFileNames', { 211 ext: () => path $2.extname(emittedName).slice(1),212 extname: () => path $2.extname(emittedName),230 ext: () => path.extname(emittedName).slice(1), 231 extname: () => path.extname(emittedName), 213 232 hash: size => sourceHash.slice(0, Math.max(0, size || DEFAULT_HASH_SIZE)), 214 name: () => emittedName.slice(0, Math.max(0, emittedName.length - path $2.extname(emittedName).length))233 name: () => emittedName.slice(0, Math.max(0, emittedName.length - path.extname(emittedName).length)) 215 234 }), bundle); 216 235 } … … 323 342 const output = (this.output = { 324 343 bundle, 325 fileNamesBySource : new Map(),344 fileNamesBySourceHash: new Map(), 326 345 getHash, 327 346 outputOptions … … 478 497 return referenceId; 479 498 } 480 finalizeAdditionalAsset(consumedFile, source, { bundle, fileNamesBySource , getHash, outputOptions }) {481 let { fileName, n eedsCodeReference, originalFileName, referenceId } = consumedFile;499 finalizeAdditionalAsset(consumedFile, source, { bundle, fileNamesBySourceHash, getHash, outputOptions }) { 500 let { fileName, name, needsCodeReference, originalFileName, referenceId } = consumedFile; 482 501 // Deduplicate assets if an explicit fileName is not provided 483 502 if (!fileName) { 484 503 const sourceHash = getHash(source); 485 fileName = fileNamesBySource .get(sourceHash);504 fileName = fileNamesBySourceHash.get(sourceHash); 486 505 if (!fileName) { 487 fileName = generateAssetFileName( consumedFile.name, source, originalFileName, sourceHash, outputOptions, bundle);488 fileNamesBySource .set(sourceHash, fileName);506 fileName = generateAssetFileName(name, name ? [name] : [], source, originalFileName, originalFileName ? [originalFileName] : [], sourceHash, outputOptions, bundle, this.options); 507 fileNamesBySourceHash.set(sourceHash, fileName); 489 508 } 490 509 } … … 495 514 if (existingAsset?.type === 'asset') { 496 515 existingAsset.needsCodeReference &&= needsCodeReference; 516 if (name) { 517 existingAsset.names.push(name); 518 } 519 if (originalFileName) { 520 existingAsset.originalFileNames.push(originalFileName); 521 } 497 522 } 498 523 else { 524 const { options } = this; 499 525 bundle[fileName] = { 500 526 fileName, 501 name: consumedFile.name, 527 get name() { 528 // Additionally, this should be non-enumerable in the next major 529 parseAst_js.warnDeprecation('Accessing the "name" property of emitted assets in the bundle is deprecated. Use the "names" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, options); 530 return name; 531 }, 532 names: name ? [name] : [], 502 533 needsCodeReference, 503 originalFileName, 534 get originalFileName() { 535 // Additionally, this should be non-enumerable in the next major 536 parseAst_js.warnDeprecation('Accessing the "originalFileName" property of emitted assets in the bundle is deprecated. Use the "originalFileNames" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, options); 537 return originalFileName; 538 }, 539 originalFileNames: originalFileName ? [originalFileName] : [], 504 540 source, 505 541 type: 'asset' … … 507 543 } 508 544 } 509 finalizeAssetsWithSameSource(consumedFiles, sourceHash, { bundle, fileNamesBySource, outputOptions }) { 545 finalizeAssetsWithSameSource(consumedFiles, sourceHash, { bundle, fileNamesBySourceHash, outputOptions }) { 546 const { names, originalFileNames } = getNamesFromAssets(consumedFiles); 510 547 let fileName = ''; 511 548 let usedConsumedFile; … … 513 550 for (const consumedFile of consumedFiles) { 514 551 needsCodeReference &&= consumedFile.needsCodeReference; 515 const assetFileName = generateAssetFileName(consumedFile.name, consumedFile.source, consumedFile.originalFileName, sourceHash, outputOptions, bundle);552 const assetFileName = generateAssetFileName(consumedFile.name, names, consumedFile.source, consumedFile.originalFileName, originalFileNames, sourceHash, outputOptions, bundle, this.options); 516 553 if (!fileName || 517 554 assetFileName.length < fileName.length || … … 521 558 } 522 559 } 523 fileNamesBySource .set(sourceHash, fileName);560 fileNamesBySourceHash.set(sourceHash, fileName); 524 561 for (const consumedFile of consumedFiles) { 525 562 // We must not modify the original assets to avoid interaction between outputs … … 527 564 this.filesByReferenceId.set(consumedFile.referenceId, assetWithFileName); 528 565 } 566 const { options } = this; 529 567 bundle[fileName] = { 530 568 fileName, 531 name: usedConsumedFile.name, 569 get name() { 570 // Additionally, this should be non-enumerable in the next major 571 parseAst_js.warnDeprecation('Accessing the "name" property of emitted assets in the bundle is deprecated. Use the "names" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, options); 572 return usedConsumedFile.name; 573 }, 574 names, 532 575 needsCodeReference, 533 originalFileName: usedConsumedFile.originalFileName, 576 get originalFileName() { 577 // Additionally, this should be non-enumerable in the next major 578 parseAst_js.warnDeprecation('Accessing the "originalFileName" property of emitted assets in the bundle is deprecated. Use the "originalFileNames" property instead.', parseAst_js.URL_GENERATEBUNDLE, false, options); 579 return usedConsumedFile.originalFileName; 580 }, 581 originalFileNames, 534 582 source: usedConsumedFile.source, 535 583 type: 'asset' … … 537 585 } 538 586 } 539 540 const ANONYMOUS_PLUGIN_PREFIX = 'at position '; 541 const ANONYMOUS_OUTPUT_PLUGIN_PREFIX = 'at output position '; 542 543 function createPluginCache(cache) { 544 return { 545 delete(id) { 546 return delete cache[id]; 547 }, 548 get(id) { 549 const item = cache[id]; 550 if (!item) 551 return; 552 item[0] = 0; 553 return item[1]; 554 }, 555 has(id) { 556 const item = cache[id]; 557 if (!item) 558 return false; 559 item[0] = 0; 560 return true; 561 }, 562 set(id, value) { 563 cache[id] = [0, value]; 564 } 565 }; 566 } 567 function getTrackedPluginCache(pluginCache, onUse) { 568 return { 569 delete(id) { 570 onUse(); 571 return pluginCache.delete(id); 572 }, 573 get(id) { 574 onUse(); 575 return pluginCache.get(id); 576 }, 577 has(id) { 578 onUse(); 579 return pluginCache.has(id); 580 }, 581 set(id, value) { 582 onUse(); 583 return pluginCache.set(id, value); 584 } 585 }; 586 } 587 const NO_CACHE = { 588 delete() { 589 return false; 590 }, 591 get() { 592 return undefined; 593 }, 594 has() { 595 return false; 596 }, 597 set() { } 598 }; 599 function uncacheablePluginError(pluginName) { 600 if (pluginName.startsWith(ANONYMOUS_PLUGIN_PREFIX) || 601 pluginName.startsWith(ANONYMOUS_OUTPUT_PLUGIN_PREFIX)) { 602 return parseAst_js.error(parseAst_js.logAnonymousPluginCache()); 603 } 604 return parseAst_js.error(parseAst_js.logDuplicatePluginName(pluginName)); 605 } 606 function getCacheForUncacheablePlugin(pluginName) { 607 return { 608 delete() { 609 return uncacheablePluginError(pluginName); 610 }, 611 get() { 612 return uncacheablePluginError(pluginName); 613 }, 614 has() { 615 return uncacheablePluginError(pluginName); 616 }, 617 set() { 618 return uncacheablePluginError(pluginName); 619 } 620 }; 587 function getNamesFromAssets(consumedFiles) { 588 const names = []; 589 const originalFileNames = []; 590 for (const { name, originalFileName } of consumedFiles) { 591 if (typeof name === 'string') { 592 names.push(name); 593 } 594 if (originalFileName) { 595 originalFileNames.push(originalFileName); 596 } 597 } 598 originalFileNames.sort(); 599 // Sort by length first and then alphabetically so that the order is stable 600 // and the shortest names come first 601 names.sort((a, b) => a.length - b.length || (a > b ? 1 : a === b ? 0 : -1)); 602 return { names, originalFileNames }; 621 603 } 622 604 … … 717 699 } 718 700 }; 701 const jsxPresets = { 702 preserve: { 703 factory: null, 704 fragment: null, 705 importSource: null, 706 mode: 'preserve' 707 }, 708 'preserve-react': { 709 factory: 'React.createElement', 710 fragment: 'React.Fragment', 711 importSource: 'react', 712 mode: 'preserve' 713 }, 714 react: { 715 factory: 'React.createElement', 716 fragment: 'React.Fragment', 717 importSource: 'react', 718 mode: 'classic' 719 }, 720 'react-jsx': { 721 factory: 'React.createElement', 722 importSource: 'react', 723 jsxImportSource: 'react/jsx-runtime', 724 mode: 'automatic' 725 } 726 }; 719 727 const generatedCodePresets = { 720 728 es2015: { … … 774 782 log.plugin = pluginName; 775 783 logger(level, log); 784 }; 785 } 786 787 const ANONYMOUS_PLUGIN_PREFIX = 'at position '; 788 const ANONYMOUS_OUTPUT_PLUGIN_PREFIX = 'at output position '; 789 790 function createPluginCache(cache) { 791 return { 792 delete(id) { 793 return delete cache[id]; 794 }, 795 get(id) { 796 const item = cache[id]; 797 if (!item) 798 return; 799 item[0] = 0; 800 return item[1]; 801 }, 802 has(id) { 803 const item = cache[id]; 804 if (!item) 805 return false; 806 item[0] = 0; 807 return true; 808 }, 809 set(id, value) { 810 cache[id] = [0, value]; 811 } 812 }; 813 } 814 function getTrackedPluginCache(pluginCache, onUse) { 815 return { 816 delete(id) { 817 onUse(); 818 return pluginCache.delete(id); 819 }, 820 get(id) { 821 onUse(); 822 return pluginCache.get(id); 823 }, 824 has(id) { 825 onUse(); 826 return pluginCache.has(id); 827 }, 828 set(id, value) { 829 onUse(); 830 return pluginCache.set(id, value); 831 } 832 }; 833 } 834 const NO_CACHE = { 835 delete() { 836 return false; 837 }, 838 get() { 839 return undefined; 840 }, 841 has() { 842 return false; 843 }, 844 set() { } 845 }; 846 function uncacheablePluginError(pluginName) { 847 if (pluginName.startsWith(ANONYMOUS_PLUGIN_PREFIX) || 848 pluginName.startsWith(ANONYMOUS_OUTPUT_PLUGIN_PREFIX)) { 849 return parseAst_js.error(parseAst_js.logAnonymousPluginCache()); 850 } 851 return parseAst_js.error(parseAst_js.logDuplicatePluginName(pluginName)); 852 } 853 function getCacheForUncacheablePlugin(pluginName) { 854 return { 855 delete() { 856 return uncacheablePluginError(pluginName); 857 }, 858 get() { 859 return uncacheablePluginError(pluginName); 860 }, 861 has() { 862 return uncacheablePluginError(pluginName); 863 }, 864 set() { 865 return uncacheablePluginError(pluginName); 866 } 776 867 }; 777 868 } … … 993 1084 return handler; 994 1085 } 995 // eslint-disable-next-line @typescript-eslint/ ban-types1086 // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type 996 1087 const hookResult = handler.apply(context, parameters); 997 1088 if (!hookResult?.then) { … … 1038 1129 } 1039 1130 try { 1040 // eslint-disable-next-line @typescript-eslint/ ban-types1131 // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type 1041 1132 return handler.apply(context, parameters); 1042 1133 } … … 1196 1287 external: getExternal(config, overrides), 1197 1288 input: getOption('input') || [], 1289 jsx: getObjectOption(config, overrides, 'jsx', objectifyOptionWithPresets(jsxPresets, 'jsx', parseAst_js.URL_JSX, 'false, ')), 1198 1290 logLevel: getOption('logLevel'), 1199 1291 makeAbsoluteExternalsRelative: getOption('makeAbsoluteExternalsRelative'), … … 1288 1380 sourcemap: getOption('sourcemap'), 1289 1381 sourcemapBaseUrl: getOption('sourcemapBaseUrl'), 1382 sourcemapDebugIds: getOption('sourcemapDebugIds'), 1290 1383 sourcemapExcludeSources: getOption('sourcemapExcludeSources'), 1291 1384 sourcemapFile: getOption('sourcemapFile'), … … 1295 1388 strict: getOption('strict'), 1296 1389 systemNullSetters: getOption('systemNullSetters'), 1297 validate: getOption('validate') 1390 validate: getOption('validate'), 1391 virtualDirname: getOption('virtualDirname') 1298 1392 }; 1299 1393 warnUnknownOptions(config, Object.keys(outputOptions), 'output options', log); … … 1901 1995 this.x_google_ignoreList = properties.x_google_ignoreList; 1902 1996 } 1997 if (typeof properties.debugId !== 'undefined') { 1998 this.debugId = properties.debugId; 1999 } 1903 2000 } 1904 2001 … … 1959 2056 const toString = Object.prototype.toString; 1960 2057 1961 function isObject $1(thing) {2058 function isObject(thing) { 1962 2059 return toString.call(thing) === '[object Object]'; 1963 2060 } … … 2045 2142 2046 2143 while (originalCharIndex < chunk.end) { 2047 if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {2048 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];2049 2050 if (this.hires === 'boundary') {2051 // in hires "boundary", group segments per word boundary than per char2052 if (wordRegex.test(original[originalCharIndex])) {2053 // for first char in the boundary found, start the boundary by pushing a segment2054 if (!charInHiresBoundary) {2055 this.rawSegments.push(segment);2056 charInHiresBoundary = true;2057 }2058 } else {2059 // for non-word char, end the boundary by pushing a segment2060 this.rawSegments.push(segment);2061 charInHiresBoundary = false;2062 }2063 } else {2064 this.rawSegments.push(segment);2065 }2066 }2067 2068 2144 if (original[originalCharIndex] === '\n') { 2069 2145 loc.line += 1; … … 2074 2150 first = true; 2075 2151 } else { 2152 if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { 2153 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; 2154 2155 if (this.hires === 'boundary') { 2156 // in hires "boundary", group segments per word boundary than per char 2157 if (wordRegex.test(original[originalCharIndex])) { 2158 // for first char in the boundary found, start the boundary by pushing a segment 2159 if (!charInHiresBoundary) { 2160 this.rawSegments.push(segment); 2161 charInHiresBoundary = true; 2162 } 2163 } else { 2164 // for non-word char, end the boundary by pushing a segment 2165 this.rawSegments.push(segment); 2166 charInHiresBoundary = false; 2167 } 2168 } else { 2169 this.rawSegments.push(segment); 2170 } 2171 } 2172 2076 2173 loc.column += 1; 2077 2174 this.generatedCodeColumn += 1; … … 2280 2377 const pattern = /^[^\r\n]/gm; 2281 2378 2282 if (isObject $1(indentStr)) {2379 if (isObject(indentStr)) { 2283 2380 options = indentStr; 2284 2381 indentStr = undefined; … … 2957 3054 } 2958 3055 2959 if (!isObject $1(source) || !source.content) {3056 if (!isObject(source) || !source.content) { 2960 3057 throw new Error( 2961 3058 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', … … 3228 3325 }; 3229 3326 3230 const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/; 3231 const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g; 3232 const backSlashRegEx = /\\/g; 3233 function escapeId(id) { 3234 if (!needsEscapeRegEx.test(id)) 3235 return id; 3236 return id.replace(backSlashRegEx, '\\\\').replace(quoteNewlineRegEx, '\\$1'); 3237 } 3238 3239 class ExternalChunk { 3240 constructor(module, options, inputBase) { 3241 this.options = options; 3242 this.inputBase = inputBase; 3243 this.defaultVariableName = ''; 3244 this.namespaceVariableName = ''; 3245 this.variableName = ''; 3246 this.fileName = null; 3247 this.importAttributes = null; 3248 this.id = module.id; 3249 this.moduleInfo = module.info; 3250 this.renormalizeRenderPath = module.renormalizeRenderPath; 3251 this.suggestedVariableName = module.suggestedVariableName; 3252 } 3253 getFileName() { 3254 if (this.fileName) { 3255 return this.fileName; 3256 } 3257 const { paths } = this.options; 3258 return (this.fileName = 3259 (typeof paths === 'function' ? paths(this.id) : paths[this.id]) || 3260 (this.renormalizeRenderPath ? parseAst_js.normalize(path$2.relative(this.inputBase, this.id)) : this.id)); 3261 } 3262 getImportAttributes(snippets) { 3263 return (this.importAttributes ||= formatAttributes(this.options.format === 'es' && 3264 this.options.externalImportAttributes && 3265 this.moduleInfo.attributes, snippets)); 3266 } 3267 getImportPath(importer) { 3268 return escapeId(this.renormalizeRenderPath 3269 ? parseAst_js.getImportPath(importer, this.getFileName(), this.options.format === 'amd', false) 3270 : this.getFileName()); 3271 } 3272 } 3273 function formatAttributes(attributes, { getObject }) { 3274 if (!attributes) { 3275 return null; 3276 } 3277 const assertionEntries = Object.entries(attributes).map(([key, value]) => [key, `'${value}'`]); 3278 if (assertionEntries.length > 0) { 3279 return getObject(assertionEntries, { lineBreakIndent: null }); 3280 } 3281 return null; 3282 } 3327 function treeshakeNode(node, code, start, end) { 3328 code.remove(start, end); 3329 node.removeAnnotations(code); 3330 } 3331 3332 const NO_SEMICOLON = { isNoStatement: true }; 3333 // This assumes there are only white-space and comments between start and the string we are looking for 3334 function findFirstOccurrenceOutsideComment(code, searchString, start = 0) { 3335 let searchPos, charCodeAfterSlash; 3336 searchPos = code.indexOf(searchString, start); 3337 while (true) { 3338 start = code.indexOf('/', start); 3339 if (start === -1 || start >= searchPos) 3340 return searchPos; 3341 charCodeAfterSlash = code.charCodeAt(++start); 3342 ++start; 3343 // With our assumption, '/' always starts a comment. Determine comment type: 3344 start = 3345 charCodeAfterSlash === 47 /*"/"*/ 3346 ? code.indexOf('\n', start) + 1 3347 : code.indexOf('*/', start) + 2; 3348 if (start > searchPos) { 3349 searchPos = code.indexOf(searchString, start); 3350 } 3351 } 3352 } 3353 const NON_WHITESPACE = /\S/g; 3354 function findNonWhiteSpace(code, index) { 3355 NON_WHITESPACE.lastIndex = index; 3356 const result = NON_WHITESPACE.exec(code); 3357 return result.index; 3358 } 3359 const WHITESPACE = /\s/; 3360 function findLastWhiteSpaceReverse(code, start, end) { 3361 while (true) { 3362 if (start >= end) { 3363 return end; 3364 } 3365 if (WHITESPACE.test(code[end - 1])) { 3366 end--; 3367 } 3368 else { 3369 return end; 3370 } 3371 } 3372 } 3373 // This assumes "code" only contains white-space and comments 3374 // Returns position of line-comment if applicable 3375 function findFirstLineBreakOutsideComment(code) { 3376 let lineBreakPos, charCodeAfterSlash, start = 0; 3377 lineBreakPos = code.indexOf('\n', start); 3378 while (true) { 3379 start = code.indexOf('/', start); 3380 if (start === -1 || start > lineBreakPos) 3381 return [lineBreakPos, lineBreakPos + 1]; 3382 // With our assumption, '/' always starts a comment. Determine comment type: 3383 charCodeAfterSlash = code.charCodeAt(start + 1); 3384 if (charCodeAfterSlash === 47 /*"/"*/) 3385 return [start, lineBreakPos + 1]; 3386 start = code.indexOf('*/', start + 2) + 2; 3387 if (start > lineBreakPos) { 3388 lineBreakPos = code.indexOf('\n', start); 3389 } 3390 } 3391 } 3392 function renderStatementList(statements, code, start, end, options) { 3393 let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart; 3394 let nextNode = statements[0]; 3395 let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries; 3396 if (nextNodeNeedsBoundaries) { 3397 nextNodeStart = 3398 start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1]; 3399 } 3400 for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) { 3401 currentNode = nextNode; 3402 currentNodeStart = nextNodeStart; 3403 currentNodeNeedsBoundaries = nextNodeNeedsBoundaries; 3404 nextNode = statements[nextIndex]; 3405 nextNodeNeedsBoundaries = 3406 nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries; 3407 if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) { 3408 nextNodeStart = 3409 currentNode.end + 3410 findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1]; 3411 if (currentNode.included) { 3412 if (currentNodeNeedsBoundaries) { 3413 currentNode.render(code, options, { 3414 end: nextNodeStart, 3415 start: currentNodeStart 3416 }); 3417 } 3418 else { 3419 currentNode.render(code, options); 3420 } 3421 } 3422 else { 3423 treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart); 3424 } 3425 } 3426 else { 3427 currentNode.render(code, options); 3428 } 3429 } 3430 } 3431 // This assumes that the first character is not part of the first node 3432 function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) { 3433 const splitUpNodes = []; 3434 let node, nextNodeStart, contentEnd, char; 3435 let separator = start - 1; 3436 for (const nextNode of nodes) { 3437 if (node !== undefined) { 3438 separator = 3439 node.end + 3440 findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ','); 3441 } 3442 nextNodeStart = contentEnd = 3443 separator + 3444 1 + 3445 findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1]; 3446 while (((char = code.original.charCodeAt(nextNodeStart)), 3447 char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/) 3448 nextNodeStart++; 3449 if (node !== undefined) { 3450 splitUpNodes.push({ 3451 contentEnd, 3452 end: nextNodeStart, 3453 node, 3454 separator, 3455 start 3456 }); 3457 } 3458 node = nextNode; 3459 start = nextNodeStart; 3460 } 3461 splitUpNodes.push({ 3462 contentEnd: end, 3463 end, 3464 node: node, 3465 separator: null, 3466 start 3467 }); 3468 return splitUpNodes; 3469 } 3470 // This assumes there are only white-space and comments between start and end 3471 function removeLineBreaks(code, start, end) { 3472 while (true) { 3473 const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end)); 3474 if (removeStart === -1) { 3475 break; 3476 } 3477 code.remove(start + removeStart, (start += removeEnd)); 3478 } 3479 } 3480 3481 function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') { 3482 if (exportedVariables.length === 1 && 3483 exportNamesByVariable.get(exportedVariables[0]).length === 1) { 3484 const variable = exportedVariables[0]; 3485 return `exports(${JSON.stringify(exportNamesByVariable.get(variable)[0])},${_}${variable.getName(getPropertyAccess)}${modifier})`; 3486 } 3487 else { 3488 const fields = []; 3489 for (const variable of exportedVariables) { 3490 for (const exportName of exportNamesByVariable.get(variable)) { 3491 fields.push([exportName, variable.getName(getPropertyAccess) + modifier]); 3492 } 3493 } 3494 return `exports(${getObject(fields, { lineBreakIndent: null })})`; 3495 } 3496 } 3497 // This is only invoked if there is exactly one export name 3498 function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) { 3499 code.prependRight(expressionStart, `exports(${JSON.stringify(exportNamesByVariable.get(exportedVariable)[0])},${_}`); 3500 code.appendLeft(expressionEnd, ')'); 3501 } 3502 function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) { 3503 const { _, getDirectReturnIifeLeft } = options.snippets; 3504 code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens })); 3505 code.appendLeft(expressionEnd, ')'); 3506 } 3507 function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) { 3508 const { _, getPropertyAccess } = options.snippets; 3509 code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`); 3510 if (needsParens) { 3511 code.prependRight(expressionStart, '('); 3512 code.appendLeft(expressionEnd, ')'); 3513 } 3514 } 3515 function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) { 3516 const { _ } = options.snippets; 3517 code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`); 3518 if (needsParens) { 3519 code.prependRight(expressionStart, '('); 3520 code.appendLeft(expressionEnd, ')'); 3521 } 3522 } 3523 3524 /** @import { Node } from 'estree' */ 3525 3526 /** 3527 * @param {Node} node 3528 * @param {Node} parent 3529 * @returns {boolean} 3530 */ 3531 function is_reference(node, parent) { 3532 if (node.type === 'MemberExpression') { 3533 return !node.computed && is_reference(node.object, node); 3534 } 3535 3536 if (node.type !== 'Identifier') return false; 3537 3538 switch (parent?.type) { 3539 // disregard `bar` in `foo.bar` 3540 case 'MemberExpression': 3541 return parent.computed || node === parent.object; 3542 3543 // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}` 3544 case 'MethodDefinition': 3545 return parent.computed; 3546 3547 // disregard the `meta` in `import.meta` 3548 case 'MetaProperty': 3549 return parent.meta === node; 3550 3551 // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}` 3552 case 'PropertyDefinition': 3553 return parent.computed || node === parent.value; 3554 3555 // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }` 3556 case 'Property': 3557 return parent.computed || node === parent.value; 3558 3559 // disregard the `bar` in `export { foo as bar }` or 3560 // the foo in `import { foo as bar }` 3561 case 'ExportSpecifier': 3562 case 'ImportSpecifier': 3563 return node === parent.local; 3564 3565 // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}` 3566 case 'LabeledStatement': 3567 case 'BreakStatement': 3568 case 'ContinueStatement': 3569 return false; 3570 3571 default: 3572 return true; 3573 } 3574 } 3575 3576 const PureFunctionKey = Symbol('PureFunction'); 3577 const getPureFunctions = ({ treeshake }) => { 3578 const pureFunctions = Object.create(null); 3579 for (const functionName of treeshake ? treeshake.manualPureFunctions : []) { 3580 let currentFunctions = pureFunctions; 3581 for (const pathSegment of functionName.split('.')) { 3582 currentFunctions = currentFunctions[pathSegment] ||= Object.create(null); 3583 } 3584 currentFunctions[PureFunctionKey] = true; 3585 } 3586 return pureFunctions; 3587 }; 3283 3588 3284 3589 const UnknownKey = Symbol('Unknown Key'); … … 3440 3745 this.alwaysRendered = false; 3441 3746 this.forbiddenNames = null; 3747 this.globalName = null; 3442 3748 this.initReached = false; 3443 3749 this.isId = false; … … 3485 3791 } 3486 3792 getName(getPropertyAccess, useOriginalName) { 3793 if (this.globalName) { 3794 return this.globalName; 3795 } 3487 3796 if (useOriginalName?.(this)) { 3488 3797 return this.name; … … 3498 3807 } 3499 3808 /** 3500 * Marks this variable as being part of the bundle, which is usually the case when one of3501 * its identifiers becomes part of the bundle. Returns true if it has not been included3502 * previously.3503 * Once a variable is included, it shouldtake care all its declarations are included.3809 * Marks this variable as being part of the bundle, which is usually the case 3810 * when one of its identifiers becomes part of the bundle. Returns true if it 3811 * has not been included previously. Once a variable is included, it should 3812 * take care all its declarations are included. 3504 3813 */ 3505 3814 include() { … … 3725 4034 } 3726 4035 3727 function getDefaultExportFromCjs (x) { 3728 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 3729 } 3730 3731 function getAugmentedNamespace(n) { 3732 if (n.__esModule) return n; 3733 var f = n.default; 3734 if (typeof f == "function") { 3735 var a = function a () { 3736 if (this instanceof a) { 3737 return Reflect.construct(f, arguments, this.constructor); 3738 } 3739 return f.apply(this, arguments); 3740 }; 3741 a.prototype = f.prototype; 3742 } else a = {}; 3743 Object.defineProperty(a, '__esModule', {value: true}); 3744 Object.keys(n).forEach(function (k) { 3745 var d = Object.getOwnPropertyDescriptor(n, k); 3746 Object.defineProperty(a, k, d.get ? d : { 3747 enumerable: true, 3748 get: function () { 3749 return n[k]; 3750 } 3751 }); 3752 }); 3753 return a; 3754 } 3755 3756 var utils$3 = {}; 3757 3758 const path$1 = require$$0; 3759 const WIN_SLASH = '\\\\/'; 3760 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 3761 3762 /** 3763 * Posix glob regex 3764 */ 3765 3766 const DOT_LITERAL = '\\.'; 3767 const PLUS_LITERAL = '\\+'; 3768 const QMARK_LITERAL = '\\?'; 3769 const SLASH_LITERAL = '\\/'; 3770 const ONE_CHAR = '(?=.)'; 3771 const QMARK = '[^/]'; 3772 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 3773 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 3774 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 3775 const NO_DOT = `(?!${DOT_LITERAL})`; 3776 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 3777 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 3778 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 3779 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 3780 const STAR = `${QMARK}*?`; 3781 3782 const POSIX_CHARS = { 3783 DOT_LITERAL, 3784 PLUS_LITERAL, 3785 QMARK_LITERAL, 3786 SLASH_LITERAL, 3787 ONE_CHAR, 3788 QMARK, 3789 END_ANCHOR, 3790 DOTS_SLASH, 3791 NO_DOT, 3792 NO_DOTS, 3793 NO_DOT_SLASH, 3794 NO_DOTS_SLASH, 3795 QMARK_NO_DOT, 3796 STAR, 3797 START_ANCHOR 4036 function markModuleAndImpureDependenciesAsExecuted(baseModule) { 4037 baseModule.isExecuted = true; 4038 const modules = [baseModule]; 4039 const visitedModules = new Set(); 4040 for (const module of modules) { 4041 for (const dependency of [...module.dependencies, ...module.implicitlyLoadedBefore]) { 4042 if (!(dependency instanceof ExternalModule) && 4043 !dependency.isExecuted && 4044 (dependency.info.moduleSideEffects || module.implicitlyLoadedBefore.has(dependency)) && 4045 !visitedModules.has(dependency.id)) { 4046 dependency.isExecuted = true; 4047 visitedModules.add(dependency.id); 4048 modules.push(dependency); 4049 } 4050 } 4051 } 4052 } 4053 4054 // This file is generated by scripts/generate-child-node-keys.js. 4055 // Do not edit this file directly. 4056 const childNodeKeys = { 4057 ArrayExpression: ['elements'], 4058 ArrayPattern: ['elements'], 4059 ArrowFunctionExpression: ['params', 'body'], 4060 AssignmentExpression: ['left', 'right'], 4061 AssignmentPattern: ['left', 'right'], 4062 AwaitExpression: ['argument'], 4063 BinaryExpression: ['left', 'right'], 4064 BlockStatement: ['body'], 4065 BreakStatement: ['label'], 4066 CallExpression: ['callee', 'arguments'], 4067 CatchClause: ['param', 'body'], 4068 ChainExpression: ['expression'], 4069 ClassBody: ['body'], 4070 ClassDeclaration: ['decorators', 'id', 'superClass', 'body'], 4071 ClassExpression: ['decorators', 'id', 'superClass', 'body'], 4072 ConditionalExpression: ['test', 'consequent', 'alternate'], 4073 ContinueStatement: ['label'], 4074 DebuggerStatement: [], 4075 Decorator: ['expression'], 4076 DoWhileStatement: ['body', 'test'], 4077 EmptyStatement: [], 4078 ExportAllDeclaration: ['exported', 'source', 'attributes'], 4079 ExportDefaultDeclaration: ['declaration'], 4080 ExportNamedDeclaration: ['specifiers', 'source', 'attributes', 'declaration'], 4081 ExportSpecifier: ['local', 'exported'], 4082 ExpressionStatement: ['expression'], 4083 ForInStatement: ['left', 'right', 'body'], 4084 ForOfStatement: ['left', 'right', 'body'], 4085 ForStatement: ['init', 'test', 'update', 'body'], 4086 FunctionDeclaration: ['id', 'params', 'body'], 4087 FunctionExpression: ['id', 'params', 'body'], 4088 Identifier: [], 4089 IfStatement: ['test', 'consequent', 'alternate'], 4090 ImportAttribute: ['key', 'value'], 4091 ImportDeclaration: ['specifiers', 'source', 'attributes'], 4092 ImportDefaultSpecifier: ['local'], 4093 ImportExpression: ['source', 'options'], 4094 ImportNamespaceSpecifier: ['local'], 4095 ImportSpecifier: ['imported', 'local'], 4096 JSXAttribute: ['name', 'value'], 4097 JSXClosingElement: ['name'], 4098 JSXClosingFragment: [], 4099 JSXElement: ['openingElement', 'children', 'closingElement'], 4100 JSXEmptyExpression: [], 4101 JSXExpressionContainer: ['expression'], 4102 JSXFragment: ['openingFragment', 'children', 'closingFragment'], 4103 JSXIdentifier: [], 4104 JSXMemberExpression: ['object', 'property'], 4105 JSXNamespacedName: ['namespace', 'name'], 4106 JSXOpeningElement: ['name', 'attributes'], 4107 JSXOpeningFragment: [], 4108 JSXSpreadAttribute: ['argument'], 4109 JSXSpreadChild: ['expression'], 4110 JSXText: [], 4111 LabeledStatement: ['label', 'body'], 4112 Literal: [], 4113 LogicalExpression: ['left', 'right'], 4114 MemberExpression: ['object', 'property'], 4115 MetaProperty: ['meta', 'property'], 4116 MethodDefinition: ['decorators', 'key', 'value'], 4117 NewExpression: ['callee', 'arguments'], 4118 ObjectExpression: ['properties'], 4119 ObjectPattern: ['properties'], 4120 PanicError: [], 4121 ParseError: [], 4122 PrivateIdentifier: [], 4123 Program: ['body'], 4124 Property: ['key', 'value'], 4125 PropertyDefinition: ['decorators', 'key', 'value'], 4126 RestElement: ['argument'], 4127 ReturnStatement: ['argument'], 4128 SequenceExpression: ['expressions'], 4129 SpreadElement: ['argument'], 4130 StaticBlock: ['body'], 4131 Super: [], 4132 SwitchCase: ['test', 'consequent'], 4133 SwitchStatement: ['discriminant', 'cases'], 4134 TaggedTemplateExpression: ['tag', 'quasi'], 4135 TemplateElement: [], 4136 TemplateLiteral: ['quasis', 'expressions'], 4137 ThisExpression: [], 4138 ThrowStatement: ['argument'], 4139 TryStatement: ['block', 'handler', 'finalizer'], 4140 UnaryExpression: ['argument'], 4141 UpdateExpression: ['argument'], 4142 VariableDeclaration: ['declarations'], 4143 VariableDeclarator: ['id', 'init'], 4144 WhileStatement: ['test', 'body'], 4145 YieldExpression: ['argument'] 3798 4146 }; 3799 3800 /**3801 * Windows glob regex3802 */3803 3804 const WINDOWS_CHARS = {3805 ...POSIX_CHARS,3806 3807 SLASH_LITERAL: `[${WIN_SLASH}]`,3808 QMARK: WIN_NO_SLASH,3809 STAR: `${WIN_NO_SLASH}*?`,3810 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,3811 NO_DOT: `(?!${DOT_LITERAL})`,3812 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,3813 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,3814 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,3815 QMARK_NO_DOT: `[^.${WIN_SLASH}]`,3816 START_ANCHOR: `(?:^|[${WIN_SLASH}])`,3817 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`3818 };3819 3820 /**3821 * POSIX Bracket Regex3822 */3823 3824 const POSIX_REGEX_SOURCE$1 = {3825 alnum: 'a-zA-Z0-9',3826 alpha: 'a-zA-Z',3827 ascii: '\\x00-\\x7F',3828 blank: ' \\t',3829 cntrl: '\\x00-\\x1F\\x7F',3830 digit: '0-9',3831 graph: '\\x21-\\x7E',3832 lower: 'a-z',3833 print: '\\x20-\\x7E ',3834 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',3835 space: ' \\t\\r\\n\\v\\f',3836 upper: 'A-Z',3837 word: 'A-Za-z0-9_',3838 xdigit: 'A-Fa-f0-9'3839 };3840 3841 var constants$2 = {3842 MAX_LENGTH: 1024 * 64,3843 POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1,3844 3845 // regular expressions3846 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,3847 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,3848 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,3849 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,3850 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,3851 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,3852 3853 // Replace globs with equivalent patterns to reduce parsing time.3854 REPLACEMENTS: {3855 '***': '*',3856 '**/**': '**',3857 '**/**/**': '**'3858 },3859 3860 // Digits3861 CHAR_0: 48, /* 0 */3862 CHAR_9: 57, /* 9 */3863 3864 // Alphabet chars.3865 CHAR_UPPERCASE_A: 65, /* A */3866 CHAR_LOWERCASE_A: 97, /* a */3867 CHAR_UPPERCASE_Z: 90, /* Z */3868 CHAR_LOWERCASE_Z: 122, /* z */3869 3870 CHAR_LEFT_PARENTHESES: 40, /* ( */3871 CHAR_RIGHT_PARENTHESES: 41, /* ) */3872 3873 CHAR_ASTERISK: 42, /* * */3874 3875 // Non-alphabetic chars.3876 CHAR_AMPERSAND: 38, /* & */3877 CHAR_AT: 64, /* @ */3878 CHAR_BACKWARD_SLASH: 92, /* \ */3879 CHAR_CARRIAGE_RETURN: 13, /* \r */3880 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */3881 CHAR_COLON: 58, /* : */3882 CHAR_COMMA: 44, /* , */3883 CHAR_DOT: 46, /* . */3884 CHAR_DOUBLE_QUOTE: 34, /* " */3885 CHAR_EQUAL: 61, /* = */3886 CHAR_EXCLAMATION_MARK: 33, /* ! */3887 CHAR_FORM_FEED: 12, /* \f */3888 CHAR_FORWARD_SLASH: 47, /* / */3889 CHAR_GRAVE_ACCENT: 96, /* ` */3890 CHAR_HASH: 35, /* # */3891 CHAR_HYPHEN_MINUS: 45, /* - */3892 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */3893 CHAR_LEFT_CURLY_BRACE: 123, /* { */3894 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */3895 CHAR_LINE_FEED: 10, /* \n */3896 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */3897 CHAR_PERCENT: 37, /* % */3898 CHAR_PLUS: 43, /* + */3899 CHAR_QUESTION_MARK: 63, /* ? */3900 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */3901 CHAR_RIGHT_CURLY_BRACE: 125, /* } */3902 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */3903 CHAR_SEMICOLON: 59, /* ; */3904 CHAR_SINGLE_QUOTE: 39, /* ' */3905 CHAR_SPACE: 32, /* */3906 CHAR_TAB: 9, /* \t */3907 CHAR_UNDERSCORE: 95, /* _ */3908 CHAR_VERTICAL_LINE: 124, /* | */3909 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */3910 3911 SEP: path$1.sep,3912 3913 /**3914 * Create EXTGLOB_CHARS3915 */3916 3917 extglobChars(chars) {3918 return {3919 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },3920 '?': { type: 'qmark', open: '(?:', close: ')?' },3921 '+': { type: 'plus', open: '(?:', close: ')+' },3922 '*': { type: 'star', open: '(?:', close: ')*' },3923 '@': { type: 'at', open: '(?:', close: ')' }3924 };3925 },3926 3927 /**3928 * Create GLOB_CHARS3929 */3930 3931 globChars(win32) {3932 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;3933 }3934 };3935 3936 (function (exports) {3937 3938 const path = require$$0;3939 const win32 = process.platform === 'win32';3940 const {3941 REGEX_BACKSLASH,3942 REGEX_REMOVE_BACKSLASH,3943 REGEX_SPECIAL_CHARS,3944 REGEX_SPECIAL_CHARS_GLOBAL3945 } = constants$2;3946 3947 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);3948 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);3949 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);3950 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');3951 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');3952 3953 exports.removeBackslashes = str => {3954 return str.replace(REGEX_REMOVE_BACKSLASH, match => {3955 return match === '\\' ? '' : match;3956 });3957 };3958 3959 exports.supportsLookbehinds = () => {3960 const segs = process.version.slice(1).split('.').map(Number);3961 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {3962 return true;3963 }3964 return false;3965 };3966 3967 exports.isWindows = options => {3968 if (options && typeof options.windows === 'boolean') {3969 return options.windows;3970 }3971 return win32 === true || path.sep === '\\';3972 };3973 3974 exports.escapeLast = (input, char, lastIdx) => {3975 const idx = input.lastIndexOf(char, lastIdx);3976 if (idx === -1) return input;3977 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);3978 return `${input.slice(0, idx)}\\${input.slice(idx)}`;3979 };3980 3981 exports.removePrefix = (input, state = {}) => {3982 let output = input;3983 if (output.startsWith('./')) {3984 output = output.slice(2);3985 state.prefix = './';3986 }3987 return output;3988 };3989 3990 exports.wrapOutput = (input, state = {}, options = {}) => {3991 const prepend = options.contains ? '' : '^';3992 const append = options.contains ? '' : '$';3993 3994 let output = `${prepend}(?:${input})${append}`;3995 if (state.negated === true) {3996 output = `(?:^(?!${output}).*$)`;3997 }3998 return output;3999 };4000 } (utils$3));4001 4002 const utils$2 = utils$3;4003 const {4004 CHAR_ASTERISK, /* * */4005 CHAR_AT, /* @ */4006 CHAR_BACKWARD_SLASH, /* \ */4007 CHAR_COMMA, /* , */4008 CHAR_DOT, /* . */4009 CHAR_EXCLAMATION_MARK, /* ! */4010 CHAR_FORWARD_SLASH, /* / */4011 CHAR_LEFT_CURLY_BRACE, /* { */4012 CHAR_LEFT_PARENTHESES, /* ( */4013 CHAR_LEFT_SQUARE_BRACKET, /* [ */4014 CHAR_PLUS, /* + */4015 CHAR_QUESTION_MARK, /* ? */4016 CHAR_RIGHT_CURLY_BRACE, /* } */4017 CHAR_RIGHT_PARENTHESES, /* ) */4018 CHAR_RIGHT_SQUARE_BRACKET /* ] */4019 } = constants$2;4020 4021 const isPathSeparator = code => {4022 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;4023 };4024 4025 const depth = token => {4026 if (token.isPrefix !== true) {4027 token.depth = token.isGlobstar ? Infinity : 1;4028 }4029 };4030 4031 /**4032 * Quickly scans a glob pattern and returns an object with a handful of4033 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),4034 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not4035 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).4036 *4037 * ```js4038 * const pm = require('picomatch');4039 * console.log(pm.scan('foo/bar/*.js'));4040 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }4041 * ```4042 * @param {String} `str`4043 * @param {Object} `options`4044 * @return {Object} Returns an object with tokens and regex source string.4045 * @api public4046 */4047 4048 const scan$1 = (input, options) => {4049 const opts = options || {};4050 4051 const length = input.length - 1;4052 const scanToEnd = opts.parts === true || opts.scanToEnd === true;4053 const slashes = [];4054 const tokens = [];4055 const parts = [];4056 4057 let str = input;4058 let index = -1;4059 let start = 0;4060 let lastIndex = 0;4061 let isBrace = false;4062 let isBracket = false;4063 let isGlob = false;4064 let isExtglob = false;4065 let isGlobstar = false;4066 let braceEscaped = false;4067 let backslashes = false;4068 let negated = false;4069 let negatedExtglob = false;4070 let finished = false;4071 let braces = 0;4072 let prev;4073 let code;4074 let token = { value: '', depth: 0, isGlob: false };4075 4076 const eos = () => index >= length;4077 const peek = () => str.charCodeAt(index + 1);4078 const advance = () => {4079 prev = code;4080 return str.charCodeAt(++index);4081 };4082 4083 while (index < length) {4084 code = advance();4085 let next;4086 4087 if (code === CHAR_BACKWARD_SLASH) {4088 backslashes = token.backslashes = true;4089 code = advance();4090 4091 if (code === CHAR_LEFT_CURLY_BRACE) {4092 braceEscaped = true;4093 }4094 continue;4095 }4096 4097 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {4098 braces++;4099 4100 while (eos() !== true && (code = advance())) {4101 if (code === CHAR_BACKWARD_SLASH) {4102 backslashes = token.backslashes = true;4103 advance();4104 continue;4105 }4106 4107 if (code === CHAR_LEFT_CURLY_BRACE) {4108 braces++;4109 continue;4110 }4111 4112 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {4113 isBrace = token.isBrace = true;4114 isGlob = token.isGlob = true;4115 finished = true;4116 4117 if (scanToEnd === true) {4118 continue;4119 }4120 4121 break;4122 }4123 4124 if (braceEscaped !== true && code === CHAR_COMMA) {4125 isBrace = token.isBrace = true;4126 isGlob = token.isGlob = true;4127 finished = true;4128 4129 if (scanToEnd === true) {4130 continue;4131 }4132 4133 break;4134 }4135 4136 if (code === CHAR_RIGHT_CURLY_BRACE) {4137 braces--;4138 4139 if (braces === 0) {4140 braceEscaped = false;4141 isBrace = token.isBrace = true;4142 finished = true;4143 break;4144 }4145 }4146 }4147 4148 if (scanToEnd === true) {4149 continue;4150 }4151 4152 break;4153 }4154 4155 if (code === CHAR_FORWARD_SLASH) {4156 slashes.push(index);4157 tokens.push(token);4158 token = { value: '', depth: 0, isGlob: false };4159 4160 if (finished === true) continue;4161 if (prev === CHAR_DOT && index === (start + 1)) {4162 start += 2;4163 continue;4164 }4165 4166 lastIndex = index + 1;4167 continue;4168 }4169 4170 if (opts.noext !== true) {4171 const isExtglobChar = code === CHAR_PLUS4172 || code === CHAR_AT4173 || code === CHAR_ASTERISK4174 || code === CHAR_QUESTION_MARK4175 || code === CHAR_EXCLAMATION_MARK;4176 4177 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {4178 isGlob = token.isGlob = true;4179 isExtglob = token.isExtglob = true;4180 finished = true;4181 if (code === CHAR_EXCLAMATION_MARK && index === start) {4182 negatedExtglob = true;4183 }4184 4185 if (scanToEnd === true) {4186 while (eos() !== true && (code = advance())) {4187 if (code === CHAR_BACKWARD_SLASH) {4188 backslashes = token.backslashes = true;4189 code = advance();4190 continue;4191 }4192 4193 if (code === CHAR_RIGHT_PARENTHESES) {4194 isGlob = token.isGlob = true;4195 finished = true;4196 break;4197 }4198 }4199 continue;4200 }4201 break;4202 }4203 }4204 4205 if (code === CHAR_ASTERISK) {4206 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;4207 isGlob = token.isGlob = true;4208 finished = true;4209 4210 if (scanToEnd === true) {4211 continue;4212 }4213 break;4214 }4215 4216 if (code === CHAR_QUESTION_MARK) {4217 isGlob = token.isGlob = true;4218 finished = true;4219 4220 if (scanToEnd === true) {4221 continue;4222 }4223 break;4224 }4225 4226 if (code === CHAR_LEFT_SQUARE_BRACKET) {4227 while (eos() !== true && (next = advance())) {4228 if (next === CHAR_BACKWARD_SLASH) {4229 backslashes = token.backslashes = true;4230 advance();4231 continue;4232 }4233 4234 if (next === CHAR_RIGHT_SQUARE_BRACKET) {4235 isBracket = token.isBracket = true;4236 isGlob = token.isGlob = true;4237 finished = true;4238 break;4239 }4240 }4241 4242 if (scanToEnd === true) {4243 continue;4244 }4245 4246 break;4247 }4248 4249 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {4250 negated = token.negated = true;4251 start++;4252 continue;4253 }4254 4255 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {4256 isGlob = token.isGlob = true;4257 4258 if (scanToEnd === true) {4259 while (eos() !== true && (code = advance())) {4260 if (code === CHAR_LEFT_PARENTHESES) {4261 backslashes = token.backslashes = true;4262 code = advance();4263 continue;4264 }4265 4266 if (code === CHAR_RIGHT_PARENTHESES) {4267 finished = true;4268 break;4269 }4270 }4271 continue;4272 }4273 break;4274 }4275 4276 if (isGlob === true) {4277 finished = true;4278 4279 if (scanToEnd === true) {4280 continue;4281 }4282 4283 break;4284 }4285 }4286 4287 if (opts.noext === true) {4288 isExtglob = false;4289 isGlob = false;4290 }4291 4292 let base = str;4293 let prefix = '';4294 let glob = '';4295 4296 if (start > 0) {4297 prefix = str.slice(0, start);4298 str = str.slice(start);4299 lastIndex -= start;4300 }4301 4302 if (base && isGlob === true && lastIndex > 0) {4303 base = str.slice(0, lastIndex);4304 glob = str.slice(lastIndex);4305 } else if (isGlob === true) {4306 base = '';4307 glob = str;4308 } else {4309 base = str;4310 }4311 4312 if (base && base !== '' && base !== '/' && base !== str) {4313 if (isPathSeparator(base.charCodeAt(base.length - 1))) {4314 base = base.slice(0, -1);4315 }4316 }4317 4318 if (opts.unescape === true) {4319 if (glob) glob = utils$2.removeBackslashes(glob);4320 4321 if (base && backslashes === true) {4322 base = utils$2.removeBackslashes(base);4323 }4324 }4325 4326 const state = {4327 prefix,4328 input,4329 start,4330 base,4331 glob,4332 isBrace,4333 isBracket,4334 isGlob,4335 isExtglob,4336 isGlobstar,4337 negated,4338 negatedExtglob4339 };4340 4341 if (opts.tokens === true) {4342 state.maxDepth = 0;4343 if (!isPathSeparator(code)) {4344 tokens.push(token);4345 }4346 state.tokens = tokens;4347 }4348 4349 if (opts.parts === true || opts.tokens === true) {4350 let prevIndex;4351 4352 for (let idx = 0; idx < slashes.length; idx++) {4353 const n = prevIndex ? prevIndex + 1 : start;4354 const i = slashes[idx];4355 const value = input.slice(n, i);4356 if (opts.tokens) {4357 if (idx === 0 && start !== 0) {4358 tokens[idx].isPrefix = true;4359 tokens[idx].value = prefix;4360 } else {4361 tokens[idx].value = value;4362 }4363 depth(tokens[idx]);4364 state.maxDepth += tokens[idx].depth;4365 }4366 if (idx !== 0 || value !== '') {4367 parts.push(value);4368 }4369 prevIndex = i;4370 }4371 4372 if (prevIndex && prevIndex + 1 < input.length) {4373 const value = input.slice(prevIndex + 1);4374 parts.push(value);4375 4376 if (opts.tokens) {4377 tokens[tokens.length - 1].value = value;4378 depth(tokens[tokens.length - 1]);4379 state.maxDepth += tokens[tokens.length - 1].depth;4380 }4381 }4382 4383 state.slashes = slashes;4384 state.parts = parts;4385 }4386 4387 return state;4388 };4389 4390 var scan_1 = scan$1;4391 4392 const constants$1 = constants$2;4393 const utils$1 = utils$3;4394 4395 /**4396 * Constants4397 */4398 4399 const {4400 MAX_LENGTH,4401 POSIX_REGEX_SOURCE,4402 REGEX_NON_SPECIAL_CHARS,4403 REGEX_SPECIAL_CHARS_BACKREF,4404 REPLACEMENTS4405 } = constants$1;4406 4407 /**4408 * Helpers4409 */4410 4411 const expandRange = (args, options) => {4412 if (typeof options.expandRange === 'function') {4413 return options.expandRange(...args, options);4414 }4415 4416 args.sort();4417 const value = `[${args.join('-')}]`;4418 4419 return value;4420 };4421 4422 /**4423 * Create the message for a syntax error4424 */4425 4426 const syntaxError = (type, char) => {4427 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;4428 };4429 4430 /**4431 * Parse the given input string.4432 * @param {String} input4433 * @param {Object} options4434 * @return {Object}4435 */4436 4437 const parse$1 = (input, options) => {4438 if (typeof input !== 'string') {4439 throw new TypeError('Expected a string');4440 }4441 4442 input = REPLACEMENTS[input] || input;4443 4444 const opts = { ...options };4445 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;4446 4447 let len = input.length;4448 if (len > max) {4449 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);4450 }4451 4452 const bos = { type: 'bos', value: '', output: opts.prepend || '' };4453 const tokens = [bos];4454 4455 const capture = opts.capture ? '' : '?:';4456 const win32 = utils$1.isWindows(options);4457 4458 // create constants based on platform, for windows or posix4459 const PLATFORM_CHARS = constants$1.globChars(win32);4460 const EXTGLOB_CHARS = constants$1.extglobChars(PLATFORM_CHARS);4461 4462 const {4463 DOT_LITERAL,4464 PLUS_LITERAL,4465 SLASH_LITERAL,4466 ONE_CHAR,4467 DOTS_SLASH,4468 NO_DOT,4469 NO_DOT_SLASH,4470 NO_DOTS_SLASH,4471 QMARK,4472 QMARK_NO_DOT,4473 STAR,4474 START_ANCHOR4475 } = PLATFORM_CHARS;4476 4477 const globstar = opts => {4478 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;4479 };4480 4481 const nodot = opts.dot ? '' : NO_DOT;4482 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;4483 let star = opts.bash === true ? globstar(opts) : STAR;4484 4485 if (opts.capture) {4486 star = `(${star})`;4487 }4488 4489 // minimatch options support4490 if (typeof opts.noext === 'boolean') {4491 opts.noextglob = opts.noext;4492 }4493 4494 const state = {4495 input,4496 index: -1,4497 start: 0,4498 dot: opts.dot === true,4499 consumed: '',4500 output: '',4501 prefix: '',4502 backtrack: false,4503 negated: false,4504 brackets: 0,4505 braces: 0,4506 parens: 0,4507 quotes: 0,4508 globstar: false,4509 tokens4510 };4511 4512 input = utils$1.removePrefix(input, state);4513 len = input.length;4514 4515 const extglobs = [];4516 const braces = [];4517 const stack = [];4518 let prev = bos;4519 let value;4520 4521 /**4522 * Tokenizing helpers4523 */4524 4525 const eos = () => state.index === len - 1;4526 const peek = state.peek = (n = 1) => input[state.index + n];4527 const advance = state.advance = () => input[++state.index] || '';4528 const remaining = () => input.slice(state.index + 1);4529 const consume = (value = '', num = 0) => {4530 state.consumed += value;4531 state.index += num;4532 };4533 4534 const append = token => {4535 state.output += token.output != null ? token.output : token.value;4536 consume(token.value);4537 };4538 4539 const negate = () => {4540 let count = 1;4541 4542 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {4543 advance();4544 state.start++;4545 count++;4546 }4547 4548 if (count % 2 === 0) {4549 return false;4550 }4551 4552 state.negated = true;4553 state.start++;4554 return true;4555 };4556 4557 const increment = type => {4558 state[type]++;4559 stack.push(type);4560 };4561 4562 const decrement = type => {4563 state[type]--;4564 stack.pop();4565 };4566 4567 /**4568 * Push tokens onto the tokens array. This helper speeds up4569 * tokenizing by 1) helping us avoid backtracking as much as possible,4570 * and 2) helping us avoid creating extra tokens when consecutive4571 * characters are plain text. This improves performance and simplifies4572 * lookbehinds.4573 */4574 4575 const push = tok => {4576 if (prev.type === 'globstar') {4577 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');4578 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));4579 4580 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {4581 state.output = state.output.slice(0, -prev.output.length);4582 prev.type = 'star';4583 prev.value = '*';4584 prev.output = star;4585 state.output += prev.output;4586 }4587 }4588 4589 if (extglobs.length && tok.type !== 'paren') {4590 extglobs[extglobs.length - 1].inner += tok.value;4591 }4592 4593 if (tok.value || tok.output) append(tok);4594 if (prev && prev.type === 'text' && tok.type === 'text') {4595 prev.value += tok.value;4596 prev.output = (prev.output || '') + tok.value;4597 return;4598 }4599 4600 tok.prev = prev;4601 tokens.push(tok);4602 prev = tok;4603 };4604 4605 const extglobOpen = (type, value) => {4606 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };4607 4608 token.prev = prev;4609 token.parens = state.parens;4610 token.output = state.output;4611 const output = (opts.capture ? '(' : '') + token.open;4612 4613 increment('parens');4614 push({ type, value, output: state.output ? '' : ONE_CHAR });4615 push({ type: 'paren', extglob: true, value: advance(), output });4616 extglobs.push(token);4617 };4618 4619 const extglobClose = token => {4620 let output = token.close + (opts.capture ? ')' : '');4621 let rest;4622 4623 if (token.type === 'negate') {4624 let extglobStar = star;4625 4626 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {4627 extglobStar = globstar(opts);4628 }4629 4630 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {4631 output = token.close = `)$))${extglobStar}`;4632 }4633 4634 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {4635 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.4636 // In this case, we need to parse the string and use it in the output of the original pattern.4637 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.4638 //4639 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.4640 const expression = parse$1(rest, { ...options, fastpaths: false }).output;4641 4642 output = token.close = `)${expression})${extglobStar})`;4643 }4644 4645 if (token.prev.type === 'bos') {4646 state.negatedExtglob = true;4647 }4648 }4649 4650 push({ type: 'paren', extglob: true, value, output });4651 decrement('parens');4652 };4653 4654 /**4655 * Fast paths4656 */4657 4658 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {4659 let backslashes = false;4660 4661 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {4662 if (first === '\\') {4663 backslashes = true;4664 return m;4665 }4666 4667 if (first === '?') {4668 if (esc) {4669 return esc + first + (rest ? QMARK.repeat(rest.length) : '');4670 }4671 if (index === 0) {4672 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');4673 }4674 return QMARK.repeat(chars.length);4675 }4676 4677 if (first === '.') {4678 return DOT_LITERAL.repeat(chars.length);4679 }4680 4681 if (first === '*') {4682 if (esc) {4683 return esc + first + (rest ? star : '');4684 }4685 return star;4686 }4687 return esc ? m : `\\${m}`;4688 });4689 4690 if (backslashes === true) {4691 if (opts.unescape === true) {4692 output = output.replace(/\\/g, '');4693 } else {4694 output = output.replace(/\\+/g, m => {4695 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');4696 });4697 }4698 }4699 4700 if (output === input && opts.contains === true) {4701 state.output = input;4702 return state;4703 }4704 4705 state.output = utils$1.wrapOutput(output, state, options);4706 return state;4707 }4708 4709 /**4710 * Tokenize input until we reach end-of-string4711 */4712 4713 while (!eos()) {4714 value = advance();4715 4716 if (value === '\u0000') {4717 continue;4718 }4719 4720 /**4721 * Escaped characters4722 */4723 4724 if (value === '\\') {4725 const next = peek();4726 4727 if (next === '/' && opts.bash !== true) {4728 continue;4729 }4730 4731 if (next === '.' || next === ';') {4732 continue;4733 }4734 4735 if (!next) {4736 value += '\\';4737 push({ type: 'text', value });4738 continue;4739 }4740 4741 // collapse slashes to reduce potential for exploits4742 const match = /^\\+/.exec(remaining());4743 let slashes = 0;4744 4745 if (match && match[0].length > 2) {4746 slashes = match[0].length;4747 state.index += slashes;4748 if (slashes % 2 !== 0) {4749 value += '\\';4750 }4751 }4752 4753 if (opts.unescape === true) {4754 value = advance();4755 } else {4756 value += advance();4757 }4758 4759 if (state.brackets === 0) {4760 push({ type: 'text', value });4761 continue;4762 }4763 }4764 4765 /**4766 * If we're inside a regex character class, continue4767 * until we reach the closing bracket.4768 */4769 4770 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {4771 if (opts.posix !== false && value === ':') {4772 const inner = prev.value.slice(1);4773 if (inner.includes('[')) {4774 prev.posix = true;4775 4776 if (inner.includes(':')) {4777 const idx = prev.value.lastIndexOf('[');4778 const pre = prev.value.slice(0, idx);4779 const rest = prev.value.slice(idx + 2);4780 const posix = POSIX_REGEX_SOURCE[rest];4781 if (posix) {4782 prev.value = pre + posix;4783 state.backtrack = true;4784 advance();4785 4786 if (!bos.output && tokens.indexOf(prev) === 1) {4787 bos.output = ONE_CHAR;4788 }4789 continue;4790 }4791 }4792 }4793 }4794 4795 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {4796 value = `\\${value}`;4797 }4798 4799 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {4800 value = `\\${value}`;4801 }4802 4803 if (opts.posix === true && value === '!' && prev.value === '[') {4804 value = '^';4805 }4806 4807 prev.value += value;4808 append({ value });4809 continue;4810 }4811 4812 /**4813 * If we're inside a quoted string, continue4814 * until we reach the closing double quote.4815 */4816 4817 if (state.quotes === 1 && value !== '"') {4818 value = utils$1.escapeRegex(value);4819 prev.value += value;4820 append({ value });4821 continue;4822 }4823 4824 /**4825 * Double quotes4826 */4827 4828 if (value === '"') {4829 state.quotes = state.quotes === 1 ? 0 : 1;4830 if (opts.keepQuotes === true) {4831 push({ type: 'text', value });4832 }4833 continue;4834 }4835 4836 /**4837 * Parentheses4838 */4839 4840 if (value === '(') {4841 increment('parens');4842 push({ type: 'paren', value });4843 continue;4844 }4845 4846 if (value === ')') {4847 if (state.parens === 0 && opts.strictBrackets === true) {4848 throw new SyntaxError(syntaxError('opening', '('));4849 }4850 4851 const extglob = extglobs[extglobs.length - 1];4852 if (extglob && state.parens === extglob.parens + 1) {4853 extglobClose(extglobs.pop());4854 continue;4855 }4856 4857 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });4858 decrement('parens');4859 continue;4860 }4861 4862 /**4863 * Square brackets4864 */4865 4866 if (value === '[') {4867 if (opts.nobracket === true || !remaining().includes(']')) {4868 if (opts.nobracket !== true && opts.strictBrackets === true) {4869 throw new SyntaxError(syntaxError('closing', ']'));4870 }4871 4872 value = `\\${value}`;4873 } else {4874 increment('brackets');4875 }4876 4877 push({ type: 'bracket', value });4878 continue;4879 }4880 4881 if (value === ']') {4882 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {4883 push({ type: 'text', value, output: `\\${value}` });4884 continue;4885 }4886 4887 if (state.brackets === 0) {4888 if (opts.strictBrackets === true) {4889 throw new SyntaxError(syntaxError('opening', '['));4890 }4891 4892 push({ type: 'text', value, output: `\\${value}` });4893 continue;4894 }4895 4896 decrement('brackets');4897 4898 const prevValue = prev.value.slice(1);4899 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {4900 value = `/${value}`;4901 }4902 4903 prev.value += value;4904 append({ value });4905 4906 // when literal brackets are explicitly disabled4907 // assume we should match with a regex character class4908 if (opts.literalBrackets === false || utils$1.hasRegexChars(prevValue)) {4909 continue;4910 }4911 4912 const escaped = utils$1.escapeRegex(prev.value);4913 state.output = state.output.slice(0, -prev.value.length);4914 4915 // when literal brackets are explicitly enabled4916 // assume we should escape the brackets to match literal characters4917 if (opts.literalBrackets === true) {4918 state.output += escaped;4919 prev.value = escaped;4920 continue;4921 }4922 4923 // when the user specifies nothing, try to match both4924 prev.value = `(${capture}${escaped}|${prev.value})`;4925 state.output += prev.value;4926 continue;4927 }4928 4929 /**4930 * Braces4931 */4932 4933 if (value === '{' && opts.nobrace !== true) {4934 increment('braces');4935 4936 const open = {4937 type: 'brace',4938 value,4939 output: '(',4940 outputIndex: state.output.length,4941 tokensIndex: state.tokens.length4942 };4943 4944 braces.push(open);4945 push(open);4946 continue;4947 }4948 4949 if (value === '}') {4950 const brace = braces[braces.length - 1];4951 4952 if (opts.nobrace === true || !brace) {4953 push({ type: 'text', value, output: value });4954 continue;4955 }4956 4957 let output = ')';4958 4959 if (brace.dots === true) {4960 const arr = tokens.slice();4961 const range = [];4962 4963 for (let i = arr.length - 1; i >= 0; i--) {4964 tokens.pop();4965 if (arr[i].type === 'brace') {4966 break;4967 }4968 if (arr[i].type !== 'dots') {4969 range.unshift(arr[i].value);4970 }4971 }4972 4973 output = expandRange(range, opts);4974 state.backtrack = true;4975 }4976 4977 if (brace.comma !== true && brace.dots !== true) {4978 const out = state.output.slice(0, brace.outputIndex);4979 const toks = state.tokens.slice(brace.tokensIndex);4980 brace.value = brace.output = '\\{';4981 value = output = '\\}';4982 state.output = out;4983 for (const t of toks) {4984 state.output += (t.output || t.value);4985 }4986 }4987 4988 push({ type: 'brace', value, output });4989 decrement('braces');4990 braces.pop();4991 continue;4992 }4993 4994 /**4995 * Pipes4996 */4997 4998 if (value === '|') {4999 if (extglobs.length > 0) {5000 extglobs[extglobs.length - 1].conditions++;5001 }5002 push({ type: 'text', value });5003 continue;5004 }5005 5006 /**5007 * Commas5008 */5009 5010 if (value === ',') {5011 let output = value;5012 5013 const brace = braces[braces.length - 1];5014 if (brace && stack[stack.length - 1] === 'braces') {5015 brace.comma = true;5016 output = '|';5017 }5018 5019 push({ type: 'comma', value, output });5020 continue;5021 }5022 5023 /**5024 * Slashes5025 */5026 5027 if (value === '/') {5028 // if the beginning of the glob is "./", advance the start5029 // to the current index, and don't add the "./" characters5030 // to the state. This greatly simplifies lookbehinds when5031 // checking for BOS characters like "!" and "." (not "./")5032 if (prev.type === 'dot' && state.index === state.start + 1) {5033 state.start = state.index + 1;5034 state.consumed = '';5035 state.output = '';5036 tokens.pop();5037 prev = bos; // reset "prev" to the first token5038 continue;5039 }5040 5041 push({ type: 'slash', value, output: SLASH_LITERAL });5042 continue;5043 }5044 5045 /**5046 * Dots5047 */5048 5049 if (value === '.') {5050 if (state.braces > 0 && prev.type === 'dot') {5051 if (prev.value === '.') prev.output = DOT_LITERAL;5052 const brace = braces[braces.length - 1];5053 prev.type = 'dots';5054 prev.output += value;5055 prev.value += value;5056 brace.dots = true;5057 continue;5058 }5059 5060 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {5061 push({ type: 'text', value, output: DOT_LITERAL });5062 continue;5063 }5064 5065 push({ type: 'dot', value, output: DOT_LITERAL });5066 continue;5067 }5068 5069 /**5070 * Question marks5071 */5072 5073 if (value === '?') {5074 const isGroup = prev && prev.value === '(';5075 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {5076 extglobOpen('qmark', value);5077 continue;5078 }5079 5080 if (prev && prev.type === 'paren') {5081 const next = peek();5082 let output = value;5083 5084 if (next === '<' && !utils$1.supportsLookbehinds()) {5085 throw new Error('Node.js v10 or higher is required for regex lookbehinds');5086 }5087 5088 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {5089 output = `\\${value}`;5090 }5091 5092 push({ type: 'text', value, output });5093 continue;5094 }5095 5096 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {5097 push({ type: 'qmark', value, output: QMARK_NO_DOT });5098 continue;5099 }5100 5101 push({ type: 'qmark', value, output: QMARK });5102 continue;5103 }5104 5105 /**5106 * Exclamation5107 */5108 5109 if (value === '!') {5110 if (opts.noextglob !== true && peek() === '(') {5111 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {5112 extglobOpen('negate', value);5113 continue;5114 }5115 }5116 5117 if (opts.nonegate !== true && state.index === 0) {5118 negate();5119 continue;5120 }5121 }5122 5123 /**5124 * Plus5125 */5126 5127 if (value === '+') {5128 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {5129 extglobOpen('plus', value);5130 continue;5131 }5132 5133 if ((prev && prev.value === '(') || opts.regex === false) {5134 push({ type: 'plus', value, output: PLUS_LITERAL });5135 continue;5136 }5137 5138 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {5139 push({ type: 'plus', value });5140 continue;5141 }5142 5143 push({ type: 'plus', value: PLUS_LITERAL });5144 continue;5145 }5146 5147 /**5148 * Plain text5149 */5150 5151 if (value === '@') {5152 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {5153 push({ type: 'at', extglob: true, value, output: '' });5154 continue;5155 }5156 5157 push({ type: 'text', value });5158 continue;5159 }5160 5161 /**5162 * Plain text5163 */5164 5165 if (value !== '*') {5166 if (value === '$' || value === '^') {5167 value = `\\${value}`;5168 }5169 5170 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());5171 if (match) {5172 value += match[0];5173 state.index += match[0].length;5174 }5175 5176 push({ type: 'text', value });5177 continue;5178 }5179 5180 /**5181 * Stars5182 */5183 5184 if (prev && (prev.type === 'globstar' || prev.star === true)) {5185 prev.type = 'star';5186 prev.star = true;5187 prev.value += value;5188 prev.output = star;5189 state.backtrack = true;5190 state.globstar = true;5191 consume(value);5192 continue;5193 }5194 5195 let rest = remaining();5196 if (opts.noextglob !== true && /^\([^?]/.test(rest)) {5197 extglobOpen('star', value);5198 continue;5199 }5200 5201 if (prev.type === 'star') {5202 if (opts.noglobstar === true) {5203 consume(value);5204 continue;5205 }5206 5207 const prior = prev.prev;5208 const before = prior.prev;5209 const isStart = prior.type === 'slash' || prior.type === 'bos';5210 const afterStar = before && (before.type === 'star' || before.type === 'globstar');5211 5212 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {5213 push({ type: 'star', value, output: '' });5214 continue;5215 }5216 5217 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');5218 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');5219 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {5220 push({ type: 'star', value, output: '' });5221 continue;5222 }5223 5224 // strip consecutive `/**/`5225 while (rest.slice(0, 3) === '/**') {5226 const after = input[state.index + 4];5227 if (after && after !== '/') {5228 break;5229 }5230 rest = rest.slice(3);5231 consume('/**', 3);5232 }5233 5234 if (prior.type === 'bos' && eos()) {5235 prev.type = 'globstar';5236 prev.value += value;5237 prev.output = globstar(opts);5238 state.output = prev.output;5239 state.globstar = true;5240 consume(value);5241 continue;5242 }5243 5244 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {5245 state.output = state.output.slice(0, -(prior.output + prev.output).length);5246 prior.output = `(?:${prior.output}`;5247 5248 prev.type = 'globstar';5249 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');5250 prev.value += value;5251 state.globstar = true;5252 state.output += prior.output + prev.output;5253 consume(value);5254 continue;5255 }5256 5257 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {5258 const end = rest[1] !== void 0 ? '|$' : '';5259 5260 state.output = state.output.slice(0, -(prior.output + prev.output).length);5261 prior.output = `(?:${prior.output}`;5262 5263 prev.type = 'globstar';5264 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;5265 prev.value += value;5266 5267 state.output += prior.output + prev.output;5268 state.globstar = true;5269 5270 consume(value + advance());5271 5272 push({ type: 'slash', value: '/', output: '' });5273 continue;5274 }5275 5276 if (prior.type === 'bos' && rest[0] === '/') {5277 prev.type = 'globstar';5278 prev.value += value;5279 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;5280 state.output = prev.output;5281 state.globstar = true;5282 consume(value + advance());5283 push({ type: 'slash', value: '/', output: '' });5284 continue;5285 }5286 5287 // remove single star from output5288 state.output = state.output.slice(0, -prev.output.length);5289 5290 // reset previous token to globstar5291 prev.type = 'globstar';5292 prev.output = globstar(opts);5293 prev.value += value;5294 5295 // reset output with globstar5296 state.output += prev.output;5297 state.globstar = true;5298 consume(value);5299 continue;5300 }5301 5302 const token = { type: 'star', value, output: star };5303 5304 if (opts.bash === true) {5305 token.output = '.*?';5306 if (prev.type === 'bos' || prev.type === 'slash') {5307 token.output = nodot + token.output;5308 }5309 push(token);5310 continue;5311 }5312 5313 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {5314 token.output = value;5315 push(token);5316 continue;5317 }5318 5319 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {5320 if (prev.type === 'dot') {5321 state.output += NO_DOT_SLASH;5322 prev.output += NO_DOT_SLASH;5323 5324 } else if (opts.dot === true) {5325 state.output += NO_DOTS_SLASH;5326 prev.output += NO_DOTS_SLASH;5327 5328 } else {5329 state.output += nodot;5330 prev.output += nodot;5331 }5332 5333 if (peek() !== '*') {5334 state.output += ONE_CHAR;5335 prev.output += ONE_CHAR;5336 }5337 }5338 5339 push(token);5340 }5341 5342 while (state.brackets > 0) {5343 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));5344 state.output = utils$1.escapeLast(state.output, '[');5345 decrement('brackets');5346 }5347 5348 while (state.parens > 0) {5349 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));5350 state.output = utils$1.escapeLast(state.output, '(');5351 decrement('parens');5352 }5353 5354 while (state.braces > 0) {5355 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));5356 state.output = utils$1.escapeLast(state.output, '{');5357 decrement('braces');5358 }5359 5360 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {5361 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });5362 }5363 5364 // rebuild the output if we had to backtrack at any point5365 if (state.backtrack === true) {5366 state.output = '';5367 5368 for (const token of state.tokens) {5369 state.output += token.output != null ? token.output : token.value;5370 5371 if (token.suffix) {5372 state.output += token.suffix;5373 }5374 }5375 }5376 5377 return state;5378 };5379 5380 /**5381 * Fast paths for creating regular expressions for common glob patterns.5382 * This can significantly speed up processing and has very little downside5383 * impact when none of the fast paths match.5384 */5385 5386 parse$1.fastpaths = (input, options) => {5387 const opts = { ...options };5388 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;5389 const len = input.length;5390 if (len > max) {5391 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);5392 }5393 5394 input = REPLACEMENTS[input] || input;5395 const win32 = utils$1.isWindows(options);5396 5397 // create constants based on platform, for windows or posix5398 const {5399 DOT_LITERAL,5400 SLASH_LITERAL,5401 ONE_CHAR,5402 DOTS_SLASH,5403 NO_DOT,5404 NO_DOTS,5405 NO_DOTS_SLASH,5406 STAR,5407 START_ANCHOR5408 } = constants$1.globChars(win32);5409 5410 const nodot = opts.dot ? NO_DOTS : NO_DOT;5411 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;5412 const capture = opts.capture ? '' : '?:';5413 const state = { negated: false, prefix: '' };5414 let star = opts.bash === true ? '.*?' : STAR;5415 5416 if (opts.capture) {5417 star = `(${star})`;5418 }5419 5420 const globstar = opts => {5421 if (opts.noglobstar === true) return star;5422 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;5423 };5424 5425 const create = str => {5426 switch (str) {5427 case '*':5428 return `${nodot}${ONE_CHAR}${star}`;5429 5430 case '.*':5431 return `${DOT_LITERAL}${ONE_CHAR}${star}`;5432 5433 case '*.*':5434 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;5435 5436 case '*/*':5437 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;5438 5439 case '**':5440 return nodot + globstar(opts);5441 5442 case '**/*':5443 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;5444 5445 case '**/*.*':5446 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;5447 5448 case '**/.*':5449 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;5450 5451 default: {5452 const match = /^(.*?)\.(\w+)$/.exec(str);5453 if (!match) return;5454 5455 const source = create(match[1]);5456 if (!source) return;5457 5458 return source + DOT_LITERAL + match[2];5459 }5460 }5461 };5462 5463 const output = utils$1.removePrefix(input, state);5464 let source = create(output);5465 5466 if (source && opts.strictSlashes !== true) {5467 source += `${SLASH_LITERAL}?`;5468 }5469 5470 return source;5471 };5472 5473 var parse_1 = parse$1;5474 5475 const path = require$$0;5476 const scan = scan_1;5477 const parse = parse_1;5478 const utils = utils$3;5479 const constants = constants$2;5480 const isObject = val => val && typeof val === 'object' && !Array.isArray(val);5481 5482 /**5483 * Creates a matcher function from one or more glob patterns. The5484 * returned function takes a string to match as its first argument,5485 * and returns true if the string is a match. The returned matcher5486 * function also takes a boolean as the second argument that, when true,5487 * returns an object with additional information.5488 *5489 * ```js5490 * const picomatch = require('picomatch');5491 * // picomatch(glob[, options]);5492 *5493 * const isMatch = picomatch('*.!(*a)');5494 * console.log(isMatch('a.a')); //=> false5495 * console.log(isMatch('a.b')); //=> true5496 * ```5497 * @name picomatch5498 * @param {String|Array} `globs` One or more glob patterns.5499 * @param {Object=} `options`5500 * @return {Function=} Returns a matcher function.5501 * @api public5502 */5503 5504 const picomatch$1 = (glob, options, returnState = false) => {5505 if (Array.isArray(glob)) {5506 const fns = glob.map(input => picomatch$1(input, options, returnState));5507 const arrayMatcher = str => {5508 for (const isMatch of fns) {5509 const state = isMatch(str);5510 if (state) return state;5511 }5512 return false;5513 };5514 return arrayMatcher;5515 }5516 5517 const isState = isObject(glob) && glob.tokens && glob.input;5518 5519 if (glob === '' || (typeof glob !== 'string' && !isState)) {5520 throw new TypeError('Expected pattern to be a non-empty string');5521 }5522 5523 const opts = options || {};5524 const posix = utils.isWindows(options);5525 const regex = isState5526 ? picomatch$1.compileRe(glob, options)5527 : picomatch$1.makeRe(glob, options, false, true);5528 5529 const state = regex.state;5530 delete regex.state;5531 5532 let isIgnored = () => false;5533 if (opts.ignore) {5534 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };5535 isIgnored = picomatch$1(opts.ignore, ignoreOpts, returnState);5536 }5537 5538 const matcher = (input, returnObject = false) => {5539 const { isMatch, match, output } = picomatch$1.test(input, regex, options, { glob, posix });5540 const result = { glob, state, regex, posix, input, output, match, isMatch };5541 5542 if (typeof opts.onResult === 'function') {5543 opts.onResult(result);5544 }5545 5546 if (isMatch === false) {5547 result.isMatch = false;5548 return returnObject ? result : false;5549 }5550 5551 if (isIgnored(input)) {5552 if (typeof opts.onIgnore === 'function') {5553 opts.onIgnore(result);5554 }5555 result.isMatch = false;5556 return returnObject ? result : false;5557 }5558 5559 if (typeof opts.onMatch === 'function') {5560 opts.onMatch(result);5561 }5562 return returnObject ? result : true;5563 };5564 5565 if (returnState) {5566 matcher.state = state;5567 }5568 5569 return matcher;5570 };5571 5572 /**5573 * Test `input` with the given `regex`. This is used by the main5574 * `picomatch()` function to test the input string.5575 *5576 * ```js5577 * const picomatch = require('picomatch');5578 * // picomatch.test(input, regex[, options]);5579 *5580 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));5581 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }5582 * ```5583 * @param {String} `input` String to test.5584 * @param {RegExp} `regex`5585 * @return {Object} Returns an object with matching info.5586 * @api public5587 */5588 5589 picomatch$1.test = (input, regex, options, { glob, posix } = {}) => {5590 if (typeof input !== 'string') {5591 throw new TypeError('Expected input to be a string');5592 }5593 5594 if (input === '') {5595 return { isMatch: false, output: '' };5596 }5597 5598 const opts = options || {};5599 const format = opts.format || (posix ? utils.toPosixSlashes : null);5600 let match = input === glob;5601 let output = (match && format) ? format(input) : input;5602 5603 if (match === false) {5604 output = format ? format(input) : input;5605 match = output === glob;5606 }5607 5608 if (match === false || opts.capture === true) {5609 if (opts.matchBase === true || opts.basename === true) {5610 match = picomatch$1.matchBase(input, regex, options, posix);5611 } else {5612 match = regex.exec(output);5613 }5614 }5615 5616 return { isMatch: Boolean(match), match, output };5617 };5618 5619 /**5620 * Match the basename of a filepath.5621 *5622 * ```js5623 * const picomatch = require('picomatch');5624 * // picomatch.matchBase(input, glob[, options]);5625 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true5626 * ```5627 * @param {String} `input` String to test.5628 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).5629 * @return {Boolean}5630 * @api public5631 */5632 5633 picomatch$1.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {5634 const regex = glob instanceof RegExp ? glob : picomatch$1.makeRe(glob, options);5635 return regex.test(path.basename(input));5636 };5637 5638 /**5639 * Returns true if **any** of the given glob `patterns` match the specified `string`.5640 *5641 * ```js5642 * const picomatch = require('picomatch');5643 * // picomatch.isMatch(string, patterns[, options]);5644 *5645 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true5646 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false5647 * ```5648 * @param {String|Array} str The string to test.5649 * @param {String|Array} patterns One or more glob patterns to use for matching.5650 * @param {Object} [options] See available [options](#options).5651 * @return {Boolean} Returns true if any patterns match `str`5652 * @api public5653 */5654 5655 picomatch$1.isMatch = (str, patterns, options) => picomatch$1(patterns, options)(str);5656 5657 /**5658 * Parse a glob pattern to create the source string for a regular5659 * expression.5660 *5661 * ```js5662 * const picomatch = require('picomatch');5663 * const result = picomatch.parse(pattern[, options]);5664 * ```5665 * @param {String} `pattern`5666 * @param {Object} `options`5667 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.5668 * @api public5669 */5670 5671 picomatch$1.parse = (pattern, options) => {5672 if (Array.isArray(pattern)) return pattern.map(p => picomatch$1.parse(p, options));5673 return parse(pattern, { ...options, fastpaths: false });5674 };5675 5676 /**5677 * Scan a glob pattern to separate the pattern into segments.5678 *5679 * ```js5680 * const picomatch = require('picomatch');5681 * // picomatch.scan(input[, options]);5682 *5683 * const result = picomatch.scan('!./foo/*.js');5684 * console.log(result);5685 * { prefix: '!./',5686 * input: '!./foo/*.js',5687 * start: 3,5688 * base: 'foo',5689 * glob: '*.js',5690 * isBrace: false,5691 * isBracket: false,5692 * isGlob: true,5693 * isExtglob: false,5694 * isGlobstar: false,5695 * negated: true }5696 * ```5697 * @param {String} `input` Glob pattern to scan.5698 * @param {Object} `options`5699 * @return {Object} Returns an object with5700 * @api public5701 */5702 5703 picomatch$1.scan = (input, options) => scan(input, options);5704 5705 /**5706 * Compile a regular expression from the `state` object returned by the5707 * [parse()](#parse) method.5708 *5709 * @param {Object} `state`5710 * @param {Object} `options`5711 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.5712 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.5713 * @return {RegExp}5714 * @api public5715 */5716 5717 picomatch$1.compileRe = (state, options, returnOutput = false, returnState = false) => {5718 if (returnOutput === true) {5719 return state.output;5720 }5721 5722 const opts = options || {};5723 const prepend = opts.contains ? '' : '^';5724 const append = opts.contains ? '' : '$';5725 5726 let source = `${prepend}(?:${state.output})${append}`;5727 if (state && state.negated === true) {5728 source = `^(?!${source}).*$`;5729 }5730 5731 const regex = picomatch$1.toRegex(source, options);5732 if (returnState === true) {5733 regex.state = state;5734 }5735 5736 return regex;5737 };5738 5739 /**5740 * Create a regular expression from a parsed glob pattern.5741 *5742 * ```js5743 * const picomatch = require('picomatch');5744 * const state = picomatch.parse('*.js');5745 * // picomatch.compileRe(state[, options]);5746 *5747 * console.log(picomatch.compileRe(state));5748 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/5749 * ```5750 * @param {String} `state` The object returned from the `.parse` method.5751 * @param {Object} `options`5752 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result.5753 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.5754 * @return {RegExp} Returns a regex created from the given pattern.5755 * @api public5756 */5757 5758 picomatch$1.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {5759 if (!input || typeof input !== 'string') {5760 throw new TypeError('Expected a non-empty string');5761 }5762 5763 let parsed = { negated: false, fastpaths: true };5764 5765 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {5766 parsed.output = parse.fastpaths(input, options);5767 }5768 5769 if (!parsed.output) {5770 parsed = parse(input, options);5771 }5772 5773 return picomatch$1.compileRe(parsed, options, returnOutput, returnState);5774 };5775 5776 /**5777 * Create a regular expression from the given regex source string.5778 *5779 * ```js5780 * const picomatch = require('picomatch');5781 * // picomatch.toRegex(source[, options]);5782 *5783 * const { output } = picomatch.parse('*.js');5784 * console.log(picomatch.toRegex(output));5785 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/5786 * ```5787 * @param {String} `source` Regular expression source string.5788 * @param {Object} `options`5789 * @return {RegExp}5790 * @api public5791 */5792 5793 picomatch$1.toRegex = (source, options) => {5794 try {5795 const opts = options || {};5796 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));5797 } catch (err) {5798 if (options && options.debug === true) throw err;5799 return /$^/;5800 }5801 };5802 5803 /**5804 * Picomatch constants.5805 * @return {Object}5806 */5807 5808 picomatch$1.constants = constants;5809 5810 /**5811 * Expose "picomatch"5812 */5813 5814 var picomatch_1 = picomatch$1;5815 5816 var picomatch = picomatch_1;5817 5818 const pm = /*@__PURE__*/getDefaultExportFromCjs(picomatch);5819 5820 const extractors = {5821 ArrayPattern(names, param) {5822 for (const element of param.elements) {5823 if (element)5824 extractors[element.type](names, element);5825 }5826 },5827 AssignmentPattern(names, param) {5828 extractors[param.left.type](names, param.left);5829 },5830 Identifier(names, param) {5831 names.push(param.name);5832 },5833 MemberExpression() { },5834 ObjectPattern(names, param) {5835 for (const prop of param.properties) {5836 // @ts-ignore Typescript reports that this is not a valid type5837 if (prop.type === 'RestElement') {5838 extractors.RestElement(names, prop);5839 }5840 else {5841 extractors[prop.value.type](names, prop.value);5842 }5843 }5844 },5845 RestElement(names, param) {5846 extractors[param.argument.type](names, param.argument);5847 }5848 };5849 const extractAssignedNames = function extractAssignedNames(param) {5850 const names = [];5851 extractors[param.type](names, param);5852 return names;5853 };5854 5855 // Helper since Typescript can't detect readonly arrays with Array.isArray5856 function isArray(arg) {5857 return Array.isArray(arg);5858 }5859 function ensureArray(thing) {5860 if (isArray(thing))5861 return thing;5862 if (thing == null)5863 return [];5864 return [thing];5865 }5866 5867 const normalizePath = function normalizePath(filename) {5868 return filename.split(require$$0.win32.sep).join(require$$0.posix.sep);5869 };5870 5871 function getMatcherString(id, resolutionBase) {5872 if (resolutionBase === false || require$$0.isAbsolute(id) || id.startsWith('**')) {5873 return normalizePath(id);5874 }5875 // resolve('') is valid and will default to process.cwd()5876 const basePath = normalizePath(require$$0.resolve(resolutionBase || ''))5877 // escape all possible (posix + win) path characters that might interfere with regex5878 .replace(/[-^$*+?.()|[\]{}]/g, '\\$&');5879 // Note that we use posix.join because:5880 // 1. the basePath has been normalized to use /5881 // 2. the incoming glob (id) matcher, also uses /5882 // otherwise Node will force backslash (\) on windows5883 return require$$0.posix.join(basePath, normalizePath(id));5884 }5885 const createFilter = function createFilter(include, exclude, options) {5886 const resolutionBase = options && options.resolve;5887 const getMatcher = (id) => id instanceof RegExp5888 ? id5889 : {5890 test: (what) => {5891 // this refactor is a tad overly verbose but makes for easy debugging5892 const pattern = getMatcherString(id, resolutionBase);5893 const fn = pm(pattern, { dot: true });5894 const result = fn(what);5895 return result;5896 }5897 };5898 const includeMatchers = ensureArray(include).map(getMatcher);5899 const excludeMatchers = ensureArray(exclude).map(getMatcher);5900 return function result(id) {5901 if (typeof id !== 'string')5902 return false;5903 if (/\0/.test(id))5904 return false;5905 const pathId = normalizePath(id);5906 for (let i = 0; i < excludeMatchers.length; ++i) {5907 const matcher = excludeMatchers[i];5908 if (matcher.test(pathId))5909 return false;5910 }5911 for (let i = 0; i < includeMatchers.length; ++i) {5912 const matcher = includeMatchers[i];5913 if (matcher.test(pathId))5914 return true;5915 }5916 return !includeMatchers.length;5917 };5918 };5919 5920 const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';5921 const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';5922 const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));5923 forbiddenIdentifiers.add('');5924 4147 5925 4148 function createInclusionContext() { … … 5951 4174 replacedVariableInits: new Map() 5952 4175 }; 4176 } 4177 4178 const INCLUDE_PARAMETERS = 'variables'; 4179 const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN'); 4180 class NodeBase extends ExpressionEntity { 4181 /** 4182 * Nodes can apply custom deoptimizations once they become part of the 4183 * executed code. To do this, they must initialize this as false, implement 4184 * applyDeoptimizations and call this from include and hasEffects if they have 4185 * custom handlers 4186 */ 4187 get deoptimized() { 4188 return isFlagSet(this.flags, 2 /* Flag.deoptimized */); 4189 } 4190 set deoptimized(value) { 4191 this.flags = setFlag(this.flags, 2 /* Flag.deoptimized */, value); 4192 } 4193 constructor(parent, parentScope) { 4194 super(); 4195 this.parent = parent; 4196 this.scope = parentScope; 4197 this.createScope(parentScope); 4198 } 4199 addExportedVariables(_variables, _exportNamesByVariable) { } 4200 /** 4201 * Override this to bind assignments to variables and do any initialisations 4202 * that require the scopes to be populated with variables. 4203 */ 4204 bind() { 4205 for (const key of childNodeKeys[this.type]) { 4206 const value = this[key]; 4207 if (Array.isArray(value)) { 4208 for (const child of value) { 4209 child?.bind(); 4210 } 4211 } 4212 else if (value) { 4213 value.bind(); 4214 } 4215 } 4216 } 4217 /** 4218 * Override if this node should receive a different scope than the parent 4219 * scope. 4220 */ 4221 createScope(parentScope) { 4222 this.scope = parentScope; 4223 } 4224 hasEffects(context) { 4225 if (!this.deoptimized) 4226 this.applyDeoptimizations(); 4227 for (const key of childNodeKeys[this.type]) { 4228 const value = this[key]; 4229 if (value === null) 4230 continue; 4231 if (Array.isArray(value)) { 4232 for (const child of value) { 4233 if (child?.hasEffects(context)) 4234 return true; 4235 } 4236 } 4237 else if (value.hasEffects(context)) 4238 return true; 4239 } 4240 return false; 4241 } 4242 hasEffectsAsAssignmentTarget(context, _checkAccess) { 4243 return (this.hasEffects(context) || 4244 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context)); 4245 } 4246 include(context, includeChildrenRecursively, _options) { 4247 if (!this.deoptimized) 4248 this.applyDeoptimizations(); 4249 this.included = true; 4250 for (const key of childNodeKeys[this.type]) { 4251 const value = this[key]; 4252 if (value === null) 4253 continue; 4254 if (Array.isArray(value)) { 4255 for (const child of value) { 4256 child?.include(context, includeChildrenRecursively); 4257 } 4258 } 4259 else { 4260 value.include(context, includeChildrenRecursively); 4261 } 4262 } 4263 } 4264 includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) { 4265 this.include(context, includeChildrenRecursively); 4266 } 4267 /** 4268 * Override to perform special initialisation steps after the scope is 4269 * initialised 4270 */ 4271 initialise() { 4272 this.scope.context.magicString.addSourcemapLocation(this.start); 4273 this.scope.context.magicString.addSourcemapLocation(this.end); 4274 } 4275 parseNode(esTreeNode) { 4276 for (const [key, value] of Object.entries(esTreeNode)) { 4277 // Skip properties defined on the class already. 4278 // This way, we can override this function to add custom initialisation and then call super.parseNode 4279 // Note: this doesn't skip properties with defined getters/setters which we use to pack wrap booleans 4280 // in bitfields. Those are still assigned from the value in the esTreeNode. 4281 if (this.hasOwnProperty(key)) 4282 continue; 4283 if (key.charCodeAt(0) === 95 /* _ */) { 4284 if (key === parseAst_js.ANNOTATION_KEY) { 4285 this.annotations = value; 4286 } 4287 else if (key === parseAst_js.INVALID_ANNOTATION_KEY) { 4288 this.invalidAnnotations = value; 4289 } 4290 } 4291 else if (typeof value !== 'object' || value === null) { 4292 this[key] = value; 4293 } 4294 else if (Array.isArray(value)) { 4295 this[key] = new Array(value.length); 4296 let index = 0; 4297 for (const child of value) { 4298 this[key][index++] = 4299 child === null 4300 ? null 4301 : new (this.scope.context.getNodeConstructor(child.type))(this, this.scope).parseNode(child); 4302 } 4303 } 4304 else { 4305 this[key] = new (this.scope.context.getNodeConstructor(value.type))(this, this.scope).parseNode(value); 4306 } 4307 } 4308 // extend child keys for unknown node types 4309 childNodeKeys[esTreeNode.type] ||= createChildNodeKeysForNode(esTreeNode); 4310 this.initialise(); 4311 return this; 4312 } 4313 removeAnnotations(code) { 4314 if (this.annotations) { 4315 for (const annotation of this.annotations) { 4316 code.remove(annotation.start, annotation.end); 4317 } 4318 } 4319 } 4320 render(code, options) { 4321 for (const key of childNodeKeys[this.type]) { 4322 const value = this[key]; 4323 if (value === null) 4324 continue; 4325 if (Array.isArray(value)) { 4326 for (const child of value) { 4327 child?.render(code, options); 4328 } 4329 } 4330 else { 4331 value.render(code, options); 4332 } 4333 } 4334 } 4335 setAssignedValue(value) { 4336 this.assignmentInteraction = { args: [null, value], type: INTERACTION_ASSIGNED }; 4337 } 4338 shouldBeIncluded(context) { 4339 return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext())); 4340 } 4341 /** 4342 * Just deoptimize everything by default so that when e.g. we do not track 4343 * something properly, it is deoptimized. 4344 * @protected 4345 */ 4346 applyDeoptimizations() { 4347 this.deoptimized = true; 4348 for (const key of childNodeKeys[this.type]) { 4349 const value = this[key]; 4350 if (value === null) 4351 continue; 4352 if (Array.isArray(value)) { 4353 for (const child of value) { 4354 child?.deoptimizePath(UNKNOWN_PATH); 4355 } 4356 } 4357 else { 4358 value.deoptimizePath(UNKNOWN_PATH); 4359 } 4360 } 4361 this.scope.context.requestTreeshakingPass(); 4362 } 4363 } 4364 function createChildNodeKeysForNode(esTreeNode) { 4365 return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */); 4366 } 4367 4368 function isObjectExpressionNode(node) { 4369 return node instanceof NodeBase && node.type === parseAst_js.ObjectExpression; 4370 } 4371 function isPropertyNode(node) { 4372 return node.type === parseAst_js.Property; 5953 4373 } 5954 4374 … … 6155 4575 } 6156 4576 6157 // This file is generated by scripts/generate-child-node-keys.js.6158 // Do not edit this file directly.6159 const childNodeKeys = {6160 ArrayExpression: ['elements'],6161 ArrayPattern: ['elements'],6162 ArrowFunctionExpression: ['params', 'body'],6163 AssignmentExpression: ['left', 'right'],6164 AssignmentPattern: ['left', 'right'],6165 AwaitExpression: ['argument'],6166 BinaryExpression: ['left', 'right'],6167 BlockStatement: ['body'],6168 BreakStatement: ['label'],6169 CallExpression: ['callee', 'arguments'],6170 CatchClause: ['param', 'body'],6171 ChainExpression: ['expression'],6172 ClassBody: ['body'],6173 ClassDeclaration: ['decorators', 'id', 'superClass', 'body'],6174 ClassExpression: ['decorators', 'id', 'superClass', 'body'],6175 ConditionalExpression: ['test', 'consequent', 'alternate'],6176 ContinueStatement: ['label'],6177 DebuggerStatement: [],6178 Decorator: ['expression'],6179 DoWhileStatement: ['body', 'test'],6180 EmptyStatement: [],6181 ExportAllDeclaration: ['exported', 'source', 'attributes'],6182 ExportDefaultDeclaration: ['declaration'],6183 ExportNamedDeclaration: ['specifiers', 'source', 'attributes', 'declaration'],6184 ExportSpecifier: ['local', 'exported'],6185 ExpressionStatement: ['expression'],6186 ForInStatement: ['left', 'right', 'body'],6187 ForOfStatement: ['left', 'right', 'body'],6188 ForStatement: ['init', 'test', 'update', 'body'],6189 FunctionDeclaration: ['id', 'params', 'body'],6190 FunctionExpression: ['id', 'params', 'body'],6191 Identifier: [],6192 IfStatement: ['test', 'consequent', 'alternate'],6193 ImportAttribute: ['key', 'value'],6194 ImportDeclaration: ['specifiers', 'source', 'attributes'],6195 ImportDefaultSpecifier: ['local'],6196 ImportExpression: ['source', 'options'],6197 ImportNamespaceSpecifier: ['local'],6198 ImportSpecifier: ['imported', 'local'],6199 LabeledStatement: ['label', 'body'],6200 Literal: [],6201 LogicalExpression: ['left', 'right'],6202 MemberExpression: ['object', 'property'],6203 MetaProperty: ['meta', 'property'],6204 MethodDefinition: ['decorators', 'key', 'value'],6205 NewExpression: ['callee', 'arguments'],6206 ObjectExpression: ['properties'],6207 ObjectPattern: ['properties'],6208 PanicError: [],6209 ParseError: [],6210 PrivateIdentifier: [],6211 Program: ['body'],6212 Property: ['key', 'value'],6213 PropertyDefinition: ['decorators', 'key', 'value'],6214 RestElement: ['argument'],6215 ReturnStatement: ['argument'],6216 SequenceExpression: ['expressions'],6217 SpreadElement: ['argument'],6218 StaticBlock: ['body'],6219 Super: [],6220 SwitchCase: ['test', 'consequent'],6221 SwitchStatement: ['discriminant', 'cases'],6222 TaggedTemplateExpression: ['tag', 'quasi'],6223 TemplateElement: [],6224 TemplateLiteral: ['quasis', 'expressions'],6225 ThisExpression: [],6226 ThrowStatement: ['argument'],6227 TryStatement: ['block', 'handler', 'finalizer'],6228 UnaryExpression: ['argument'],6229 UpdateExpression: ['argument'],6230 VariableDeclaration: ['declarations'],6231 VariableDeclarator: ['id', 'init'],6232 WhileStatement: ['test', 'body'],6233 YieldExpression: ['argument']6234 };6235 6236 const INCLUDE_PARAMETERS = 'variables';6237 const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');6238 class NodeBase extends ExpressionEntity {6239 /**6240 * Nodes can apply custom deoptimizations once they become part of the6241 * executed code. To do this, they must initialize this as false, implement6242 * applyDeoptimizations and call this from include and hasEffects if they have6243 * custom handlers6244 */6245 get deoptimized() {6246 return isFlagSet(this.flags, 2 /* Flag.deoptimized */);6247 }6248 set deoptimized(value) {6249 this.flags = setFlag(this.flags, 2 /* Flag.deoptimized */, value);6250 }6251 constructor(parent, parentScope) {6252 super();6253 this.parent = parent;6254 this.scope = parentScope;6255 this.createScope(parentScope);6256 }6257 addExportedVariables(_variables, _exportNamesByVariable) { }6258 /**6259 * Override this to bind assignments to variables and do any initialisations6260 * that require the scopes to be populated with variables.6261 */6262 bind() {6263 for (const key of childNodeKeys[this.type]) {6264 const value = this[key];6265 if (Array.isArray(value)) {6266 for (const child of value) {6267 child?.bind();6268 }6269 }6270 else if (value) {6271 value.bind();6272 }6273 }6274 }6275 /**6276 * Override if this node should receive a different scope than the parent6277 * scope.6278 */6279 createScope(parentScope) {6280 this.scope = parentScope;6281 }6282 hasEffects(context) {6283 if (!this.deoptimized)6284 this.applyDeoptimizations();6285 for (const key of childNodeKeys[this.type]) {6286 const value = this[key];6287 if (value === null)6288 continue;6289 if (Array.isArray(value)) {6290 for (const child of value) {6291 if (child?.hasEffects(context))6292 return true;6293 }6294 }6295 else if (value.hasEffects(context))6296 return true;6297 }6298 return false;6299 }6300 hasEffectsAsAssignmentTarget(context, _checkAccess) {6301 return (this.hasEffects(context) ||6302 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));6303 }6304 include(context, includeChildrenRecursively, _options) {6305 if (!this.deoptimized)6306 this.applyDeoptimizations();6307 this.included = true;6308 for (const key of childNodeKeys[this.type]) {6309 const value = this[key];6310 if (value === null)6311 continue;6312 if (Array.isArray(value)) {6313 for (const child of value) {6314 child?.include(context, includeChildrenRecursively);6315 }6316 }6317 else {6318 value.include(context, includeChildrenRecursively);6319 }6320 }6321 }6322 includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {6323 this.include(context, includeChildrenRecursively);6324 }6325 /**6326 * Override to perform special initialisation steps after the scope is6327 * initialised6328 */6329 initialise() {6330 this.scope.context.magicString.addSourcemapLocation(this.start);6331 this.scope.context.magicString.addSourcemapLocation(this.end);6332 }6333 parseNode(esTreeNode) {6334 for (const [key, value] of Object.entries(esTreeNode)) {6335 // Skip properties defined on the class already.6336 // This way, we can override this function to add custom initialisation and then call super.parseNode6337 // Note: this doesn't skip properties with defined getters/setters which we use to pack wrap booleans6338 // in bitfields. Those are still assigned from the value in the esTreeNode.6339 if (this.hasOwnProperty(key))6340 continue;6341 if (key.charCodeAt(0) === 95 /* _ */) {6342 if (key === parseAst_js.ANNOTATION_KEY) {6343 this.annotations = value;6344 }6345 else if (key === parseAst_js.INVALID_ANNOTATION_KEY) {6346 this.invalidAnnotations = value;6347 }6348 }6349 else if (typeof value !== 'object' || value === null) {6350 this[key] = value;6351 }6352 else if (Array.isArray(value)) {6353 this[key] = [];6354 for (const child of value) {6355 this[key].push(child === null6356 ? null6357 : new (this.scope.context.getNodeConstructor(child.type))(this, this.scope).parseNode(child));6358 }6359 }6360 else {6361 this[key] = new (this.scope.context.getNodeConstructor(value.type))(this, this.scope).parseNode(value);6362 }6363 }6364 // extend child keys for unknown node types6365 childNodeKeys[esTreeNode.type] ||= createChildNodeKeysForNode(esTreeNode);6366 this.initialise();6367 return this;6368 }6369 removeAnnotations(code) {6370 if (this.annotations) {6371 for (const annotation of this.annotations) {6372 code.remove(annotation.start, annotation.end);6373 }6374 }6375 }6376 render(code, options) {6377 for (const key of childNodeKeys[this.type]) {6378 const value = this[key];6379 if (value === null)6380 continue;6381 if (Array.isArray(value)) {6382 for (const child of value) {6383 child?.render(code, options);6384 }6385 }6386 else {6387 value.render(code, options);6388 }6389 }6390 }6391 setAssignedValue(value) {6392 this.assignmentInteraction = { args: [null, value], type: INTERACTION_ASSIGNED };6393 }6394 shouldBeIncluded(context) {6395 return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext()));6396 }6397 /**6398 * Just deoptimize everything by default so that when e.g. we do not track6399 * something properly, it is deoptimized.6400 * @protected6401 */6402 applyDeoptimizations() {6403 this.deoptimized = true;6404 for (const key of childNodeKeys[this.type]) {6405 const value = this[key];6406 if (value === null)6407 continue;6408 if (Array.isArray(value)) {6409 for (const child of value) {6410 child?.deoptimizePath(UNKNOWN_PATH);6411 }6412 }6413 else {6414 value.deoptimizePath(UNKNOWN_PATH);6415 }6416 }6417 this.scope.context.requestTreeshakingPass();6418 }6419 }6420 function createChildNodeKeysForNode(esTreeNode) {6421 return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);6422 }6423 6424 4577 class SpreadElement extends NodeBase { 6425 4578 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6426 4579 if (path.length > 0) { 6427 this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, [UnknownKey, ...path], recursionTracker);4580 this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker); 6428 4581 } 6429 4582 } … … 6724 4877 property.deoptimizePath(subPath); 6725 4878 } 6726 this.prototypeExpression?.deoptimizePath(path.length === 1 ? [ ...path, UnknownKey] : path);4879 this.prototypeExpression?.deoptimizePath(path.length === 1 ? [path[0], UnknownKey] : path); 6727 4880 } 6728 4881 getLiteralValueAtPath(path, recursionTracker, origin) { … … 7137 5290 } 7138 5291 7139 class ArrayPattern extends NodeBase {7140 addExportedVariables(variables, exportNamesByVariable) {7141 for (const element of this.elements) {7142 element?.addExportedVariables(variables, exportNamesByVariable);7143 }7144 }7145 declare(kind) {7146 const variables = [];7147 for (const element of this.elements) {7148 if (element !== null) {7149 variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));7150 }7151 }7152 return variables;7153 }7154 // Patterns can only be deoptimized at the empty path at the moment7155 deoptimizePath() {7156 for (const element of this.elements) {7157 element?.deoptimizePath(EMPTY_PATH);7158 }7159 }7160 // Patterns are only checked at the empty path at the moment7161 hasEffectsOnInteractionAtPath(_path, interaction, context) {7162 for (const element of this.elements) {7163 if (element?.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))7164 return true;7165 }7166 return false;7167 }7168 markDeclarationReached() {7169 for (const element of this.elements) {7170 element?.markDeclarationReached();7171 }7172 }7173 }7174 7175 /** @typedef { import('estree').Node} Node */7176 /** @typedef {Node | {7177 * type: 'PropertyDefinition';7178 * computed: boolean;7179 * value: Node7180 * }} NodeWithPropertyDefinition */7181 7182 /**7183 *7184 * @param {NodeWithPropertyDefinition} node7185 * @param {NodeWithPropertyDefinition} parent7186 * @returns {boolean}7187 */7188 function is_reference (node, parent) {7189 if (node.type === 'MemberExpression') {7190 return !node.computed && is_reference(node.object, node);7191 }7192 7193 if (node.type === 'Identifier') {7194 if (!parent) return true;7195 7196 switch (parent.type) {7197 // disregard `bar` in `foo.bar`7198 case 'MemberExpression': return parent.computed || node === parent.object;7199 7200 // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`7201 case 'MethodDefinition': return parent.computed;7202 7203 // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`7204 case 'PropertyDefinition': return parent.computed || node === parent.value;7205 7206 // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`7207 case 'Property': return parent.computed || node === parent.value;7208 7209 // disregard the `bar` in `export { foo as bar }` or7210 // the foo in `import { foo as bar }`7211 case 'ExportSpecifier':7212 case 'ImportSpecifier': return node === parent.local;7213 7214 // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`7215 case 'LabeledStatement':7216 case 'BreakStatement':7217 case 'ContinueStatement': return false;7218 default: return true;7219 }7220 }7221 7222 return false;7223 }7224 7225 const PureFunctionKey = Symbol('PureFunction');7226 const getPureFunctions = ({ treeshake }) => {7227 const pureFunctions = Object.create(null);7228 for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {7229 let currentFunctions = pureFunctions;7230 for (const pathSegment of functionName.split('.')) {7231 currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);7232 }7233 currentFunctions[PureFunctionKey] = true;7234 }7235 return pureFunctions;7236 };7237 7238 5292 /* eslint sort-keys: "off" */ 7239 5293 const ValueProperties = Symbol('Value Properties'); … … 7349 5403 prototype: O 7350 5404 }, 5405 AggregateError: PC_WITH_ARRAY, 7351 5406 Atomics: O, 7352 5407 BigInt: C, … … 7372 5427 eval: O, 7373 5428 EvalError: PC, 5429 FinalizationRegistry: C, 7374 5430 Float32Array: ARRAY_TYPE, 7375 5431 Float64Array: ARRAY_TYPE, … … 7476 5532 }, 7477 5533 propertyIsEnumerable: O, 7478 Proxy: O, 5534 Proxy: { 5535 __proto__: null, 5536 [ValueProperties]: { 5537 deoptimizeArgumentsOnCall: ({ args: [, target, parameter] }) => { 5538 if (isObjectExpressionNode(parameter)) { 5539 const hasSpreadElement = parameter.properties.some(property => !isPropertyNode(property)); 5540 if (!hasSpreadElement) { 5541 for (const property of parameter.properties) { 5542 property.deoptimizeArgumentsOnInteractionAtPath({ 5543 args: [null, target], 5544 type: INTERACTION_CALLED, 5545 withNew: false 5546 }, EMPTY_PATH, SHARED_RECURSION_TRACKER); 5547 } 5548 return; 5549 } 5550 } 5551 target.deoptimizePath(UNKNOWN_PATH); 5552 }, 5553 getLiteralValue: getTruthyLiteralValue, 5554 hasEffectsWhenCalled: returnTrue 5555 } 5556 }, 7479 5557 RangeError: PC, 7480 5558 ReferenceError: PC, … … 7522 5600 valueOf: O, 7523 5601 WeakMap: PC_WITH_ARRAY, 5602 WeakRef: C, 7524 5603 WeakSet: PC_WITH_ARRAY, 7525 5604 // Additional globals shared by Node and Browser that are not strictly part of the language … … 8377 6456 8378 6457 const tdzVariableKinds = new Set(['class', 'const', 'let', 'var', 'using', 'await using']); 8379 class Identifier extends NodeBase {6458 class IdentifierBase extends NodeBase { 8380 6459 constructor() { 8381 6460 super(...arguments); 8382 6461 this.variable = null; 8383 this.is ReferenceVariable = false;6462 this.isVariableReference = false; 8384 6463 } 8385 6464 get isTDZAccess() { … … 8392 6471 this.flags = setFlag(this.flags, 4 /* Flag.tdzAccessDefined */, true); 8393 6472 this.flags = setFlag(this.flags, 8 /* Flag.tdzAccess */, value); 6473 } 6474 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6475 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 6476 } 6477 deoptimizePath(path) { 6478 if (path.length === 0 && !this.scope.contains(this.name)) { 6479 this.disallowImportReassignment(); 6480 } 6481 // We keep conditional chaining because an unknown Node could have an 6482 // Identifier as property that might be deoptimized by default 6483 this.variable?.deoptimizePath(path); 6484 } 6485 getLiteralValueAtPath(path, recursionTracker, origin) { 6486 return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin); 6487 } 6488 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 6489 const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 6490 return [expression, isPure || this.isPureFunction(path)]; 6491 } 6492 hasEffects(context) { 6493 if (!this.deoptimized) 6494 this.applyDeoptimizations(); 6495 if (this.isPossibleTDZ() && this.variable.kind !== 'var') { 6496 return true; 6497 } 6498 return (this.scope.context.options.treeshake 6499 .unknownGlobalSideEffects && 6500 this.variable instanceof GlobalVariable && 6501 !this.isPureFunction(EMPTY_PATH) && 6502 this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context)); 6503 } 6504 hasEffectsOnInteractionAtPath(path, interaction, context) { 6505 switch (interaction.type) { 6506 case INTERACTION_ACCESSED: { 6507 return (this.variable !== null && 6508 !this.isPureFunction(path) && 6509 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context)); 6510 } 6511 case INTERACTION_ASSIGNED: { 6512 return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context); 6513 } 6514 case INTERACTION_CALLED: { 6515 return (!this.isPureFunction(path) && 6516 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context)); 6517 } 6518 } 6519 } 6520 include() { 6521 if (!this.deoptimized) 6522 this.applyDeoptimizations(); 6523 if (!this.included) { 6524 this.included = true; 6525 if (this.variable !== null) { 6526 this.scope.context.includeVariableInModule(this.variable); 6527 } 6528 } 6529 } 6530 includeCallArguments(context, parameters) { 6531 this.variable.includeCallArguments(context, parameters); 6532 } 6533 isPossibleTDZ() { 6534 // return cached value to avoid issues with the next tree-shaking pass 6535 const cachedTdzAccess = this.isTDZAccess; 6536 if (cachedTdzAccess !== null) 6537 return cachedTdzAccess; 6538 if (!(this.variable instanceof LocalVariable && 6539 this.variable.kind && 6540 tdzVariableKinds.has(this.variable.kind) && 6541 // We ignore modules that did not receive a treeshaking pass yet as that 6542 // causes many false positives due to circular dependencies or disabled 6543 // moduleSideEffects. 6544 this.variable.module.hasTreeShakingPassStarted)) { 6545 return (this.isTDZAccess = false); 6546 } 6547 let decl_id; 6548 if (this.variable.declarations && 6549 this.variable.declarations.length === 1 && 6550 (decl_id = this.variable.declarations[0]) && 6551 this.start < decl_id.start && 6552 closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) { 6553 // a variable accessed before its declaration 6554 // in the same function or at top level of module 6555 return (this.isTDZAccess = true); 6556 } 6557 if (!this.variable.initReached) { 6558 // Either a const/let TDZ violation or 6559 // var use before declaration was encountered. 6560 return (this.isTDZAccess = true); 6561 } 6562 return (this.isTDZAccess = false); 6563 } 6564 applyDeoptimizations() { 6565 this.deoptimized = true; 6566 if (this.variable instanceof LocalVariable) { 6567 // When accessing a variable from a module without side effects, this 6568 // means we use an export of that module and therefore need to potentially 6569 // include it in the bundle. 6570 if (!this.variable.module.isExecuted) { 6571 markModuleAndImpureDependenciesAsExecuted(this.variable.module); 6572 } 6573 this.variable.consolidateInitializers(); 6574 this.scope.context.requestTreeshakingPass(); 6575 } 6576 if (this.isVariableReference) { 6577 this.variable.addUsedPlace(this); 6578 this.scope.context.requestTreeshakingPass(); 6579 } 6580 } 6581 disallowImportReassignment() { 6582 return this.scope.context.error(parseAst_js.logIllegalImportReassignment(this.name, this.scope.context.module.id), this.start); 6583 } 6584 getVariableRespectingTDZ() { 6585 if (this.isPossibleTDZ()) { 6586 return UNKNOWN_EXPRESSION; 6587 } 6588 return this.variable; 6589 } 6590 isPureFunction(path) { 6591 let currentPureFunction = this.scope.context.manualPureFunctions[this.name]; 6592 for (const segment of path) { 6593 if (currentPureFunction) { 6594 if (currentPureFunction[PureFunctionKey]) { 6595 return true; 6596 } 6597 currentPureFunction = currentPureFunction[segment]; 6598 } 6599 else { 6600 return false; 6601 } 6602 } 6603 return currentPureFunction?.[PureFunctionKey]; 6604 } 6605 } 6606 function closestParentFunctionOrProgram(node) { 6607 while (node && !/^Program|Function/.test(node.type)) { 6608 node = node.parent; 6609 } 6610 // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program 6611 return node; 6612 } 6613 6614 class Identifier extends IdentifierBase { 6615 constructor() { 6616 super(...arguments); 6617 this.variable = null; 8394 6618 } 8395 6619 addExportedVariables(variables, exportNamesByVariable) { … … 8402 6626 this.variable = this.scope.findVariable(this.name); 8403 6627 this.variable.addReference(this); 8404 this.is ReferenceVariable = true;6628 this.isVariableReference = true; 8405 6629 } 8406 6630 } … … 8442 6666 return [(this.variable = variable)]; 8443 6667 } 8444 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {8445 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);8446 }8447 deoptimizePath(path) {8448 if (path.length === 0 && !this.scope.contains(this.name)) {8449 this.disallowImportReassignment();8450 }8451 // We keep conditional chaining because an unknown Node could have an8452 // Identifier as property that might be deoptimized by default8453 this.variable?.deoptimizePath(path);8454 }8455 getLiteralValueAtPath(path, recursionTracker, origin) {8456 return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);8457 }8458 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {8459 const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);8460 return [expression, isPure || this.isPureFunction(path)];8461 }8462 hasEffects(context) {8463 if (!this.deoptimized)8464 this.applyDeoptimizations();8465 if (this.isPossibleTDZ() && this.variable.kind !== 'var') {8466 return true;8467 }8468 return (this.scope.context.options.treeshake8469 .unknownGlobalSideEffects &&8470 this.variable instanceof GlobalVariable &&8471 !this.isPureFunction(EMPTY_PATH) &&8472 this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));8473 }8474 hasEffectsOnInteractionAtPath(path, interaction, context) {8475 switch (interaction.type) {8476 case INTERACTION_ACCESSED: {8477 return (this.variable !== null &&8478 !this.isPureFunction(path) &&8479 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));8480 }8481 case INTERACTION_ASSIGNED: {8482 return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context);8483 }8484 case INTERACTION_CALLED: {8485 return (!this.isPureFunction(path) &&8486 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));8487 }8488 }8489 }8490 include() {8491 if (!this.deoptimized)8492 this.applyDeoptimizations();8493 if (!this.included) {8494 this.included = true;8495 if (this.variable !== null) {8496 this.scope.context.includeVariableInModule(this.variable);8497 }8498 }8499 }8500 includeCallArguments(context, parameters) {8501 this.variable.includeCallArguments(context, parameters);8502 }8503 isPossibleTDZ() {8504 // return cached value to avoid issues with the next tree-shaking pass8505 const cachedTdzAccess = this.isTDZAccess;8506 if (cachedTdzAccess !== null)8507 return cachedTdzAccess;8508 if (!(this.variable instanceof LocalVariable &&8509 this.variable.kind &&8510 tdzVariableKinds.has(this.variable.kind) &&8511 // we ignore possible TDZs due to circular module dependencies as8512 // otherwise we get many false positives8513 this.variable.module === this.scope.context.module)) {8514 return (this.isTDZAccess = false);8515 }8516 let decl_id;8517 if (this.variable.declarations &&8518 this.variable.declarations.length === 1 &&8519 (decl_id = this.variable.declarations[0]) &&8520 this.start < decl_id.start &&8521 closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) {8522 // a variable accessed before its declaration8523 // in the same function or at top level of module8524 return (this.isTDZAccess = true);8525 }8526 // We ignore the case where the module is not yet executed because8527 // moduleSideEffects are false.8528 if (!this.variable.initReached && this.scope.context.module.isExecuted) {8529 // Either a const/let TDZ violation or8530 // var use before declaration was encountered.8531 return (this.isTDZAccess = true);8532 }8533 return (this.isTDZAccess = false);8534 }8535 6668 markDeclarationReached() { 8536 6669 this.variable.initReached = true; … … 8555 6688 } 8556 6689 } 8557 }8558 disallowImportReassignment() {8559 return this.scope.context.error(parseAst_js.logIllegalImportReassignment(this.name, this.scope.context.module.id), this.start);8560 }8561 applyDeoptimizations() {8562 this.deoptimized = true;8563 if (this.variable instanceof LocalVariable) {8564 this.variable.consolidateInitializers();8565 this.scope.context.requestTreeshakingPass();8566 }8567 if (this.isReferenceVariable) {8568 this.variable.addUsedPlace(this);8569 this.scope.context.requestTreeshakingPass();8570 }8571 }8572 getVariableRespectingTDZ() {8573 if (this.isPossibleTDZ()) {8574 return UNKNOWN_EXPRESSION;8575 }8576 return this.variable;8577 }8578 isPureFunction(path) {8579 let currentPureFunction = this.scope.context.manualPureFunctions[this.name];8580 for (const segment of path) {8581 if (currentPureFunction) {8582 if (currentPureFunction[PureFunctionKey]) {8583 return true;8584 }8585 currentPureFunction = currentPureFunction[segment];8586 }8587 else {8588 return false;8589 }8590 }8591 return currentPureFunction?.[PureFunctionKey];8592 }8593 }8594 function closestParentFunctionOrProgram(node) {8595 while (node && !/^Program|Function/.test(node.type)) {8596 node = node.parent;8597 }8598 // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program8599 return node;8600 }8601 8602 const MAX_TRACKED_INTERACTIONS = 20;8603 const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY;8604 const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);8605 const EMPTY_PATH_TRACKER = new PathTracker();8606 const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);8607 class ParameterVariable extends LocalVariable {8608 constructor(name, declarator, context) {8609 super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');8610 this.deoptimizationInteractions = [];8611 this.deoptimizations = new PathTracker();8612 this.deoptimizedFields = new Set();8613 this.entitiesToBeDeoptimized = new Set();8614 this.expressionsUseTheKnownValue = [];8615 this.knownValue = null;8616 this.knownValueLiteral = UnknownValue;8617 this.frozenValue = null;8618 }8619 addEntityToBeDeoptimized(entity) {8620 if (entity === UNKNOWN_EXPRESSION) {8621 // As unknown expressions fully deoptimize all interactions, we can clear8622 // the interaction cache at this point provided we keep this optimization8623 // in mind when adding new interactions8624 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {8625 this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);8626 for (const { interaction } of this.deoptimizationInteractions) {8627 deoptimizeInteraction(interaction);8628 }8629 this.deoptimizationInteractions = NO_INTERACTIONS;8630 }8631 }8632 else if (this.deoptimizedFields.has(UnknownKey)) {8633 // This means that we already deoptimized all interactions and no longer8634 // track them8635 entity.deoptimizePath(UNKNOWN_PATH);8636 }8637 else if (!this.entitiesToBeDeoptimized.has(entity)) {8638 this.entitiesToBeDeoptimized.add(entity);8639 for (const field of this.deoptimizedFields) {8640 entity.deoptimizePath([field]);8641 }8642 for (const { interaction, path } of this.deoptimizationInteractions) {8643 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);8644 }8645 }8646 }8647 markReassigned() {8648 if (this.isReassigned) {8649 return;8650 }8651 super.markReassigned();8652 for (const expression of this.expressionsUseTheKnownValue) {8653 expression.deoptimizeCache();8654 }8655 this.expressionsUseTheKnownValue = parseAst_js.EMPTY_ARRAY;8656 }8657 deoptimizeCache() {8658 this.markReassigned();8659 }8660 /**8661 * Update the known value of the parameter variable.8662 * Must be called for every function call, so it can track all the arguments,8663 * and deoptimizeCache itself to mark reassigned if the argument is changed.8664 * @param argument The argument of the function call8665 */8666 updateKnownValue(argument) {8667 if (this.isReassigned) {8668 return;8669 }8670 if (this.knownValue === null) {8671 this.knownValue = argument;8672 this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);8673 return;8674 }8675 // the same literal or identifier, do nothing8676 if (this.knownValue === argument ||8677 (this.knownValue instanceof Identifier &&8678 argument instanceof Identifier &&8679 this.knownValue.variable === argument.variable)) {8680 return;8681 }8682 const oldValue = this.knownValueLiteral;8683 if (typeof oldValue === 'symbol') {8684 this.markReassigned();8685 return;8686 }8687 // add tracking for the new argument8688 const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);8689 if (newValue !== oldValue) {8690 this.markReassigned();8691 }8692 }8693 /**8694 * This function freezes the known value of the parameter variable,8695 * so the optimization starts with a certain ExpressionEntity.8696 * The optimization can be undone by calling `markReassigned`.8697 * @returns the frozen value8698 */8699 getKnownValue() {8700 if (this.frozenValue === null) {8701 this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION;8702 }8703 return this.frozenValue;8704 }8705 getLiteralValueAtPath(path, recursionTracker, origin) {8706 if (this.isReassigned) {8707 return UnknownValue;8708 }8709 const knownValue = this.getKnownValue();8710 this.expressionsUseTheKnownValue.push(origin);8711 return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);8712 }8713 hasEffectsOnInteractionAtPath(path, interaction, context) {8714 if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {8715 return super.hasEffectsOnInteractionAtPath(path, interaction, context);8716 }8717 const knownValue = this.getKnownValue();8718 return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);8719 }8720 deoptimizeArgumentsOnInteractionAtPath(interaction, path) {8721 // For performance reasons, we fully deoptimize all deeper interactions8722 if (path.length >= 2 ||8723 this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||8724 this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||8725 (path.length === 1 &&8726 (this.deoptimizedFields.has(UnknownKey) ||8727 (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) {8728 deoptimizeInteraction(interaction);8729 return;8730 }8731 if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {8732 for (const entity of this.entitiesToBeDeoptimized) {8733 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);8734 }8735 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {8736 this.deoptimizationInteractions.push({8737 interaction,8738 path8739 });8740 }8741 }8742 }8743 deoptimizePath(path) {8744 if (path.length === 0) {8745 this.markReassigned();8746 return;8747 }8748 if (this.deoptimizedFields.has(UnknownKey)) {8749 return;8750 }8751 const key = path[0];8752 if (this.deoptimizedFields.has(key)) {8753 return;8754 }8755 this.deoptimizedFields.add(key);8756 for (const entity of this.entitiesToBeDeoptimized) {8757 // We do not need a recursion tracker here as we already track whether8758 // this field is deoptimized8759 entity.deoptimizePath([key]);8760 }8761 if (key === UnknownKey) {8762 // save some memory8763 this.deoptimizationInteractions = NO_INTERACTIONS;8764 this.deoptimizations = EMPTY_PATH_TRACKER;8765 this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;8766 this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;8767 }8768 }8769 getReturnExpressionWhenCalledAtPath(path) {8770 // We deoptimize everything that is called as that will trivially deoptimize8771 // the corresponding return expressions as well and avoid badly performing8772 // and complicated alternatives8773 if (path.length === 0) {8774 this.deoptimizePath(UNKNOWN_PATH);8775 }8776 else if (!this.deoptimizedFields.has(path[0])) {8777 this.deoptimizePath([path[0]]);8778 }8779 return UNKNOWN_RETURN_EXPRESSION;8780 6690 } 8781 6691 } … … 8864 6774 } 8865 6775 addReturnExpression(expression) { 8866 this.parent instanceof ChildScope && this.parent.addReturnExpression(expression); 6776 if (this.parent instanceof ChildScope) { 6777 this.parent.addReturnExpression(expression); 6778 } 8867 6779 } 8868 6780 addUsedOutsideNames(usedNames, format, exportNamesByVariable, accessedGlobalsByScope) { … … 8907 6819 return this.parent.findLexicalBoundary(); 8908 6820 } 6821 findGlobal(name) { 6822 const variable = this.parent.findVariable(name); 6823 this.accessedOutsideVariables.set(name, variable); 6824 return variable; 6825 } 8909 6826 findVariable(name) { 8910 6827 const knownVariable = this.variables.get(name) || this.accessedOutsideVariables.get(name); … … 8915 6832 this.accessedOutsideVariables.set(name, variable); 8916 6833 return variable; 6834 } 6835 } 6836 6837 function checkEffectForNodes(nodes, context) { 6838 for (const node of nodes) { 6839 if (node.hasEffects(context)) { 6840 return true; 6841 } 6842 } 6843 return false; 6844 } 6845 6846 class MethodBase extends NodeBase { 6847 constructor() { 6848 super(...arguments); 6849 this.accessedValue = null; 6850 } 6851 get computed() { 6852 return isFlagSet(this.flags, 1024 /* Flag.computed */); 6853 } 6854 set computed(value) { 6855 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value); 6856 } 6857 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6858 if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) { 6859 return this.value.deoptimizeArgumentsOnInteractionAtPath({ 6860 args: interaction.args, 6861 type: INTERACTION_CALLED, 6862 withNew: false 6863 }, EMPTY_PATH, recursionTracker); 6864 } 6865 if (interaction.type === INTERACTION_ASSIGNED && this.kind === 'set' && path.length === 0) { 6866 return this.value.deoptimizeArgumentsOnInteractionAtPath({ 6867 args: interaction.args, 6868 type: INTERACTION_CALLED, 6869 withNew: false 6870 }, EMPTY_PATH, recursionTracker); 6871 } 6872 this.getAccessedValue()[0].deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 6873 } 6874 // As getter properties directly receive their values from fixed function 6875 // expressions, there is no known situation where a getter is deoptimized. 6876 deoptimizeCache() { } 6877 deoptimizePath(path) { 6878 this.getAccessedValue()[0].deoptimizePath(path); 6879 } 6880 getLiteralValueAtPath(path, recursionTracker, origin) { 6881 return this.getAccessedValue()[0].getLiteralValueAtPath(path, recursionTracker, origin); 6882 } 6883 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 6884 return this.getAccessedValue()[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 6885 } 6886 hasEffects(context) { 6887 return this.key.hasEffects(context); 6888 } 6889 hasEffectsOnInteractionAtPath(path, interaction, context) { 6890 if (this.kind === 'get' && interaction.type === INTERACTION_ACCESSED && path.length === 0) { 6891 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, { 6892 args: interaction.args, 6893 type: INTERACTION_CALLED, 6894 withNew: false 6895 }, context); 6896 } 6897 // setters are only called for empty paths 6898 if (this.kind === 'set' && interaction.type === INTERACTION_ASSIGNED) { 6899 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, { 6900 args: interaction.args, 6901 type: INTERACTION_CALLED, 6902 withNew: false 6903 }, context); 6904 } 6905 return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context); 6906 } 6907 applyDeoptimizations() { } 6908 getAccessedValue() { 6909 if (this.accessedValue === null) { 6910 if (this.kind === 'get') { 6911 this.accessedValue = UNKNOWN_RETURN_EXPRESSION; 6912 return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this)); 6913 } 6914 else { 6915 return (this.accessedValue = [this.value, false]); 6916 } 6917 } 6918 return this.accessedValue; 6919 } 6920 } 6921 6922 class MethodDefinition extends MethodBase { 6923 hasEffects(context) { 6924 return super.hasEffects(context) || checkEffectForNodes(this.decorators, context); 6925 } 6926 applyDeoptimizations() { } 6927 } 6928 6929 class BlockScope extends ChildScope { 6930 constructor(parent) { 6931 super(parent, parent.context); 6932 } 6933 addDeclaration(identifier, context, init, kind) { 6934 if (kind === 'var') { 6935 const name = identifier.name; 6936 const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name); 6937 if (existingVariable) { 6938 if (existingVariable.kind === 'var' || 6939 (kind === 'var' && existingVariable.kind === 'parameter')) { 6940 existingVariable.addDeclaration(identifier, init); 6941 return existingVariable; 6942 } 6943 return context.error(parseAst_js.logRedeclarationError(name), identifier.start); 6944 } 6945 const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind); 6946 // Necessary to make sure the init is deoptimized for conditional declarations. 6947 // We cannot call deoptimizePath here. 6948 declaredVariable.markInitializersForDeoptimization(); 6949 // We add the variable to this and all parent scopes to reliably detect conflicts 6950 this.addHoistedVariable(name, declaredVariable); 6951 return declaredVariable; 6952 } 6953 return super.addDeclaration(identifier, context, init, kind); 6954 } 6955 } 6956 6957 class StaticBlock extends NodeBase { 6958 createScope(parentScope) { 6959 this.scope = new BlockScope(parentScope); 6960 } 6961 hasEffects(context) { 6962 for (const node of this.body) { 6963 if (node.hasEffects(context)) 6964 return true; 6965 } 6966 return false; 6967 } 6968 include(context, includeChildrenRecursively) { 6969 this.included = true; 6970 for (const node of this.body) { 6971 if (includeChildrenRecursively || node.shouldBeIncluded(context)) 6972 node.include(context, includeChildrenRecursively); 6973 } 6974 } 6975 render(code, options) { 6976 if (this.body.length > 0) { 6977 const bodyStartPos = findFirstOccurrenceOutsideComment(code.original.slice(this.start, this.end), '{') + 1; 6978 renderStatementList(this.body, code, this.start + bodyStartPos, this.end - 1, options); 6979 } 6980 else { 6981 super.render(code, options); 6982 } 6983 } 6984 } 6985 function isStaticBlock(statement) { 6986 return statement.type === parseAst_js.StaticBlock; 6987 } 6988 6989 class ObjectMember extends ExpressionEntity { 6990 constructor(object, key) { 6991 super(); 6992 this.object = object; 6993 this.key = key; 6994 } 6995 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6996 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker); 6997 } 6998 deoptimizePath(path) { 6999 this.object.deoptimizePath([this.key, ...path]); 7000 } 7001 getLiteralValueAtPath(path, recursionTracker, origin) { 7002 return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin); 7003 } 7004 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 7005 return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin); 7006 } 7007 hasEffectsOnInteractionAtPath(path, interaction, context) { 7008 return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context); 7009 } 7010 } 7011 7012 class ClassNode extends NodeBase { 7013 constructor() { 7014 super(...arguments); 7015 this.objectEntity = null; 7016 } 7017 createScope(parentScope) { 7018 this.scope = new ChildScope(parentScope, parentScope.context); 7019 } 7020 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 7021 this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 7022 } 7023 deoptimizeCache() { 7024 this.getObjectEntity().deoptimizeAllProperties(); 7025 } 7026 deoptimizePath(path) { 7027 this.getObjectEntity().deoptimizePath(path); 7028 } 7029 getLiteralValueAtPath(path, recursionTracker, origin) { 7030 return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin); 7031 } 7032 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 7033 return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 7034 } 7035 hasEffects(context) { 7036 if (!this.deoptimized) 7037 this.applyDeoptimizations(); 7038 const initEffect = this.superClass?.hasEffects(context) || this.body.hasEffects(context); 7039 this.id?.markDeclarationReached(); 7040 return initEffect || super.hasEffects(context) || checkEffectForNodes(this.decorators, context); 7041 } 7042 hasEffectsOnInteractionAtPath(path, interaction, context) { 7043 return interaction.type === INTERACTION_CALLED && path.length === 0 7044 ? !interaction.withNew || 7045 (this.classConstructor === null 7046 ? this.superClass?.hasEffectsOnInteractionAtPath(path, interaction, context) 7047 : this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)) || 7048 false 7049 : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context); 7050 } 7051 include(context, includeChildrenRecursively) { 7052 if (!this.deoptimized) 7053 this.applyDeoptimizations(); 7054 this.included = true; 7055 this.superClass?.include(context, includeChildrenRecursively); 7056 this.body.include(context, includeChildrenRecursively); 7057 for (const decorator of this.decorators) 7058 decorator.include(context, includeChildrenRecursively); 7059 if (this.id) { 7060 this.id.markDeclarationReached(); 7061 this.id.include(); 7062 } 7063 } 7064 initialise() { 7065 super.initialise(); 7066 this.id?.declare('class', this); 7067 for (const method of this.body.body) { 7068 if (method instanceof MethodDefinition && method.kind === 'constructor') { 7069 this.classConstructor = method; 7070 return; 7071 } 7072 } 7073 this.classConstructor = null; 7074 } 7075 applyDeoptimizations() { 7076 this.deoptimized = true; 7077 for (const definition of this.body.body) { 7078 if (!isStaticBlock(definition) && 7079 !(definition.static || 7080 (definition instanceof MethodDefinition && definition.kind === 'constructor'))) { 7081 // Calls to methods are not tracked, ensure that the return value is deoptimized 7082 definition.deoptimizePath(UNKNOWN_PATH); 7083 } 7084 } 7085 this.scope.context.requestTreeshakingPass(); 7086 } 7087 getObjectEntity() { 7088 if (this.objectEntity !== null) { 7089 return this.objectEntity; 7090 } 7091 const staticProperties = []; 7092 const dynamicMethods = []; 7093 for (const definition of this.body.body) { 7094 if (isStaticBlock(definition)) 7095 continue; 7096 const properties = definition.static ? staticProperties : dynamicMethods; 7097 const definitionKind = definition.kind; 7098 // Note that class fields do not end up on the prototype 7099 if (properties === dynamicMethods && !definitionKind) 7100 continue; 7101 const kind = definitionKind === 'set' || definitionKind === 'get' ? definitionKind : 'init'; 7102 let key; 7103 if (definition.computed) { 7104 const keyValue = definition.key.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 7105 if (typeof keyValue === 'symbol') { 7106 properties.push({ key: UnknownKey, kind, property: definition }); 7107 continue; 7108 } 7109 else { 7110 key = String(keyValue); 7111 } 7112 } 7113 else { 7114 key = 7115 definition.key instanceof Identifier 7116 ? definition.key.name 7117 : String(definition.key.value); 7118 } 7119 properties.push({ key, kind, property: definition }); 7120 } 7121 staticProperties.unshift({ 7122 key: 'prototype', 7123 kind: 'init', 7124 property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE) 7125 }); 7126 return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE)); 7127 } 7128 } 7129 7130 class ClassDeclaration extends ClassNode { 7131 initialise() { 7132 super.initialise(); 7133 if (this.id !== null) { 7134 this.id.variable.isId = true; 7135 } 7136 } 7137 parseNode(esTreeNode) { 7138 if (esTreeNode.id !== null) { 7139 this.id = new Identifier(this, this.scope.parent).parseNode(esTreeNode.id); 7140 } 7141 return super.parseNode(esTreeNode); 7142 } 7143 render(code, options) { 7144 const { exportNamesByVariable, format, snippets: { _, getPropertyAccess } } = options; 7145 if (this.id) { 7146 const { variable, name } = this.id; 7147 if (format === 'system' && exportNamesByVariable.has(variable)) { 7148 code.appendLeft(this.end, `${_}${getSystemExportStatement([variable], options)};`); 7149 } 7150 const renderedVariable = variable.getName(getPropertyAccess); 7151 if (renderedVariable !== name) { 7152 this.decorators.map(decorator => decorator.render(code, options)); 7153 this.superClass?.render(code, options); 7154 this.body.render(code, { 7155 ...options, 7156 useOriginalName: (_variable) => _variable === variable 7157 }); 7158 code.prependRight(this.start, `let ${renderedVariable}${_}=${_}`); 7159 code.prependLeft(this.end, ';'); 7160 return; 7161 } 7162 } 7163 super.render(code, options); 7164 } 7165 applyDeoptimizations() { 7166 super.applyDeoptimizations(); 7167 const { id, scope } = this; 7168 if (id) { 7169 const { name, variable } = id; 7170 for (const accessedVariable of scope.accessedOutsideVariables.values()) { 7171 if (accessedVariable !== variable) { 7172 accessedVariable.forbidName(name); 7173 } 7174 } 7175 } 7176 } 7177 } 7178 7179 class ArgumentsVariable extends LocalVariable { 7180 constructor(context) { 7181 super('arguments', null, UNKNOWN_EXPRESSION, context, 'other'); 7182 this.deoptimizedArguments = []; 7183 } 7184 addArgumentToBeDeoptimized(argument) { 7185 if (this.included) { 7186 argument.deoptimizePath(UNKNOWN_PATH); 7187 } 7188 else { 7189 this.deoptimizedArguments.push(argument); 7190 } 7191 } 7192 hasEffectsOnInteractionAtPath(path, { type }) { 7193 return type !== INTERACTION_ACCESSED || path.length > 1; 7194 } 7195 include() { 7196 super.include(); 7197 for (const argument of this.deoptimizedArguments) { 7198 argument.deoptimizePath(UNKNOWN_PATH); 7199 } 7200 this.deoptimizedArguments.length = 0; 7201 } 7202 } 7203 7204 const MAX_TRACKED_INTERACTIONS = 20; 7205 const NO_INTERACTIONS = parseAst_js.EMPTY_ARRAY; 7206 const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]); 7207 const EMPTY_PATH_TRACKER = new PathTracker(); 7208 const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]); 7209 class ParameterVariable extends LocalVariable { 7210 constructor(name, declarator, context) { 7211 super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter'); 7212 this.deoptimizationInteractions = []; 7213 this.deoptimizations = new PathTracker(); 7214 this.deoptimizedFields = new Set(); 7215 this.entitiesToBeDeoptimized = new Set(); 7216 this.expressionsUseTheKnownValue = []; 7217 this.knownValue = null; 7218 this.knownValueLiteral = UnknownValue; 7219 this.frozenValue = null; 7220 } 7221 addEntityToBeDeoptimized(entity) { 7222 if (entity === UNKNOWN_EXPRESSION) { 7223 // As unknown expressions fully deoptimize all interactions, we can clear 7224 // the interaction cache at this point provided we keep this optimization 7225 // in mind when adding new interactions 7226 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) { 7227 this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION); 7228 for (const { interaction } of this.deoptimizationInteractions) { 7229 deoptimizeInteraction(interaction); 7230 } 7231 this.deoptimizationInteractions = NO_INTERACTIONS; 7232 } 7233 } 7234 else if (this.deoptimizedFields.has(UnknownKey)) { 7235 // This means that we already deoptimized all interactions and no longer 7236 // track them 7237 entity.deoptimizePath(UNKNOWN_PATH); 7238 } 7239 else if (!this.entitiesToBeDeoptimized.has(entity)) { 7240 this.entitiesToBeDeoptimized.add(entity); 7241 for (const field of this.deoptimizedFields) { 7242 entity.deoptimizePath([field]); 7243 } 7244 for (const { interaction, path } of this.deoptimizationInteractions) { 7245 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER); 7246 } 7247 } 7248 } 7249 markReassigned() { 7250 if (this.isReassigned) { 7251 return; 7252 } 7253 super.markReassigned(); 7254 for (const expression of this.expressionsUseTheKnownValue) { 7255 expression.deoptimizeCache(); 7256 } 7257 this.expressionsUseTheKnownValue = parseAst_js.EMPTY_ARRAY; 7258 } 7259 deoptimizeCache() { 7260 this.markReassigned(); 7261 } 7262 /** 7263 * Update the known value of the parameter variable. 7264 * Must be called for every function call, so it can track all the arguments, 7265 * and deoptimizeCache itself to mark reassigned if the argument is changed. 7266 * @param argument The argument of the function call 7267 */ 7268 updateKnownValue(argument) { 7269 if (this.isReassigned) { 7270 return; 7271 } 7272 if (this.knownValue === null) { 7273 this.knownValue = argument; 7274 this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 7275 return; 7276 } 7277 // the same literal or identifier, do nothing 7278 if (this.knownValue === argument || 7279 (this.knownValue instanceof Identifier && 7280 argument instanceof Identifier && 7281 this.knownValue.variable === argument.variable)) { 7282 return; 7283 } 7284 const oldValue = this.knownValueLiteral; 7285 if (typeof oldValue === 'symbol') { 7286 this.markReassigned(); 7287 return; 7288 } 7289 // add tracking for the new argument 7290 const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 7291 if (newValue !== oldValue) { 7292 this.markReassigned(); 7293 } 7294 } 7295 /** 7296 * This function freezes the known value of the parameter variable, 7297 * so the optimization starts with a certain ExpressionEntity. 7298 * The optimization can be undone by calling `markReassigned`. 7299 * @returns the frozen value 7300 */ 7301 getKnownValue() { 7302 if (this.frozenValue === null) { 7303 this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION; 7304 } 7305 return this.frozenValue; 7306 } 7307 getLiteralValueAtPath(path, recursionTracker, origin) { 7308 if (this.isReassigned) { 7309 return UnknownValue; 7310 } 7311 const knownValue = this.getKnownValue(); 7312 this.expressionsUseTheKnownValue.push(origin); 7313 return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue); 7314 } 7315 hasEffectsOnInteractionAtPath(path, interaction, context) { 7316 if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) { 7317 return super.hasEffectsOnInteractionAtPath(path, interaction, context); 7318 } 7319 const knownValue = this.getKnownValue(); 7320 return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context); 7321 } 7322 deoptimizeArgumentsOnInteractionAtPath(interaction, path) { 7323 // For performance reasons, we fully deoptimize all deeper interactions 7324 if (path.length >= 2 || 7325 this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) || 7326 this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS || 7327 (path.length === 1 && 7328 (this.deoptimizedFields.has(UnknownKey) || 7329 (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) { 7330 deoptimizeInteraction(interaction); 7331 return; 7332 } 7333 if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) { 7334 for (const entity of this.entitiesToBeDeoptimized) { 7335 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER); 7336 } 7337 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) { 7338 this.deoptimizationInteractions.push({ 7339 interaction, 7340 path 7341 }); 7342 } 7343 } 7344 } 7345 deoptimizePath(path) { 7346 if (path.length === 0) { 7347 this.markReassigned(); 7348 return; 7349 } 7350 if (this.deoptimizedFields.has(UnknownKey)) { 7351 return; 7352 } 7353 const key = path[0]; 7354 if (this.deoptimizedFields.has(key)) { 7355 return; 7356 } 7357 this.deoptimizedFields.add(key); 7358 for (const entity of this.entitiesToBeDeoptimized) { 7359 // We do not need a recursion tracker here as we already track whether 7360 // this field is deoptimized 7361 entity.deoptimizePath([key]); 7362 } 7363 if (key === UnknownKey) { 7364 // save some memory 7365 this.deoptimizationInteractions = NO_INTERACTIONS; 7366 this.deoptimizations = EMPTY_PATH_TRACKER; 7367 this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD; 7368 this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY; 7369 } 7370 } 7371 getReturnExpressionWhenCalledAtPath(path) { 7372 // We deoptimize everything that is called as that will trivially deoptimize 7373 // the corresponding return expressions as well and avoid badly performing 7374 // and complicated alternatives 7375 if (path.length === 0) { 7376 this.deoptimizePath(UNKNOWN_PATH); 7377 } 7378 else if (!this.deoptimizedFields.has(path[0])) { 7379 this.deoptimizePath([path[0]]); 7380 } 7381 return UNKNOWN_RETURN_EXPRESSION; 7382 } 7383 } 7384 7385 class ThisVariable extends ParameterVariable { 7386 constructor(context) { 7387 super('this', null, context); 7388 } 7389 hasEffectsOnInteractionAtPath(path, interaction, context) { 7390 return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context); 8917 7391 } 8918 7392 } … … 9095 7569 } 9096 7570 9097 function treeshakeNode(node, code, start, end) { 9098 code.remove(start, end); 9099 node.removeAnnotations(code); 9100 } 9101 9102 const NO_SEMICOLON = { isNoStatement: true }; 9103 // This assumes there are only white-space and comments between start and the string we are looking for 9104 function findFirstOccurrenceOutsideComment(code, searchString, start = 0) { 9105 let searchPos, charCodeAfterSlash; 9106 searchPos = code.indexOf(searchString, start); 9107 while (true) { 9108 start = code.indexOf('/', start); 9109 if (start === -1 || start >= searchPos) 9110 return searchPos; 9111 charCodeAfterSlash = code.charCodeAt(++start); 9112 ++start; 9113 // With our assumption, '/' always starts a comment. Determine comment type: 9114 start = 9115 charCodeAfterSlash === 47 /*"/"*/ 9116 ? code.indexOf('\n', start) + 1 9117 : code.indexOf('*/', start) + 2; 9118 if (start > searchPos) { 9119 searchPos = code.indexOf(searchString, start); 9120 } 9121 } 9122 } 9123 const NON_WHITESPACE = /\S/g; 9124 function findNonWhiteSpace(code, index) { 9125 NON_WHITESPACE.lastIndex = index; 9126 const result = NON_WHITESPACE.exec(code); 9127 return result.index; 9128 } 9129 const WHITESPACE = /\s/; 9130 function findLastWhiteSpaceReverse(code, start, end) { 9131 while (true) { 9132 if (start >= end) { 9133 return end; 9134 } 9135 if (WHITESPACE.test(code[end - 1])) { 9136 end--; 9137 } 9138 else { 9139 return end; 9140 } 9141 } 9142 } 9143 // This assumes "code" only contains white-space and comments 9144 // Returns position of line-comment if applicable 9145 function findFirstLineBreakOutsideComment(code) { 9146 let lineBreakPos, charCodeAfterSlash, start = 0; 9147 lineBreakPos = code.indexOf('\n', start); 9148 while (true) { 9149 start = code.indexOf('/', start); 9150 if (start === -1 || start > lineBreakPos) 9151 return [lineBreakPos, lineBreakPos + 1]; 9152 // With our assumption, '/' always starts a comment. Determine comment type: 9153 charCodeAfterSlash = code.charCodeAt(start + 1); 9154 if (charCodeAfterSlash === 47 /*"/"*/) 9155 return [start, lineBreakPos + 1]; 9156 start = code.indexOf('*/', start + 2) + 2; 9157 if (start > lineBreakPos) { 9158 lineBreakPos = code.indexOf('\n', start); 9159 } 9160 } 9161 } 9162 function renderStatementList(statements, code, start, end, options) { 9163 let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart; 9164 let nextNode = statements[0]; 9165 let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries; 9166 if (nextNodeNeedsBoundaries) { 9167 nextNodeStart = 9168 start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1]; 9169 } 9170 for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) { 9171 currentNode = nextNode; 9172 currentNodeStart = nextNodeStart; 9173 currentNodeNeedsBoundaries = nextNodeNeedsBoundaries; 9174 nextNode = statements[nextIndex]; 9175 nextNodeNeedsBoundaries = 9176 nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries; 9177 if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) { 9178 nextNodeStart = 9179 currentNode.end + 9180 findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1]; 9181 if (currentNode.included) { 9182 currentNodeNeedsBoundaries 9183 ? currentNode.render(code, options, { 9184 end: nextNodeStart, 9185 start: currentNodeStart 9186 }) 9187 : currentNode.render(code, options); 9188 } 9189 else { 9190 treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart); 9191 } 9192 } 9193 else { 9194 currentNode.render(code, options); 9195 } 9196 } 9197 } 9198 // This assumes that the first character is not part of the first node 9199 function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) { 9200 const splitUpNodes = []; 9201 let node, nextNodeStart, contentEnd, char; 9202 let separator = start - 1; 9203 for (const nextNode of nodes) { 9204 if (node !== undefined) { 9205 separator = 9206 node.end + 9207 findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ','); 9208 } 9209 nextNodeStart = contentEnd = 9210 separator + 9211 1 + 9212 findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1]; 9213 while (((char = code.original.charCodeAt(nextNodeStart)), 9214 char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/) 9215 nextNodeStart++; 9216 if (node !== undefined) { 9217 splitUpNodes.push({ 9218 contentEnd, 9219 end: nextNodeStart, 9220 node, 9221 separator, 9222 start 9223 }); 9224 } 9225 node = nextNode; 9226 start = nextNodeStart; 9227 } 9228 splitUpNodes.push({ 9229 contentEnd: end, 9230 end, 9231 node: node, 9232 separator: null, 9233 start 9234 }); 9235 return splitUpNodes; 9236 } 9237 // This assumes there are only white-space and comments between start and end 9238 function removeLineBreaks(code, start, end) { 9239 while (true) { 9240 const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end)); 9241 if (removeStart === -1) { 9242 break; 9243 } 9244 code.remove(start + removeStart, (start += removeEnd)); 9245 } 9246 } 9247 9248 class BlockScope extends ChildScope { 7571 class FunctionScope extends ReturnValueScope { 9249 7572 constructor(parent) { 9250 super(parent, parent.context); 9251 } 9252 addDeclaration(identifier, context, init, kind) { 9253 if (kind === 'var') { 9254 const name = identifier.name; 9255 const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name); 9256 if (existingVariable) { 9257 if (existingVariable.kind === 'var' || 9258 (kind === 'var' && existingVariable.kind === 'parameter')) { 9259 existingVariable.addDeclaration(identifier, init); 9260 return existingVariable; 7573 const { context } = parent; 7574 super(parent, false); 7575 this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context))); 7576 this.variables.set('this', (this.thisVariable = new ThisVariable(context))); 7577 } 7578 findLexicalBoundary() { 7579 return this; 7580 } 7581 includeCallArguments(context, parameters) { 7582 super.includeCallArguments(context, parameters); 7583 if (this.argumentsVariable.included) { 7584 for (const argument of parameters) { 7585 if (!argument.included) { 7586 argument.include(context, false); 9261 7587 } 9262 return context.error(parseAst_js.logRedeclarationError(name), identifier.start); 9263 } 9264 const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind); 9265 // Necessary to make sure the init is deoptimized for conditional declarations. 9266 // We cannot call deoptimizePath here. 9267 declaredVariable.markInitializersForDeoptimization(); 9268 // We add the variable to this and all parent scopes to reliably detect conflicts 9269 this.addHoistedVariable(name, declaredVariable); 9270 return declaredVariable; 9271 } 9272 return super.addDeclaration(identifier, context, init, kind); 7588 } 7589 } 9273 7590 } 9274 7591 } … … 9379 7696 } 9380 7697 deoptimizePath(path) { 9381 path.length === 0 && this.argument.deoptimizePath(EMPTY_PATH); 7698 if (path.length === 0) { 7699 this.argument.deoptimizePath(EMPTY_PATH); 7700 } 9382 7701 } 9383 7702 hasEffectsOnInteractionAtPath(path, interaction, context) { … … 9587 7906 FunctionBase.prototype.preventChildBlockScope = true; 9588 7907 9589 class ArrowFunctionExpression extends FunctionBase {9590 constructor() {9591 super(...arguments);9592 this.objectEntity = null;9593 }9594 get expression() {9595 return isFlagSet(this.flags, 8388608 /* Flag.expression */);9596 }9597 set expression(value) {9598 this.flags = setFlag(this.flags, 8388608 /* Flag.expression */, value);9599 }9600 createScope(parentScope) {9601 this.scope = new ReturnValueScope(parentScope, false);9602 }9603 hasEffects() {9604 if (!this.deoptimized)9605 this.applyDeoptimizations();9606 return false;9607 }9608 hasEffectsOnInteractionAtPath(path, interaction, context) {9609 if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {9610 return true;9611 }9612 if (this.annotationNoSideEffects) {9613 return false;9614 }9615 if (interaction.type === INTERACTION_CALLED) {9616 const { ignore, brokenFlow } = context;9617 context.ignore = {9618 breaks: false,9619 continues: false,9620 labels: new Set(),9621 returnYield: true,9622 this: false9623 };9624 if (this.body.hasEffects(context))9625 return true;9626 context.ignore = ignore;9627 context.brokenFlow = brokenFlow;9628 }9629 return false;9630 }9631 onlyFunctionCallUsed() {9632 const isIIFE = this.parent.type === parseAst_js.CallExpression &&9633 this.parent.callee === this;9634 return isIIFE || super.onlyFunctionCallUsed();9635 }9636 include(context, includeChildrenRecursively) {9637 super.include(context, includeChildrenRecursively);9638 for (const parameter of this.params) {9639 if (!(parameter instanceof Identifier)) {9640 parameter.include(context, includeChildrenRecursively);9641 }9642 }9643 }9644 getObjectEntity() {9645 if (this.objectEntity !== null) {9646 return this.objectEntity;9647 }9648 return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE));9649 }9650 }9651 9652 function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') {9653 if (exportedVariables.length === 1 &&9654 exportNamesByVariable.get(exportedVariables[0]).length === 1) {9655 const variable = exportedVariables[0];9656 return `exports(${JSON.stringify(exportNamesByVariable.get(variable)[0])},${_}${variable.getName(getPropertyAccess)}${modifier})`;9657 }9658 else {9659 const fields = [];9660 for (const variable of exportedVariables) {9661 for (const exportName of exportNamesByVariable.get(variable)) {9662 fields.push([exportName, variable.getName(getPropertyAccess) + modifier]);9663 }9664 }9665 return `exports(${getObject(fields, { lineBreakIndent: null })})`;9666 }9667 }9668 // This is only invoked if there is exactly one export name9669 function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) {9670 code.prependRight(expressionStart, `exports(${JSON.stringify(exportNamesByVariable.get(exportedVariable)[0])},${_}`);9671 code.appendLeft(expressionEnd, ')');9672 }9673 function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) {9674 const { _, getDirectReturnIifeLeft } = options.snippets;9675 code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens }));9676 code.appendLeft(expressionEnd, ')');9677 }9678 function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) {9679 const { _, getPropertyAccess } = options.snippets;9680 code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`);9681 if (needsParens) {9682 code.prependRight(expressionStart, '(');9683 code.appendLeft(expressionEnd, ')');9684 }9685 }9686 function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) {9687 const { _ } = options.snippets;9688 code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`);9689 if (needsParens) {9690 code.prependRight(expressionStart, '(');9691 code.appendLeft(expressionEnd, ')');9692 }9693 }9694 9695 class ObjectPattern extends NodeBase {9696 addExportedVariables(variables, exportNamesByVariable) {9697 for (const property of this.properties) {9698 if (property.type === parseAst_js.Property) {9699 property.value.addExportedVariables(variables, exportNamesByVariable);9700 }9701 else {9702 property.argument.addExportedVariables(variables, exportNamesByVariable);9703 }9704 }9705 }9706 declare(kind, init) {9707 const variables = [];9708 for (const property of this.properties) {9709 variables.push(...property.declare(kind, init));9710 }9711 return variables;9712 }9713 deoptimizePath(path) {9714 if (path.length === 0) {9715 for (const property of this.properties) {9716 property.deoptimizePath(path);9717 }9718 }9719 }9720 hasEffectsOnInteractionAtPath(9721 // At the moment, this is only triggered for assignment left-hand sides,9722 // where the path is empty9723 _path, interaction, context) {9724 for (const property of this.properties) {9725 if (property.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))9726 return true;9727 }9728 return false;9729 }9730 markDeclarationReached() {9731 for (const property of this.properties) {9732 property.markDeclarationReached();9733 }9734 }9735 }9736 9737 class AssignmentExpression extends NodeBase {9738 hasEffects(context) {9739 const { deoptimized, left, operator, right } = this;9740 if (!deoptimized)9741 this.applyDeoptimizations();9742 // MemberExpressions do not access the property before assignments if the9743 // operator is '='.9744 return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));9745 }9746 hasEffectsOnInteractionAtPath(path, interaction, context) {9747 return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);9748 }9749 include(context, includeChildrenRecursively) {9750 const { deoptimized, left, right, operator } = this;9751 if (!deoptimized)9752 this.applyDeoptimizations();9753 this.included = true;9754 if (includeChildrenRecursively ||9755 operator !== '=' ||9756 left.included ||9757 left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {9758 left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');9759 }9760 right.include(context, includeChildrenRecursively);9761 }9762 initialise() {9763 super.initialise();9764 if (this.left instanceof Identifier) {9765 const variable = this.scope.variables.get(this.left.name);9766 if (variable?.kind === 'const') {9767 this.scope.context.error(parseAst_js.logConstVariableReassignError(), this.left.start);9768 }9769 }9770 this.left.setAssignedValue(this.right);9771 }9772 render(code, options, { preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) {9773 const { left, right, start, end, parent } = this;9774 if (left.included) {9775 left.render(code, options);9776 right.render(code, options);9777 }9778 else {9779 const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', left.end) + 1);9780 code.remove(start, inclusionStart);9781 if (preventASI) {9782 removeLineBreaks(code, inclusionStart, right.start);9783 }9784 right.render(code, options, {9785 renderedParentType: renderedParentType || parent.type,9786 renderedSurroundingElement: renderedSurroundingElement || parent.type9787 });9788 }9789 if (options.format === 'system') {9790 if (left instanceof Identifier) {9791 const variable = left.variable;9792 const exportNames = options.exportNamesByVariable.get(variable);9793 if (exportNames) {9794 if (exportNames.length === 1) {9795 renderSystemExportExpression(variable, start, end, code, options);9796 }9797 else {9798 renderSystemExportSequenceAfterExpression(variable, start, end, parent.type !== parseAst_js.ExpressionStatement, code, options);9799 }9800 return;9801 }9802 }9803 else {9804 const systemPatternExports = [];9805 left.addExportedVariables(systemPatternExports, options.exportNamesByVariable);9806 if (systemPatternExports.length > 0) {9807 renderSystemExportFunction(systemPatternExports, start, end, renderedSurroundingElement === parseAst_js.ExpressionStatement, code, options);9808 return;9809 }9810 }9811 }9812 if (left.included &&9813 left instanceof ObjectPattern &&9814 (renderedSurroundingElement === parseAst_js.ExpressionStatement ||9815 renderedSurroundingElement === parseAst_js.ArrowFunctionExpression)) {9816 code.appendRight(start, '(');9817 code.prependLeft(end, ')');9818 }9819 }9820 applyDeoptimizations() {9821 this.deoptimized = true;9822 this.left.deoptimizePath(EMPTY_PATH);9823 this.right.deoptimizePath(UNKNOWN_PATH);9824 this.scope.context.requestTreeshakingPass();9825 }9826 }9827 9828 class AssignmentPattern extends NodeBase {9829 addExportedVariables(variables, exportNamesByVariable) {9830 this.left.addExportedVariables(variables, exportNamesByVariable);9831 }9832 declare(kind, init) {9833 return this.left.declare(kind, init);9834 }9835 deoptimizePath(path) {9836 path.length === 0 && this.left.deoptimizePath(path);9837 }9838 hasEffectsOnInteractionAtPath(path, interaction, context) {9839 return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));9840 }9841 markDeclarationReached() {9842 this.left.markDeclarationReached();9843 }9844 render(code, options, { isShorthandProperty } = parseAst_js.BLANK) {9845 this.left.render(code, options, { isShorthandProperty });9846 this.right.render(code, options);9847 }9848 applyDeoptimizations() {9849 this.deoptimized = true;9850 this.left.deoptimizePath(EMPTY_PATH);9851 this.right.deoptimizePath(UNKNOWN_PATH);9852 this.scope.context.requestTreeshakingPass();9853 }9854 }9855 9856 class ArgumentsVariable extends LocalVariable {9857 constructor(context) {9858 super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');9859 this.deoptimizedArguments = [];9860 }9861 addArgumentToBeDeoptimized(argument) {9862 if (this.included) {9863 argument.deoptimizePath(UNKNOWN_PATH);9864 }9865 else {9866 this.deoptimizedArguments.push(argument);9867 }9868 }9869 hasEffectsOnInteractionAtPath(path, { type }) {9870 return type !== INTERACTION_ACCESSED || path.length > 1;9871 }9872 include() {9873 super.include();9874 for (const argument of this.deoptimizedArguments) {9875 argument.deoptimizePath(UNKNOWN_PATH);9876 }9877 this.deoptimizedArguments.length = 0;9878 }9879 }9880 9881 class ThisVariable extends ParameterVariable {9882 constructor(context) {9883 super('this', null, context);9884 }9885 hasEffectsOnInteractionAtPath(path, interaction, context) {9886 return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);9887 }9888 }9889 9890 class FunctionScope extends ReturnValueScope {9891 constructor(parent) {9892 const { context } = parent;9893 super(parent, false);9894 this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));9895 this.variables.set('this', (this.thisVariable = new ThisVariable(context)));9896 }9897 findLexicalBoundary() {9898 return this;9899 }9900 includeCallArguments(context, parameters) {9901 super.includeCallArguments(context, parameters);9902 if (this.argumentsVariable.included) {9903 for (const argument of parameters) {9904 if (!argument.included) {9905 argument.include(context, false);9906 }9907 }9908 }9909 }9910 }9911 9912 7908 class FunctionNode extends FunctionBase { 9913 7909 constructor() { … … 9998 7994 } 9999 7995 10000 class AwaitExpression extends NodeBase {10001 hasEffects() {10002 if (!this.deoptimized)10003 this.applyDeoptimizations();10004 return true;10005 }10006 include(context, includeChildrenRecursively) {10007 if (!this.deoptimized)10008 this.applyDeoptimizations();10009 if (!this.included) {10010 this.included = true;10011 checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {10012 let parent = this.parent;10013 do {10014 if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)10015 break checkTopLevelAwait;10016 } while ((parent = parent.parent));10017 this.scope.context.usesTopLevelAwait = true;10018 }10019 }10020 this.argument.include(context, includeChildrenRecursively);10021 }10022 }10023 10024 const binaryOperators = {10025 '!=': (left, right) => left != right,10026 '!==': (left, right) => left !== right,10027 '%': (left, right) => left % right,10028 '&': (left, right) => left & right,10029 '*': (left, right) => left * right,10030 // At the moment, "**" will be transpiled to Math.pow10031 '**': (left, right) => left ** right,10032 '+': (left, right) => left + right,10033 '-': (left, right) => left - right,10034 '/': (left, right) => left / right,10035 '<': (left, right) => left < right,10036 '<<': (left, right) => left << right,10037 '<=': (left, right) => left <= right,10038 '==': (left, right) => left == right,10039 '===': (left, right) => left === right,10040 '>': (left, right) => left > right,10041 '>=': (left, right) => left >= right,10042 '>>': (left, right) => left >> right,10043 '>>>': (left, right) => left >>> right,10044 '^': (left, right) => left ^ right,10045 '|': (left, right) => left | right10046 // We use the fallback for cases where we return something unknown10047 // in: () => UnknownValue,10048 // instanceof: () => UnknownValue,10049 };10050 class BinaryExpression extends NodeBase {10051 deoptimizeCache() { }10052 getLiteralValueAtPath(path, recursionTracker, origin) {10053 if (path.length > 0)10054 return UnknownValue;10055 const leftValue = this.left.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin);10056 if (typeof leftValue === 'symbol')10057 return UnknownValue;10058 const rightValue = this.right.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin);10059 if (typeof rightValue === 'symbol')10060 return UnknownValue;10061 const operatorFunction = binaryOperators[this.operator];10062 if (!operatorFunction)10063 return UnknownValue;10064 return operatorFunction(leftValue, rightValue);10065 }10066 hasEffects(context) {10067 // support some implicit type coercion runtime errors10068 if (this.operator === '+' &&10069 this.parent instanceof ExpressionStatement &&10070 this.left.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) === '') {10071 return true;10072 }10073 return super.hasEffects(context);10074 }10075 hasEffectsOnInteractionAtPath(path, { type }) {10076 return type !== INTERACTION_ACCESSED || path.length > 1;10077 }10078 removeAnnotations(code) {10079 this.left.removeAnnotations(code);10080 }10081 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {10082 this.left.render(code, options, { renderedSurroundingElement });10083 this.right.render(code, options);10084 }10085 }10086 10087 class BreakStatement extends NodeBase {10088 hasEffects(context) {10089 if (this.label) {10090 if (!context.ignore.labels.has(this.label.name))10091 return true;10092 context.includedLabels.add(this.label.name);10093 }10094 else {10095 if (!context.ignore.breaks)10096 return true;10097 context.hasBreak = true;10098 }10099 context.brokenFlow = true;10100 return false;10101 }10102 include(context) {10103 this.included = true;10104 if (this.label) {10105 this.label.include();10106 context.includedLabels.add(this.label.name);10107 }10108 else {10109 context.hasBreak = true;10110 }10111 context.brokenFlow = true;10112 }10113 }10114 10115 function renderCallArguments(code, options, node) {10116 if (node.arguments.length > 0) {10117 if (node.arguments[node.arguments.length - 1].included) {10118 for (const argument of node.arguments) {10119 argument.render(code, options);10120 }10121 }10122 else {10123 let lastIncludedIndex = node.arguments.length - 2;10124 while (lastIncludedIndex >= 0 && !node.arguments[lastIncludedIndex].included) {10125 lastIncludedIndex--;10126 }10127 if (lastIncludedIndex >= 0) {10128 for (let index = 0; index <= lastIncludedIndex; index++) {10129 node.arguments[index].render(code, options);10130 }10131 code.remove(findFirstOccurrenceOutsideComment(code.original, ',', node.arguments[lastIncludedIndex].end), node.end - 1);10132 }10133 else {10134 code.remove(findFirstOccurrenceOutsideComment(code.original, '(', node.callee.end) + 1, node.end - 1);10135 }10136 }10137 }10138 }10139 10140 class Literal extends NodeBase {10141 deoptimizeArgumentsOnInteractionAtPath() { }10142 getLiteralValueAtPath(path) {10143 if (path.length > 0 ||10144 // unknown literals can also be null but do not start with an "n"10145 (this.value === null && this.scope.context.code.charCodeAt(this.start) !== 110) ||10146 typeof this.value === 'bigint' ||10147 // to support shims for regular expressions10148 this.scope.context.code.charCodeAt(this.start) === 47) {10149 return UnknownValue;10150 }10151 return this.value;10152 }10153 getReturnExpressionWhenCalledAtPath(path) {10154 if (path.length !== 1)10155 return UNKNOWN_RETURN_EXPRESSION;10156 return getMemberReturnExpressionWhenCalled(this.members, path[0]);10157 }10158 hasEffectsOnInteractionAtPath(path, interaction, context) {10159 switch (interaction.type) {10160 case INTERACTION_ACCESSED: {10161 return path.length > (this.value === null ? 0 : 1);10162 }10163 case INTERACTION_ASSIGNED: {10164 return true;10165 }10166 case INTERACTION_CALLED: {10167 if (this.included &&10168 this.value instanceof RegExp &&10169 (this.value.global || this.value.sticky)) {10170 return true;10171 }10172 return (path.length !== 1 ||10173 hasMemberEffectWhenCalled(this.members, path[0], interaction, context));10174 }10175 }10176 }10177 initialise() {10178 super.initialise();10179 this.members = getLiteralMembersForValue(this.value);10180 }10181 parseNode(esTreeNode) {10182 this.value = esTreeNode.value;10183 this.regex = esTreeNode.regex;10184 return super.parseNode(esTreeNode);10185 }10186 render(code) {10187 if (typeof this.value === 'string') {10188 code.indentExclusionRanges.push([this.start + 1, this.end - 1]);10189 }10190 }10191 }10192 10193 function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {10194 if ('getLiteralValueAtPathAsChainElement' in object) {10195 const calleeValue = object.getLiteralValueAtPathAsChainElement(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin);10196 if (calleeValue === IS_SKIPPED_CHAIN || (element.optional && calleeValue == null)) {10197 return IS_SKIPPED_CHAIN;10198 }10199 }10200 else if (element.optional &&10201 object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin) == null) {10202 return IS_SKIPPED_CHAIN;10203 }10204 return element.getLiteralValueAtPath(path, recursionTracker, origin);10205 }10206 10207 // To avoid infinite recursions10208 const MAX_PATH_DEPTH = 7;10209 function getResolvablePropertyKey(memberExpression) {10210 return memberExpression.computed10211 ? getResolvableComputedPropertyKey(memberExpression.property)10212 : memberExpression.property.name;10213 }10214 function getResolvableComputedPropertyKey(propertyKey) {10215 if (propertyKey instanceof Literal) {10216 return String(propertyKey.value);10217 }10218 return null;10219 }10220 function getPathIfNotComputed(memberExpression) {10221 const nextPathKey = memberExpression.propertyKey;10222 const object = memberExpression.object;10223 if (typeof nextPathKey === 'string') {10224 if (object instanceof Identifier) {10225 return [10226 { key: object.name, pos: object.start },10227 { key: nextPathKey, pos: memberExpression.property.start }10228 ];10229 }10230 if (object instanceof MemberExpression) {10231 const parentPath = getPathIfNotComputed(object);10232 return (parentPath && [...parentPath, { key: nextPathKey, pos: memberExpression.property.start }]);10233 }10234 }10235 return null;10236 }10237 function getStringFromPath(path) {10238 let pathString = path[0].key;10239 for (let index = 1; index < path.length; index++) {10240 pathString += '.' + path[index].key;10241 }10242 return pathString;10243 }10244 class MemberExpression extends NodeBase {10245 constructor() {10246 super(...arguments);10247 this.variable = null;10248 this.expressionsToBeDeoptimized = [];10249 }10250 get computed() {10251 return isFlagSet(this.flags, 1024 /* Flag.computed */);10252 }10253 set computed(value) {10254 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value);10255 }10256 get optional() {10257 return isFlagSet(this.flags, 128 /* Flag.optional */);10258 }10259 set optional(value) {10260 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value);10261 }10262 get assignmentDeoptimized() {10263 return isFlagSet(this.flags, 16 /* Flag.assignmentDeoptimized */);10264 }10265 set assignmentDeoptimized(value) {10266 this.flags = setFlag(this.flags, 16 /* Flag.assignmentDeoptimized */, value);10267 }10268 get bound() {10269 return isFlagSet(this.flags, 32 /* Flag.bound */);10270 }10271 set bound(value) {10272 this.flags = setFlag(this.flags, 32 /* Flag.bound */, value);10273 }10274 get isUndefined() {10275 return isFlagSet(this.flags, 64 /* Flag.isUndefined */);10276 }10277 set isUndefined(value) {10278 this.flags = setFlag(this.flags, 64 /* Flag.isUndefined */, value);10279 }10280 bind() {10281 this.bound = true;10282 const path = getPathIfNotComputed(this);10283 const baseVariable = path && this.scope.findVariable(path[0].key);10284 if (baseVariable?.isNamespace) {10285 const resolvedVariable = resolveNamespaceVariables(baseVariable, path.slice(1), this.scope.context);10286 if (!resolvedVariable) {10287 super.bind();10288 }10289 else if (resolvedVariable === 'undefined') {10290 this.isUndefined = true;10291 }10292 else {10293 this.variable = resolvedVariable;10294 this.scope.addNamespaceMemberAccess(getStringFromPath(path), resolvedVariable);10295 }10296 }10297 else {10298 super.bind();10299 }10300 }10301 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10302 if (this.variable) {10303 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);10304 }10305 else if (!this.isUndefined) {10306 if (path.length < MAX_PATH_DEPTH) {10307 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);10308 }10309 else {10310 deoptimizeInteraction(interaction);10311 }10312 }10313 }10314 deoptimizeCache() {10315 const { expressionsToBeDeoptimized, object } = this;10316 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;10317 this.propertyKey = UnknownKey;10318 object.deoptimizePath(UNKNOWN_PATH);10319 for (const expression of expressionsToBeDeoptimized) {10320 expression.deoptimizeCache();10321 }10322 }10323 deoptimizePath(path) {10324 if (path.length === 0)10325 this.disallowNamespaceReassignment();10326 if (this.variable) {10327 this.variable.deoptimizePath(path);10328 }10329 else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) {10330 const propertyKey = this.getPropertyKey();10331 this.object.deoptimizePath([10332 propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,10333 ...path10334 ]);10335 }10336 }10337 getLiteralValueAtPath(path, recursionTracker, origin) {10338 if (this.variable) {10339 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin);10340 }10341 if (this.isUndefined) {10342 return undefined;10343 }10344 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {10345 this.expressionsToBeDeoptimized.push(origin);10346 return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin);10347 }10348 return UnknownValue;10349 }10350 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) {10351 if (this.variable) {10352 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin);10353 }10354 if (this.isUndefined) {10355 return undefined;10356 }10357 return getChainElementLiteralValueAtPath(this, this.object, path, recursionTracker, origin);10358 }10359 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {10360 if (this.variable) {10361 return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);10362 }10363 if (this.isUndefined) {10364 return [UNDEFINED_EXPRESSION, false];10365 }10366 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {10367 this.expressionsToBeDeoptimized.push(origin);10368 return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);10369 }10370 return UNKNOWN_RETURN_EXPRESSION;10371 }10372 hasEffects(context) {10373 if (!this.deoptimized)10374 this.applyDeoptimizations();10375 return (this.property.hasEffects(context) ||10376 this.object.hasEffects(context) ||10377 this.hasAccessEffect(context));10378 }10379 hasEffectsAsChainElement(context) {10380 if (this.variable || this.isUndefined)10381 return this.hasEffects(context);10382 const objectHasEffects = 'hasEffectsAsChainElement' in this.object10383 ? this.object.hasEffectsAsChainElement(context)10384 : this.object.hasEffects(context);10385 if (objectHasEffects === IS_SKIPPED_CHAIN)10386 return IS_SKIPPED_CHAIN;10387 if (this.optional &&10388 this.object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) {10389 return objectHasEffects || IS_SKIPPED_CHAIN;10390 }10391 // We only apply deoptimizations lazily once we know we are not skipping10392 if (!this.deoptimized)10393 this.applyDeoptimizations();10394 return this.property.hasEffects(context) || this.hasAccessEffect(context);10395 }10396 hasEffectsAsAssignmentTarget(context, checkAccess) {10397 if (checkAccess && !this.deoptimized)10398 this.applyDeoptimizations();10399 if (!this.assignmentDeoptimized)10400 this.applyAssignmentDeoptimization();10401 return (this.property.hasEffects(context) ||10402 this.object.hasEffects(context) ||10403 (checkAccess && this.hasAccessEffect(context)) ||10404 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));10405 }10406 hasEffectsOnInteractionAtPath(path, interaction, context) {10407 if (this.variable) {10408 return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);10409 }10410 if (this.isUndefined) {10411 return true;10412 }10413 if (path.length < MAX_PATH_DEPTH) {10414 return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);10415 }10416 return true;10417 }10418 include(context, includeChildrenRecursively) {10419 if (!this.deoptimized)10420 this.applyDeoptimizations();10421 this.includeProperties(context, includeChildrenRecursively);10422 }10423 includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {10424 if (!this.assignmentDeoptimized)10425 this.applyAssignmentDeoptimization();10426 if (deoptimizeAccess) {10427 this.include(context, includeChildrenRecursively);10428 }10429 else {10430 this.includeProperties(context, includeChildrenRecursively);10431 }10432 }10433 includeCallArguments(context, parameters) {10434 if (this.variable) {10435 this.variable.includeCallArguments(context, parameters);10436 }10437 else {10438 super.includeCallArguments(context, parameters);10439 }10440 }10441 initialise() {10442 super.initialise();10443 this.propertyKey = getResolvablePropertyKey(this);10444 this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };10445 }10446 render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = parseAst_js.BLANK) {10447 if (this.variable || this.isUndefined) {10448 const { snippets: { getPropertyAccess } } = options;10449 let replacement = this.variable ? this.variable.getName(getPropertyAccess) : 'undefined';10450 if (renderedParentType && isCalleeOfRenderedParent)10451 replacement = '0, ' + replacement;10452 code.overwrite(this.start, this.end, replacement, {10453 contentOnly: true,10454 storeName: true10455 });10456 }10457 else {10458 if (renderedParentType && isCalleeOfRenderedParent) {10459 code.appendRight(this.start, '0, ');10460 }10461 this.object.render(code, options, { renderedSurroundingElement });10462 this.property.render(code, options);10463 }10464 }10465 setAssignedValue(value) {10466 this.assignmentInteraction = {10467 args: [this.object, value],10468 type: INTERACTION_ASSIGNED10469 };10470 }10471 applyDeoptimizations() {10472 this.deoptimized = true;10473 const { propertyReadSideEffects } = this.scope.context.options10474 .treeshake;10475 if (10476 // Namespaces are not bound and should not be deoptimized10477 this.bound &&10478 propertyReadSideEffects &&10479 !(this.variable || this.isUndefined)) {10480 const propertyKey = this.getPropertyKey();10481 this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);10482 this.scope.context.requestTreeshakingPass();10483 }10484 if (this.variable) {10485 this.variable.addUsedPlace(this);10486 this.scope.context.requestTreeshakingPass();10487 }10488 }10489 applyAssignmentDeoptimization() {10490 this.assignmentDeoptimized = true;10491 const { propertyReadSideEffects } = this.scope.context.options10492 .treeshake;10493 if (10494 // Namespaces are not bound and should not be deoptimized10495 this.bound &&10496 propertyReadSideEffects &&10497 !(this.variable || this.isUndefined)) {10498 this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);10499 this.scope.context.requestTreeshakingPass();10500 }10501 }10502 disallowNamespaceReassignment() {10503 if (this.object instanceof Identifier) {10504 const variable = this.scope.findVariable(this.object.name);10505 if (variable.isNamespace) {10506 if (this.variable) {10507 this.scope.context.includeVariableInModule(this.variable);10508 }10509 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);10510 }10511 }10512 }10513 getPropertyKey() {10514 if (this.propertyKey === null) {10515 this.propertyKey = UnknownKey;10516 const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);10517 return (this.propertyKey =10518 value === SymbolToStringTag10519 ? value10520 : typeof value === 'symbol'10521 ? UnknownKey10522 : String(value));10523 }10524 return this.propertyKey;10525 }10526 hasAccessEffect(context) {10527 const { propertyReadSideEffects } = this.scope.context.options10528 .treeshake;10529 return (!(this.variable || this.isUndefined) &&10530 propertyReadSideEffects &&10531 (propertyReadSideEffects === 'always' ||10532 this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));10533 }10534 includeProperties(context, includeChildrenRecursively) {10535 if (!this.included) {10536 this.included = true;10537 if (this.variable) {10538 this.scope.context.includeVariableInModule(this.variable);10539 }10540 }10541 this.object.include(context, includeChildrenRecursively);10542 this.property.include(context, includeChildrenRecursively);10543 }10544 }10545 function resolveNamespaceVariables(baseVariable, path, astContext) {10546 if (path.length === 0)10547 return baseVariable;10548 if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable)10549 return null;10550 const exportName = path[0].key;10551 const variable = baseVariable.context.traceExport(exportName);10552 if (!variable) {10553 if (path.length === 1) {10554 const fileName = baseVariable.context.fileName;10555 astContext.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingExport(exportName, astContext.module.id, fileName), path[0].pos);10556 return 'undefined';10557 }10558 return null;10559 }10560 return resolveNamespaceVariables(variable, path.slice(1), astContext);10561 }10562 10563 class CallExpressionBase extends NodeBase {10564 constructor() {10565 super(...arguments);10566 this.returnExpression = null;10567 this.deoptimizableDependentExpressions = [];10568 this.expressionsToBeDeoptimized = new Set();10569 }10570 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10571 const { args } = interaction;10572 const [returnExpression, isPure] = this.getReturnExpression(recursionTracker);10573 if (isPure)10574 return;10575 const deoptimizedExpressions = args.filter(expression => !!expression && expression !== UNKNOWN_EXPRESSION);10576 if (deoptimizedExpressions.length === 0)10577 return;10578 if (returnExpression === UNKNOWN_EXPRESSION) {10579 for (const expression of deoptimizedExpressions) {10580 expression.deoptimizePath(UNKNOWN_PATH);10581 }10582 }10583 else {10584 recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {10585 for (const expression of deoptimizedExpressions) {10586 this.expressionsToBeDeoptimized.add(expression);10587 }10588 returnExpression.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);10589 }, null);10590 }10591 }10592 deoptimizeCache() {10593 if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) {10594 this.returnExpression = UNKNOWN_RETURN_EXPRESSION;10595 const { deoptimizableDependentExpressions, expressionsToBeDeoptimized } = this;10596 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_SET;10597 this.deoptimizableDependentExpressions = parseAst_js.EMPTY_ARRAY;10598 for (const expression of deoptimizableDependentExpressions) {10599 expression.deoptimizeCache();10600 }10601 for (const expression of expressionsToBeDeoptimized) {10602 expression.deoptimizePath(UNKNOWN_PATH);10603 }10604 }10605 }10606 deoptimizePath(path) {10607 if (path.length === 0 ||10608 this.scope.context.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) {10609 return;10610 }10611 const [returnExpression] = this.getReturnExpression();10612 if (returnExpression !== UNKNOWN_EXPRESSION) {10613 returnExpression.deoptimizePath(path);10614 }10615 }10616 getLiteralValueAtPath(path, recursionTracker, origin) {10617 const [returnExpression] = this.getReturnExpression(recursionTracker);10618 if (returnExpression === UNKNOWN_EXPRESSION) {10619 return UnknownValue;10620 }10621 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {10622 this.deoptimizableDependentExpressions.push(origin);10623 return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin);10624 }, UnknownValue);10625 }10626 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {10627 const returnExpression = this.getReturnExpression(recursionTracker);10628 if (returnExpression[0] === UNKNOWN_EXPRESSION) {10629 return returnExpression;10630 }10631 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {10632 this.deoptimizableDependentExpressions.push(origin);10633 const [expression, isPure] = returnExpression[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);10634 return [expression, isPure || returnExpression[1]];10635 }, UNKNOWN_RETURN_EXPRESSION);10636 }10637 hasEffectsOnInteractionAtPath(path, interaction, context) {10638 const { type } = interaction;10639 if (type === INTERACTION_CALLED) {10640 const { args, withNew } = interaction;10641 if ((withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, args, this)) {10642 return false;10643 }10644 }10645 else if ((type === INTERACTION_ASSIGNED10646 ? context.assigned10647 : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) {10648 return false;10649 }10650 const [returnExpression, isPure] = this.getReturnExpression();10651 return ((type === INTERACTION_ASSIGNED || !isPure) &&10652 returnExpression.hasEffectsOnInteractionAtPath(path, interaction, context));10653 }10654 }10655 10656 class CallExpression extends CallExpressionBase {10657 get optional() {10658 return isFlagSet(this.flags, 128 /* Flag.optional */);10659 }10660 set optional(value) {10661 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value);10662 }10663 bind() {10664 super.bind();10665 if (this.callee instanceof Identifier) {10666 const variable = this.scope.findVariable(this.callee.name);10667 if (variable.isNamespace) {10668 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logCannotCallNamespace(this.callee.name), this.start);10669 }10670 if (this.callee.name === 'eval') {10671 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logEval(this.scope.context.module.id), this.start);10672 }10673 }10674 this.interaction = {10675 args: [10676 this.callee instanceof MemberExpression && !this.callee.variable10677 ? this.callee.object10678 : null,10679 ...this.arguments10680 ],10681 type: INTERACTION_CALLED,10682 withNew: false10683 };10684 }10685 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) {10686 return getChainElementLiteralValueAtPath(this, this.callee, path, recursionTracker, origin);10687 }10688 hasEffects(context) {10689 if (!this.deoptimized)10690 this.applyDeoptimizations();10691 for (const argument of this.arguments) {10692 if (argument.hasEffects(context))10693 return true;10694 }10695 if (this.annotationPure) {10696 return false;10697 }10698 return (this.callee.hasEffects(context) ||10699 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));10700 }10701 hasEffectsAsChainElement(context) {10702 const calleeHasEffects = 'hasEffectsAsChainElement' in this.callee10703 ? this.callee.hasEffectsAsChainElement(context)10704 : this.callee.hasEffects(context);10705 if (calleeHasEffects === IS_SKIPPED_CHAIN)10706 return IS_SKIPPED_CHAIN;10707 if (this.optional &&10708 this.callee.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) {10709 return (!this.annotationPure && calleeHasEffects) || IS_SKIPPED_CHAIN;10710 }10711 // We only apply deoptimizations lazily once we know we are not skipping10712 if (!this.deoptimized)10713 this.applyDeoptimizations();10714 for (const argument of this.arguments) {10715 if (argument.hasEffects(context))10716 return true;10717 }10718 return (!this.annotationPure &&10719 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));10720 }10721 include(context, includeChildrenRecursively) {10722 if (!this.deoptimized)10723 this.applyDeoptimizations();10724 if (includeChildrenRecursively) {10725 super.include(context, includeChildrenRecursively);10726 if (includeChildrenRecursively === INCLUDE_PARAMETERS &&10727 this.callee instanceof Identifier &&10728 this.callee.variable) {10729 this.callee.variable.markCalledFromTryStatement();10730 }10731 }10732 else {10733 this.included = true;10734 this.callee.include(context, false);10735 }10736 this.callee.includeCallArguments(context, this.arguments);10737 }10738 initialise() {10739 super.initialise();10740 if (this.annotations &&10741 this.scope.context.options.treeshake.annotations) {10742 this.annotationPure = this.annotations.some(comment => comment.type === 'pure');10743 }10744 }10745 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {10746 this.callee.render(code, options, {10747 isCalleeOfRenderedParent: true,10748 renderedSurroundingElement10749 });10750 renderCallArguments(code, options, this);10751 }10752 applyDeoptimizations() {10753 this.deoptimized = true;10754 this.callee.deoptimizeArgumentsOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER);10755 this.scope.context.requestTreeshakingPass();10756 }10757 getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {10758 if (this.returnExpression === null) {10759 this.returnExpression = UNKNOWN_RETURN_EXPRESSION;10760 return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));10761 }10762 return this.returnExpression;10763 }10764 }10765 10766 class CatchClause extends NodeBase {10767 createScope(parentScope) {10768 this.scope = new ParameterScope(parentScope, true);10769 }10770 parseNode(esTreeNode) {10771 const { body, param, type } = esTreeNode;10772 this.type = type;10773 if (param) {10774 this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);10775 this.param.declare('parameter', UNKNOWN_EXPRESSION);10776 }10777 this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);10778 return super.parseNode(esTreeNode);10779 }10780 }10781 CatchClause.prototype.preventChildBlockScope = true;10782 10783 class ChainExpression extends NodeBase {10784 // deoptimizations are not relevant as we are not caching values10785 deoptimizeCache() { }10786 getLiteralValueAtPath(path, recursionTracker, origin) {10787 const literalValue = this.expression.getLiteralValueAtPathAsChainElement(path, recursionTracker, origin);10788 return literalValue === IS_SKIPPED_CHAIN ? undefined : literalValue;10789 }10790 hasEffects(context) {10791 return this.expression.hasEffectsAsChainElement(context) === true;10792 }10793 removeAnnotations(code) {10794 this.expression.removeAnnotations(code);10795 }10796 applyDeoptimizations() { }10797 }10798 10799 class ClassBodyScope extends ChildScope {10800 constructor(parent, classNode) {10801 const { context } = parent;10802 super(parent, context);10803 this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));10804 this.instanceScope = new ChildScope(this, context);10805 this.instanceScope.variables.set('this', new ThisVariable(context));10806 }10807 findLexicalBoundary() {10808 return this;10809 }10810 }10811 10812 class ClassBody extends NodeBase {10813 createScope(parentScope) {10814 this.scope = new ClassBodyScope(parentScope, this.parent);10815 }10816 include(context, includeChildrenRecursively) {10817 this.included = true;10818 this.scope.context.includeVariableInModule(this.scope.thisVariable);10819 for (const definition of this.body) {10820 definition.include(context, includeChildrenRecursively);10821 }10822 }10823 parseNode(esTreeNode) {10824 const body = (this.body = []);10825 for (const definition of esTreeNode.body) {10826 body.push(new (this.scope.context.getNodeConstructor(definition.type))(this, definition.static ? this.scope : this.scope.instanceScope).parseNode(definition));10827 }10828 return super.parseNode(esTreeNode);10829 }10830 applyDeoptimizations() { }10831 }10832 10833 function checkEffectForNodes(nodes, context) {10834 for (const node of nodes) {10835 if (node.hasEffects(context)) {10836 return true;10837 }10838 }10839 return false;10840 }10841 10842 class MethodBase extends NodeBase {10843 constructor() {10844 super(...arguments);10845 this.accessedValue = null;10846 }10847 get computed() {10848 return isFlagSet(this.flags, 1024 /* Flag.computed */);10849 }10850 set computed(value) {10851 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value);10852 }10853 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10854 if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) {10855 return this.value.deoptimizeArgumentsOnInteractionAtPath({10856 args: interaction.args,10857 type: INTERACTION_CALLED,10858 withNew: false10859 }, EMPTY_PATH, recursionTracker);10860 }10861 if (interaction.type === INTERACTION_ASSIGNED && this.kind === 'set' && path.length === 0) {10862 return this.value.deoptimizeArgumentsOnInteractionAtPath({10863 args: interaction.args,10864 type: INTERACTION_CALLED,10865 withNew: false10866 }, EMPTY_PATH, recursionTracker);10867 }10868 this.getAccessedValue()[0].deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);10869 }10870 // As getter properties directly receive their values from fixed function10871 // expressions, there is no known situation where a getter is deoptimized.10872 deoptimizeCache() { }10873 deoptimizePath(path) {10874 this.getAccessedValue()[0].deoptimizePath(path);10875 }10876 getLiteralValueAtPath(path, recursionTracker, origin) {10877 return this.getAccessedValue()[0].getLiteralValueAtPath(path, recursionTracker, origin);10878 }10879 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {10880 return this.getAccessedValue()[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);10881 }10882 hasEffects(context) {10883 return this.key.hasEffects(context);10884 }10885 hasEffectsOnInteractionAtPath(path, interaction, context) {10886 if (this.kind === 'get' && interaction.type === INTERACTION_ACCESSED && path.length === 0) {10887 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {10888 args: interaction.args,10889 type: INTERACTION_CALLED,10890 withNew: false10891 }, context);10892 }10893 // setters are only called for empty paths10894 if (this.kind === 'set' && interaction.type === INTERACTION_ASSIGNED) {10895 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {10896 args: interaction.args,10897 type: INTERACTION_CALLED,10898 withNew: false10899 }, context);10900 }10901 return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);10902 }10903 applyDeoptimizations() { }10904 getAccessedValue() {10905 if (this.accessedValue === null) {10906 if (this.kind === 'get') {10907 this.accessedValue = UNKNOWN_RETURN_EXPRESSION;10908 return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this));10909 }10910 else {10911 return (this.accessedValue = [this.value, false]);10912 }10913 }10914 return this.accessedValue;10915 }10916 }10917 10918 class MethodDefinition extends MethodBase {10919 hasEffects(context) {10920 return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);10921 }10922 applyDeoptimizations() { }10923 }10924 10925 class StaticBlock extends NodeBase {10926 createScope(parentScope) {10927 this.scope = new BlockScope(parentScope);10928 }10929 hasEffects(context) {10930 for (const node of this.body) {10931 if (node.hasEffects(context))10932 return true;10933 }10934 return false;10935 }10936 include(context, includeChildrenRecursively) {10937 this.included = true;10938 for (const node of this.body) {10939 if (includeChildrenRecursively || node.shouldBeIncluded(context))10940 node.include(context, includeChildrenRecursively);10941 }10942 }10943 render(code, options) {10944 if (this.body.length > 0) {10945 const bodyStartPos = findFirstOccurrenceOutsideComment(code.original.slice(this.start, this.end), '{') + 1;10946 renderStatementList(this.body, code, this.start + bodyStartPos, this.end - 1, options);10947 }10948 else {10949 super.render(code, options);10950 }10951 }10952 }10953 function isStaticBlock(statement) {10954 return statement.type === parseAst_js.StaticBlock;10955 }10956 10957 class ObjectMember extends ExpressionEntity {10958 constructor(object, key) {10959 super();10960 this.object = object;10961 this.key = key;10962 }10963 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10964 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);10965 }10966 deoptimizePath(path) {10967 this.object.deoptimizePath([this.key, ...path]);10968 }10969 getLiteralValueAtPath(path, recursionTracker, origin) {10970 return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);10971 }10972 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {10973 return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);10974 }10975 hasEffectsOnInteractionAtPath(path, interaction, context) {10976 return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);10977 }10978 }10979 10980 class ClassNode extends NodeBase {10981 constructor() {10982 super(...arguments);10983 this.objectEntity = null;10984 }10985 createScope(parentScope) {10986 this.scope = new ChildScope(parentScope, parentScope.context);10987 }10988 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {10989 this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);10990 }10991 deoptimizeCache() {10992 this.getObjectEntity().deoptimizeAllProperties();10993 }10994 deoptimizePath(path) {10995 this.getObjectEntity().deoptimizePath(path);10996 }10997 getLiteralValueAtPath(path, recursionTracker, origin) {10998 return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);10999 }11000 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {11001 return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);11002 }11003 hasEffects(context) {11004 if (!this.deoptimized)11005 this.applyDeoptimizations();11006 const initEffect = this.superClass?.hasEffects(context) || this.body.hasEffects(context);11007 this.id?.markDeclarationReached();11008 return initEffect || super.hasEffects(context) || checkEffectForNodes(this.decorators, context);11009 }11010 hasEffectsOnInteractionAtPath(path, interaction, context) {11011 return interaction.type === INTERACTION_CALLED && path.length === 011012 ? !interaction.withNew ||11013 (this.classConstructor === null11014 ? this.superClass?.hasEffectsOnInteractionAtPath(path, interaction, context)11015 : this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)) ||11016 false11017 : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);11018 }11019 include(context, includeChildrenRecursively) {11020 if (!this.deoptimized)11021 this.applyDeoptimizations();11022 this.included = true;11023 this.superClass?.include(context, includeChildrenRecursively);11024 this.body.include(context, includeChildrenRecursively);11025 for (const decorator of this.decorators)11026 decorator.include(context, includeChildrenRecursively);11027 if (this.id) {11028 this.id.markDeclarationReached();11029 this.id.include();11030 }11031 }11032 initialise() {11033 super.initialise();11034 this.id?.declare('class', this);11035 for (const method of this.body.body) {11036 if (method instanceof MethodDefinition && method.kind === 'constructor') {11037 this.classConstructor = method;11038 return;11039 }11040 }11041 this.classConstructor = null;11042 }11043 applyDeoptimizations() {11044 this.deoptimized = true;11045 for (const definition of this.body.body) {11046 if (!isStaticBlock(definition) &&11047 !(definition.static ||11048 (definition instanceof MethodDefinition && definition.kind === 'constructor'))) {11049 // Calls to methods are not tracked, ensure that the return value is deoptimized11050 definition.deoptimizePath(UNKNOWN_PATH);11051 }11052 }11053 this.scope.context.requestTreeshakingPass();11054 }11055 getObjectEntity() {11056 if (this.objectEntity !== null) {11057 return this.objectEntity;11058 }11059 const staticProperties = [];11060 const dynamicMethods = [];11061 for (const definition of this.body.body) {11062 if (isStaticBlock(definition))11063 continue;11064 const properties = definition.static ? staticProperties : dynamicMethods;11065 const definitionKind = definition.kind;11066 // Note that class fields do not end up on the prototype11067 if (properties === dynamicMethods && !definitionKind)11068 continue;11069 const kind = definitionKind === 'set' || definitionKind === 'get' ? definitionKind : 'init';11070 let key;11071 if (definition.computed) {11072 const keyValue = definition.key.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);11073 if (typeof keyValue === 'symbol') {11074 properties.push({ key: UnknownKey, kind, property: definition });11075 continue;11076 }11077 else {11078 key = String(keyValue);11079 }11080 }11081 else {11082 key =11083 definition.key instanceof Identifier11084 ? definition.key.name11085 : String(definition.key.value);11086 }11087 properties.push({ key, kind, property: definition });11088 }11089 staticProperties.unshift({11090 key: 'prototype',11091 kind: 'init',11092 property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)11093 });11094 return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));11095 }11096 }11097 11098 class ClassDeclaration extends ClassNode {11099 initialise() {11100 super.initialise();11101 if (this.id !== null) {11102 this.id.variable.isId = true;11103 }11104 }11105 parseNode(esTreeNode) {11106 if (esTreeNode.id !== null) {11107 this.id = new Identifier(this, this.scope.parent).parseNode(esTreeNode.id);11108 }11109 return super.parseNode(esTreeNode);11110 }11111 render(code, options) {11112 const { exportNamesByVariable, format, snippets: { _, getPropertyAccess } } = options;11113 if (this.id) {11114 const { variable, name } = this.id;11115 if (format === 'system' && exportNamesByVariable.has(variable)) {11116 code.appendLeft(this.end, `${_}${getSystemExportStatement([variable], options)};`);11117 }11118 const renderedVariable = variable.getName(getPropertyAccess);11119 if (renderedVariable !== name) {11120 this.decorators.map(decorator => decorator.render(code, options));11121 this.superClass?.render(code, options);11122 this.body.render(code, {11123 ...options,11124 useOriginalName: (_variable) => _variable === variable11125 });11126 code.prependRight(this.start, `let ${renderedVariable}${_}=${_}`);11127 code.prependLeft(this.end, ';');11128 return;11129 }11130 }11131 super.render(code, options);11132 }11133 applyDeoptimizations() {11134 super.applyDeoptimizations();11135 const { id, scope } = this;11136 if (id) {11137 const { name, variable } = id;11138 for (const accessedVariable of scope.accessedOutsideVariables.values()) {11139 if (accessedVariable !== variable) {11140 accessedVariable.forbidName(name);11141 }11142 }11143 }11144 }11145 }11146 11147 class ClassExpression extends ClassNode {11148 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) {11149 super.render(code, options);11150 if (renderedSurroundingElement === parseAst_js.ExpressionStatement) {11151 code.appendRight(this.start, '(');11152 code.prependLeft(this.end, ')');11153 }11154 }11155 }11156 11157 class MultiExpression extends ExpressionEntity {11158 constructor(expressions) {11159 super();11160 this.expressions = expressions;11161 }11162 deoptimizePath(path) {11163 for (const expression of this.expressions) {11164 expression.deoptimizePath(path);11165 }11166 }11167 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {11168 return [11169 new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])),11170 false11171 ];11172 }11173 hasEffectsOnInteractionAtPath(path, interaction, context) {11174 for (const expression of this.expressions) {11175 if (expression.hasEffectsOnInteractionAtPath(path, interaction, context))11176 return true;11177 }11178 return false;11179 }11180 }11181 11182 class ConditionalExpression extends NodeBase {11183 constructor() {11184 super(...arguments);11185 this.expressionsToBeDeoptimized = [];11186 this.usedBranch = null;11187 }11188 get isBranchResolutionAnalysed() {11189 return isFlagSet(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */);11190 }11191 set isBranchResolutionAnalysed(value) {11192 this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value);11193 }11194 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {11195 this.consequent.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);11196 this.alternate.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);11197 }11198 deoptimizeCache() {11199 if (this.usedBranch !== null) {11200 const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;11201 this.usedBranch = null;11202 unusedBranch.deoptimizePath(UNKNOWN_PATH);11203 const { expressionsToBeDeoptimized } = this;11204 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY;11205 for (const expression of expressionsToBeDeoptimized) {11206 expression.deoptimizeCache();11207 }11208 }11209 }11210 deoptimizePath(path) {11211 const usedBranch = this.getUsedBranch();11212 if (usedBranch) {11213 usedBranch.deoptimizePath(path);11214 }11215 else {11216 this.consequent.deoptimizePath(path);11217 this.alternate.deoptimizePath(path);11218 }11219 }11220 getLiteralValueAtPath(path, recursionTracker, origin) {11221 const usedBranch = this.getUsedBranch();11222 if (!usedBranch)11223 return UnknownValue;11224 this.expressionsToBeDeoptimized.push(origin);11225 return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);11226 }11227 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {11228 const usedBranch = this.getUsedBranch();11229 if (!usedBranch)11230 return [11231 new MultiExpression([11232 this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],11233 this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]11234 ]),11235 false11236 ];11237 this.expressionsToBeDeoptimized.push(origin);11238 return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);11239 }11240 hasEffects(context) {11241 if (this.test.hasEffects(context))11242 return true;11243 const usedBranch = this.getUsedBranch();11244 if (!usedBranch) {11245 return this.consequent.hasEffects(context) || this.alternate.hasEffects(context);11246 }11247 return usedBranch.hasEffects(context);11248 }11249 hasEffectsOnInteractionAtPath(path, interaction, context) {11250 const usedBranch = this.getUsedBranch();11251 if (!usedBranch) {11252 return (this.consequent.hasEffectsOnInteractionAtPath(path, interaction, context) ||11253 this.alternate.hasEffectsOnInteractionAtPath(path, interaction, context));11254 }11255 return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);11256 }11257 include(context, includeChildrenRecursively) {11258 this.included = true;11259 const usedBranch = this.getUsedBranch();11260 if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {11261 this.test.include(context, includeChildrenRecursively);11262 this.consequent.include(context, includeChildrenRecursively);11263 this.alternate.include(context, includeChildrenRecursively);11264 }11265 else {11266 usedBranch.include(context, includeChildrenRecursively);11267 }11268 }11269 includeCallArguments(context, parameters) {11270 const usedBranch = this.getUsedBranch();11271 if (usedBranch) {11272 usedBranch.includeCallArguments(context, parameters);11273 }11274 else {11275 this.consequent.includeCallArguments(context, parameters);11276 this.alternate.includeCallArguments(context, parameters);11277 }11278 }11279 removeAnnotations(code) {11280 this.test.removeAnnotations(code);11281 }11282 render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) {11283 const usedBranch = this.getUsedBranch();11284 if (this.test.included) {11285 this.test.render(code, options, { renderedSurroundingElement });11286 this.consequent.render(code, options);11287 this.alternate.render(code, options);11288 }11289 else {11290 const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);11291 const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included11292 ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)11293 : colonPos) + 1);11294 if (preventASI) {11295 removeLineBreaks(code, inclusionStart, usedBranch.start);11296 }11297 code.remove(this.start, inclusionStart);11298 if (this.consequent.included) {11299 code.remove(colonPos, this.end);11300 }11301 this.test.removeAnnotations(code);11302 usedBranch.render(code, options, {11303 isCalleeOfRenderedParent,11304 preventASI: true,11305 renderedParentType: renderedParentType || this.parent.type,11306 renderedSurroundingElement: renderedSurroundingElement || this.parent.type11307 });11308 }11309 }11310 getUsedBranch() {11311 if (this.isBranchResolutionAnalysed) {11312 return this.usedBranch;11313 }11314 this.isBranchResolutionAnalysed = true;11315 const testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);11316 return typeof testValue === 'symbol'11317 ? null11318 : (this.usedBranch = testValue ? this.consequent : this.alternate);11319 }11320 }11321 11322 class ContinueStatement extends NodeBase {11323 hasEffects(context) {11324 if (this.label) {11325 if (!context.ignore.labels.has(this.label.name))11326 return true;11327 context.includedLabels.add(this.label.name);11328 }11329 else {11330 if (!context.ignore.continues)11331 return true;11332 context.hasContinue = true;11333 }11334 context.brokenFlow = true;11335 return false;11336 }11337 include(context) {11338 this.included = true;11339 if (this.label) {11340 this.label.include();11341 context.includedLabels.add(this.label.name);11342 }11343 else {11344 context.hasContinue = true;11345 }11346 context.brokenFlow = true;11347 }11348 }11349 11350 class DebuggerStatement extends NodeBase {11351 hasEffects() {11352 return true;11353 }11354 }11355 11356 class Decorator extends NodeBase {11357 hasEffects(context) {11358 return (this.expression.hasEffects(context) ||11359 this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));11360 }11361 }11362 11363 function hasLoopBodyEffects(context, body) {11364 const { brokenFlow, hasBreak, hasContinue, ignore } = context;11365 const { breaks, continues } = ignore;11366 ignore.breaks = true;11367 ignore.continues = true;11368 context.hasBreak = false;11369 context.hasContinue = false;11370 if (body.hasEffects(context))11371 return true;11372 ignore.breaks = breaks;11373 ignore.continues = continues;11374 context.hasBreak = hasBreak;11375 context.hasContinue = hasContinue;11376 context.brokenFlow = brokenFlow;11377 return false;11378 }11379 function includeLoopBody(context, body, includeChildrenRecursively) {11380 const { brokenFlow, hasBreak, hasContinue } = context;11381 context.hasBreak = false;11382 context.hasContinue = false;11383 body.include(context, includeChildrenRecursively, { asSingleStatement: true });11384 context.hasBreak = hasBreak;11385 context.hasContinue = hasContinue;11386 context.brokenFlow = brokenFlow;11387 }11388 11389 class DoWhileStatement extends NodeBase {11390 hasEffects(context) {11391 if (this.test.hasEffects(context))11392 return true;11393 return hasLoopBodyEffects(context, this.body);11394 }11395 include(context, includeChildrenRecursively) {11396 this.included = true;11397 this.test.include(context, includeChildrenRecursively);11398 includeLoopBody(context, this.body, includeChildrenRecursively);11399 }11400 }11401 11402 class EmptyStatement extends NodeBase {11403 hasEffects() {11404 return false;11405 }11406 }11407 11408 class ExportAllDeclaration extends NodeBase {11409 hasEffects() {11410 return false;11411 }11412 initialise() {11413 super.initialise();11414 this.scope.context.addExport(this);11415 }11416 render(code, _options, nodeRenderOptions) {11417 code.remove(nodeRenderOptions.start, nodeRenderOptions.end);11418 }11419 applyDeoptimizations() { }11420 }11421 ExportAllDeclaration.prototype.needsBoundaries = true;11422 11423 7996 class FunctionDeclaration extends FunctionNode { 11424 7997 initialise() { … … 11536 8109 ExportDefaultDeclaration.prototype.needsBoundaries = true; 11537 8110 11538 class ExportNamedDeclaration extends NodeBase { 11539 bind() { 11540 // Do not bind specifiers 11541 this.declaration?.bind(); 11542 } 11543 hasEffects(context) { 11544 return !!this.declaration?.hasEffects(context); 11545 } 11546 initialise() { 11547 super.initialise(); 11548 this.scope.context.addExport(this); 11549 } 11550 removeAnnotations(code) { 11551 this.declaration?.removeAnnotations(code); 11552 } 11553 render(code, options, nodeRenderOptions) { 11554 const { start, end } = nodeRenderOptions; 11555 if (this.declaration === null) { 11556 code.remove(start, end); 11557 } 11558 else { 11559 code.remove(this.start, this.declaration.start); 11560 this.declaration.render(code, options, { end, start }); 11561 } 11562 } 11563 applyDeoptimizations() { } 11564 } 11565 ExportNamedDeclaration.prototype.needsBoundaries = true; 11566 11567 class ExportSpecifier extends NodeBase { 11568 applyDeoptimizations() { } 11569 } 11570 11571 class ForInStatement extends NodeBase { 11572 createScope(parentScope) { 11573 this.scope = new BlockScope(parentScope); 11574 } 11575 hasEffects(context) { 11576 const { body, deoptimized, left, right } = this; 11577 if (!deoptimized) 11578 this.applyDeoptimizations(); 11579 if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context)) 11580 return true; 11581 return hasLoopBodyEffects(context, body); 11582 } 11583 include(context, includeChildrenRecursively) { 11584 const { body, deoptimized, left, right } = this; 11585 if (!deoptimized) 11586 this.applyDeoptimizations(); 11587 this.included = true; 11588 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 11589 right.include(context, includeChildrenRecursively); 11590 includeLoopBody(context, body, includeChildrenRecursively); 11591 } 11592 initialise() { 11593 super.initialise(); 11594 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 11595 } 11596 render(code, options) { 11597 this.left.render(code, options, NO_SEMICOLON); 11598 this.right.render(code, options, NO_SEMICOLON); 11599 // handle no space between "in" and the right side 11600 if (code.original.charCodeAt(this.right.start - 1) === 110 /* n */) { 11601 code.prependLeft(this.right.start, ' '); 11602 } 11603 this.body.render(code, options); 11604 } 11605 applyDeoptimizations() { 11606 this.deoptimized = true; 11607 this.left.deoptimizePath(EMPTY_PATH); 11608 this.scope.context.requestTreeshakingPass(); 11609 } 11610 } 11611 11612 class ForOfStatement extends NodeBase { 11613 get await() { 11614 return isFlagSet(this.flags, 131072 /* Flag.await */); 11615 } 11616 set await(value) { 11617 this.flags = setFlag(this.flags, 131072 /* Flag.await */, value); 11618 } 11619 createScope(parentScope) { 11620 this.scope = new BlockScope(parentScope); 11621 } 11622 hasEffects() { 11623 if (!this.deoptimized) 11624 this.applyDeoptimizations(); 11625 // Placeholder until proper Symbol.Iterator support 11626 return true; 11627 } 11628 include(context, includeChildrenRecursively) { 11629 const { body, deoptimized, left, right } = this; 11630 if (!deoptimized) 11631 this.applyDeoptimizations(); 11632 this.included = true; 11633 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 11634 right.include(context, includeChildrenRecursively); 11635 includeLoopBody(context, body, includeChildrenRecursively); 11636 } 11637 initialise() { 11638 super.initialise(); 11639 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 11640 } 11641 render(code, options) { 11642 this.left.render(code, options, NO_SEMICOLON); 11643 this.right.render(code, options, NO_SEMICOLON); 11644 // handle no space between "of" and the right side 11645 if (code.original.charCodeAt(this.right.start - 1) === 102 /* f */) { 11646 code.prependLeft(this.right.start, ' '); 11647 } 11648 this.body.render(code, options); 11649 } 11650 applyDeoptimizations() { 11651 this.deoptimized = true; 11652 this.left.deoptimizePath(EMPTY_PATH); 11653 this.right.deoptimizePath(UNKNOWN_PATH); 11654 this.scope.context.requestTreeshakingPass(); 11655 } 11656 } 11657 11658 class ForStatement extends NodeBase { 11659 createScope(parentScope) { 11660 this.scope = new BlockScope(parentScope); 11661 } 11662 hasEffects(context) { 11663 if (this.init?.hasEffects(context) || 11664 this.test?.hasEffects(context) || 11665 this.update?.hasEffects(context)) { 11666 return true; 11667 } 11668 return hasLoopBodyEffects(context, this.body); 11669 } 11670 include(context, includeChildrenRecursively) { 11671 this.included = true; 11672 this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true }); 11673 this.test?.include(context, includeChildrenRecursively); 11674 this.update?.include(context, includeChildrenRecursively); 11675 includeLoopBody(context, this.body, includeChildrenRecursively); 11676 } 11677 render(code, options) { 11678 this.init?.render(code, options, NO_SEMICOLON); 11679 this.test?.render(code, options, NO_SEMICOLON); 11680 this.update?.render(code, options, NO_SEMICOLON); 11681 this.body.render(code, options); 11682 } 11683 } 11684 11685 class FunctionExpression extends FunctionNode { 11686 createScope(parentScope) { 11687 super.createScope((this.idScope = new ChildScope(parentScope, parentScope.context))); 11688 } 11689 parseNode(esTreeNode) { 11690 if (esTreeNode.id !== null) { 11691 this.id = new Identifier(this, this.idScope).parseNode(esTreeNode.id); 11692 } 11693 return super.parseNode(esTreeNode); 11694 } 11695 onlyFunctionCallUsed() { 11696 const isIIFE = this.parent.type === parseAst_js.CallExpression && 11697 this.parent.callee === this && 11698 (this.id === null || this.id.variable.getOnlyFunctionCallUsed()); 11699 return isIIFE || super.onlyFunctionCallUsed(); 11700 } 11701 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 11702 super.render(code, options); 11703 if (renderedSurroundingElement === parseAst_js.ExpressionStatement) { 11704 code.appendRight(this.start, '('); 11705 code.prependLeft(this.end, ')'); 11706 } 11707 } 11708 } 11709 11710 class TrackingScope extends BlockScope { 11711 constructor() { 11712 super(...arguments); 11713 this.hoistedDeclarations = []; 11714 } 11715 addDeclaration(identifier, context, init, kind) { 11716 this.hoistedDeclarations.push(identifier); 11717 return super.addDeclaration(identifier, context, init, kind); 11718 } 11719 } 11720 11721 const unset = Symbol('unset'); 11722 class IfStatement extends NodeBase { 11723 constructor() { 11724 super(...arguments); 11725 this.testValue = unset; 11726 } 11727 deoptimizeCache() { 11728 this.testValue = UnknownValue; 11729 } 11730 hasEffects(context) { 11731 if (this.test.hasEffects(context)) { 11732 return true; 11733 } 11734 const testValue = this.getTestValue(); 11735 if (typeof testValue === 'symbol') { 11736 const { brokenFlow } = context; 11737 if (this.consequent.hasEffects(context)) 11738 return true; 11739 const consequentBrokenFlow = context.brokenFlow; 11740 context.brokenFlow = brokenFlow; 11741 if (this.alternate === null) 11742 return false; 11743 if (this.alternate.hasEffects(context)) 11744 return true; 11745 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 11746 return false; 11747 } 11748 return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context); 11749 } 11750 include(context, includeChildrenRecursively) { 11751 this.included = true; 11752 if (includeChildrenRecursively) { 11753 this.includeRecursively(includeChildrenRecursively, context); 11754 } 11755 else { 11756 const testValue = this.getTestValue(); 11757 if (typeof testValue === 'symbol') { 11758 this.includeUnknownTest(context); 11759 } 11760 else { 11761 this.includeKnownTest(context, testValue); 11762 } 11763 } 11764 } 11765 parseNode(esTreeNode) { 11766 this.consequent = new (this.scope.context.getNodeConstructor(esTreeNode.consequent.type))(this, (this.consequentScope = new TrackingScope(this.scope))).parseNode(esTreeNode.consequent); 11767 if (esTreeNode.alternate) { 11768 this.alternate = new (this.scope.context.getNodeConstructor(esTreeNode.alternate.type))(this, (this.alternateScope = new TrackingScope(this.scope))).parseNode(esTreeNode.alternate); 11769 } 11770 return super.parseNode(esTreeNode); 11771 } 11772 render(code, options) { 11773 const { snippets: { getPropertyAccess } } = options; 11774 // Note that unknown test values are always included 11775 const testValue = this.getTestValue(); 11776 const hoistedDeclarations = []; 11777 const includesIfElse = this.test.included; 11778 const noTreeshake = !this.scope.context.options.treeshake; 11779 if (includesIfElse) { 11780 this.test.render(code, options); 11781 } 11782 else { 11783 code.remove(this.start, this.consequent.start); 11784 } 11785 if (this.consequent.included && (noTreeshake || typeof testValue === 'symbol' || testValue)) { 11786 this.consequent.render(code, options); 11787 } 11788 else { 11789 code.overwrite(this.consequent.start, this.consequent.end, includesIfElse ? ';' : ''); 11790 hoistedDeclarations.push(...this.consequentScope.hoistedDeclarations); 11791 } 11792 if (this.alternate) { 11793 if (this.alternate.included && (noTreeshake || typeof testValue === 'symbol' || !testValue)) { 11794 if (includesIfElse) { 11795 if (code.original.charCodeAt(this.alternate.start - 1) === 101) { 11796 code.prependLeft(this.alternate.start, ' '); 11797 } 11798 } 11799 else { 11800 code.remove(this.consequent.end, this.alternate.start); 11801 } 11802 this.alternate.render(code, options); 11803 } 11804 else { 11805 if (includesIfElse && this.shouldKeepAlternateBranch()) { 11806 code.overwrite(this.alternate.start, this.end, ';'); 11807 } 11808 else { 11809 code.remove(this.consequent.end, this.end); 11810 } 11811 hoistedDeclarations.push(...this.alternateScope.hoistedDeclarations); 11812 } 11813 } 11814 this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess); 11815 } 11816 applyDeoptimizations() { } 11817 getTestValue() { 11818 if (this.testValue === unset) { 11819 return (this.testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)); 11820 } 11821 return this.testValue; 11822 } 11823 includeKnownTest(context, testValue) { 11824 if (this.test.shouldBeIncluded(context)) { 11825 this.test.include(context, false); 11826 } 11827 if (testValue && this.consequent.shouldBeIncluded(context)) { 11828 this.consequent.include(context, false, { asSingleStatement: true }); 11829 } 11830 if (!testValue && this.alternate?.shouldBeIncluded(context)) { 11831 this.alternate.include(context, false, { asSingleStatement: true }); 11832 } 11833 } 11834 includeRecursively(includeChildrenRecursively, context) { 11835 this.test.include(context, includeChildrenRecursively); 11836 this.consequent.include(context, includeChildrenRecursively); 11837 this.alternate?.include(context, includeChildrenRecursively); 11838 } 11839 includeUnknownTest(context) { 11840 this.test.include(context, false); 11841 const { brokenFlow } = context; 11842 let consequentBrokenFlow = false; 11843 if (this.consequent.shouldBeIncluded(context)) { 11844 this.consequent.include(context, false, { asSingleStatement: true }); 11845 consequentBrokenFlow = context.brokenFlow; 11846 context.brokenFlow = brokenFlow; 11847 } 11848 if (this.alternate?.shouldBeIncluded(context)) { 11849 this.alternate.include(context, false, { asSingleStatement: true }); 11850 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 11851 } 11852 } 11853 renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess) { 11854 const hoistedVariables = [ 11855 ...new Set(hoistedDeclarations.map(identifier => { 11856 const variable = identifier.variable; 11857 return variable.included ? variable.getName(getPropertyAccess) : ''; 11858 })) 11859 ] 11860 .filter(Boolean) 11861 .join(', '); 11862 if (hoistedVariables) { 11863 const parentType = this.parent.type; 11864 const needsBraces = parentType !== parseAst_js.Program && parentType !== parseAst_js.BlockStatement; 11865 code.prependRight(this.start, `${needsBraces ? '{ ' : ''}var ${hoistedVariables}; `); 11866 if (needsBraces) { 11867 code.appendLeft(this.end, ` }`); 11868 } 11869 } 11870 } 11871 shouldKeepAlternateBranch() { 11872 let currentParent = this.parent; 11873 do { 11874 if (currentParent instanceof IfStatement && currentParent.alternate) { 11875 return true; 11876 } 11877 if (currentParent instanceof BlockStatement) { 11878 return false; 11879 } 11880 currentParent = currentParent.parent; 11881 } while (currentParent); 11882 return false; 11883 } 11884 } 11885 11886 class ImportAttribute extends NodeBase { 11887 } 11888 11889 class ImportDeclaration extends NodeBase { 11890 // Do not bind specifiers or attributes 11891 bind() { } 11892 hasEffects() { 11893 return false; 11894 } 11895 initialise() { 11896 super.initialise(); 11897 this.scope.context.addImport(this); 11898 } 11899 render(code, _options, nodeRenderOptions) { 11900 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 11901 } 11902 applyDeoptimizations() { } 11903 } 11904 ImportDeclaration.prototype.needsBoundaries = true; 11905 11906 class ImportDefaultSpecifier extends NodeBase { 11907 applyDeoptimizations() { } 8111 const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/; 8112 const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g; 8113 const backSlashRegEx = /\\/g; 8114 function escapeId(id) { 8115 if (!needsEscapeRegEx.test(id)) 8116 return id; 8117 return id.replace(backSlashRegEx, '\\\\').replace(quoteNewlineRegEx, '\\$1'); 11908 8118 } 11909 8119 … … 11946 8156 const HELPER_GENERATORS = { 11947 8157 [DOCUMENT_CURRENT_SCRIPT](_t, { _, n }) { 11948 return `var ${_}${DOCUMENT_CURRENT_SCRIPT}${_}=${_}typeof${_}document${_}!==${_}'undefined'${_}?${_}document.currentScript${_}:${_}null;${n}`;8158 return `var ${DOCUMENT_CURRENT_SCRIPT}${_}=${_}typeof document${_}!==${_}'undefined'${_}?${_}document.currentScript${_}:${_}null;${n}`; 11949 8159 }, 11950 8160 [INTEROP_DEFAULT_COMPAT_VARIABLE](_t, snippets, liveBindings) { … … 12115 8325 } 12116 8326 8327 class Literal extends NodeBase { 8328 deoptimizeArgumentsOnInteractionAtPath() { } 8329 getLiteralValueAtPath(path) { 8330 if (path.length > 0 || 8331 // unknown literals can also be null but do not start with an "n" 8332 (this.value === null && this.scope.context.code.charCodeAt(this.start) !== 110) || 8333 typeof this.value === 'bigint' || 8334 // to support shims for regular expressions 8335 this.scope.context.code.charCodeAt(this.start) === 47) { 8336 return UnknownValue; 8337 } 8338 return this.value; 8339 } 8340 getReturnExpressionWhenCalledAtPath(path) { 8341 if (path.length !== 1) 8342 return UNKNOWN_RETURN_EXPRESSION; 8343 return getMemberReturnExpressionWhenCalled(this.members, path[0]); 8344 } 8345 hasEffectsOnInteractionAtPath(path, interaction, context) { 8346 switch (interaction.type) { 8347 case INTERACTION_ACCESSED: { 8348 return path.length > (this.value === null ? 0 : 1); 8349 } 8350 case INTERACTION_ASSIGNED: { 8351 return true; 8352 } 8353 case INTERACTION_CALLED: { 8354 if (this.included && 8355 this.value instanceof RegExp && 8356 (this.value.global || this.value.sticky)) { 8357 return true; 8358 } 8359 return (path.length !== 1 || 8360 hasMemberEffectWhenCalled(this.members, path[0], interaction, context)); 8361 } 8362 } 8363 } 8364 initialise() { 8365 super.initialise(); 8366 this.members = getLiteralMembersForValue(this.value); 8367 } 8368 parseNode(esTreeNode) { 8369 this.value = esTreeNode.value; 8370 this.regex = esTreeNode.regex; 8371 return super.parseNode(esTreeNode); 8372 } 8373 render(code) { 8374 if (typeof this.value === 'string') { 8375 code.indentExclusionRanges.push([this.start + 1, this.end - 1]); 8376 } 8377 } 8378 } 8379 8380 function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) { 8381 if ('getLiteralValueAtPathAsChainElement' in object) { 8382 const calleeValue = object.getLiteralValueAtPathAsChainElement(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin); 8383 if (calleeValue === IS_SKIPPED_CHAIN || (element.optional && calleeValue == null)) { 8384 return IS_SKIPPED_CHAIN; 8385 } 8386 } 8387 else if (element.optional && 8388 object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin) == null) { 8389 return IS_SKIPPED_CHAIN; 8390 } 8391 return element.getLiteralValueAtPath(path, recursionTracker, origin); 8392 } 8393 8394 // To avoid infinite recursions 8395 const MAX_PATH_DEPTH = 7; 8396 function getResolvablePropertyKey(memberExpression) { 8397 return memberExpression.computed 8398 ? getResolvableComputedPropertyKey(memberExpression.property) 8399 : memberExpression.property.name; 8400 } 8401 function getResolvableComputedPropertyKey(propertyKey) { 8402 if (propertyKey instanceof Literal) { 8403 return String(propertyKey.value); 8404 } 8405 return null; 8406 } 8407 function getPathIfNotComputed(memberExpression) { 8408 const nextPathKey = memberExpression.propertyKey; 8409 const object = memberExpression.object; 8410 if (typeof nextPathKey === 'string') { 8411 if (object instanceof Identifier) { 8412 return [ 8413 { key: object.name, pos: object.start }, 8414 { key: nextPathKey, pos: memberExpression.property.start } 8415 ]; 8416 } 8417 if (object instanceof MemberExpression) { 8418 const parentPath = getPathIfNotComputed(object); 8419 return (parentPath && [...parentPath, { key: nextPathKey, pos: memberExpression.property.start }]); 8420 } 8421 } 8422 return null; 8423 } 8424 function getStringFromPath(path) { 8425 let pathString = path[0].key; 8426 for (let index = 1; index < path.length; index++) { 8427 pathString += '.' + path[index].key; 8428 } 8429 return pathString; 8430 } 8431 class MemberExpression extends NodeBase { 8432 constructor() { 8433 super(...arguments); 8434 this.variable = null; 8435 this.expressionsToBeDeoptimized = []; 8436 } 8437 get computed() { 8438 return isFlagSet(this.flags, 1024 /* Flag.computed */); 8439 } 8440 set computed(value) { 8441 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value); 8442 } 8443 get optional() { 8444 return isFlagSet(this.flags, 128 /* Flag.optional */); 8445 } 8446 set optional(value) { 8447 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value); 8448 } 8449 get assignmentDeoptimized() { 8450 return isFlagSet(this.flags, 16 /* Flag.assignmentDeoptimized */); 8451 } 8452 set assignmentDeoptimized(value) { 8453 this.flags = setFlag(this.flags, 16 /* Flag.assignmentDeoptimized */, value); 8454 } 8455 get bound() { 8456 return isFlagSet(this.flags, 32 /* Flag.bound */); 8457 } 8458 set bound(value) { 8459 this.flags = setFlag(this.flags, 32 /* Flag.bound */, value); 8460 } 8461 get isUndefined() { 8462 return isFlagSet(this.flags, 64 /* Flag.isUndefined */); 8463 } 8464 set isUndefined(value) { 8465 this.flags = setFlag(this.flags, 64 /* Flag.isUndefined */, value); 8466 } 8467 bind() { 8468 this.bound = true; 8469 const path = getPathIfNotComputed(this); 8470 const baseVariable = path && this.scope.findVariable(path[0].key); 8471 if (baseVariable?.isNamespace) { 8472 const resolvedVariable = resolveNamespaceVariables(baseVariable, path.slice(1), this.scope.context); 8473 if (!resolvedVariable) { 8474 super.bind(); 8475 } 8476 else if (resolvedVariable === 'undefined') { 8477 this.isUndefined = true; 8478 } 8479 else { 8480 this.variable = resolvedVariable; 8481 this.scope.addNamespaceMemberAccess(getStringFromPath(path), resolvedVariable); 8482 } 8483 } 8484 else { 8485 super.bind(); 8486 } 8487 } 8488 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 8489 if (this.variable) { 8490 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 8491 } 8492 else if (!this.isUndefined) { 8493 if (path.length < MAX_PATH_DEPTH) { 8494 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker); 8495 } 8496 else { 8497 deoptimizeInteraction(interaction); 8498 } 8499 } 8500 } 8501 deoptimizeCache() { 8502 const { expressionsToBeDeoptimized, object } = this; 8503 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY; 8504 this.propertyKey = UnknownKey; 8505 object.deoptimizePath(UNKNOWN_PATH); 8506 for (const expression of expressionsToBeDeoptimized) { 8507 expression.deoptimizeCache(); 8508 } 8509 } 8510 deoptimizePath(path) { 8511 if (path.length === 0) 8512 this.disallowNamespaceReassignment(); 8513 if (this.variable) { 8514 this.variable.deoptimizePath(path); 8515 } 8516 else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) { 8517 const propertyKey = this.getPropertyKey(); 8518 this.object.deoptimizePath([ 8519 propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey, 8520 ...path 8521 ]); 8522 } 8523 } 8524 getLiteralValueAtPath(path, recursionTracker, origin) { 8525 if (this.variable) { 8526 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin); 8527 } 8528 if (this.isUndefined) { 8529 return undefined; 8530 } 8531 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) { 8532 this.expressionsToBeDeoptimized.push(origin); 8533 return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin); 8534 } 8535 return UnknownValue; 8536 } 8537 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) { 8538 if (this.variable) { 8539 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin); 8540 } 8541 if (this.isUndefined) { 8542 return undefined; 8543 } 8544 return getChainElementLiteralValueAtPath(this, this.object, path, recursionTracker, origin); 8545 } 8546 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 8547 if (this.variable) { 8548 return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 8549 } 8550 if (this.isUndefined) { 8551 return [UNDEFINED_EXPRESSION, false]; 8552 } 8553 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) { 8554 this.expressionsToBeDeoptimized.push(origin); 8555 return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin); 8556 } 8557 return UNKNOWN_RETURN_EXPRESSION; 8558 } 8559 hasEffects(context) { 8560 if (!this.deoptimized) 8561 this.applyDeoptimizations(); 8562 return (this.property.hasEffects(context) || 8563 this.object.hasEffects(context) || 8564 this.hasAccessEffect(context)); 8565 } 8566 hasEffectsAsChainElement(context) { 8567 if (this.variable || this.isUndefined) 8568 return this.hasEffects(context); 8569 const objectHasEffects = 'hasEffectsAsChainElement' in this.object 8570 ? this.object.hasEffectsAsChainElement(context) 8571 : this.object.hasEffects(context); 8572 if (objectHasEffects === IS_SKIPPED_CHAIN) 8573 return IS_SKIPPED_CHAIN; 8574 if (this.optional && 8575 this.object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) { 8576 return objectHasEffects || IS_SKIPPED_CHAIN; 8577 } 8578 // We only apply deoptimizations lazily once we know we are not skipping 8579 if (!this.deoptimized) 8580 this.applyDeoptimizations(); 8581 return objectHasEffects || this.property.hasEffects(context) || this.hasAccessEffect(context); 8582 } 8583 hasEffectsAsAssignmentTarget(context, checkAccess) { 8584 if (checkAccess && !this.deoptimized) 8585 this.applyDeoptimizations(); 8586 if (!this.assignmentDeoptimized) 8587 this.applyAssignmentDeoptimization(); 8588 return (this.property.hasEffects(context) || 8589 this.object.hasEffects(context) || 8590 (checkAccess && this.hasAccessEffect(context)) || 8591 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context)); 8592 } 8593 hasEffectsOnInteractionAtPath(path, interaction, context) { 8594 if (this.variable) { 8595 return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context); 8596 } 8597 if (this.isUndefined) { 8598 return true; 8599 } 8600 if (path.length < MAX_PATH_DEPTH) { 8601 return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context); 8602 } 8603 return true; 8604 } 8605 include(context, includeChildrenRecursively) { 8606 if (!this.deoptimized) 8607 this.applyDeoptimizations(); 8608 this.includeProperties(context, includeChildrenRecursively); 8609 } 8610 includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) { 8611 if (!this.assignmentDeoptimized) 8612 this.applyAssignmentDeoptimization(); 8613 if (deoptimizeAccess) { 8614 this.include(context, includeChildrenRecursively); 8615 } 8616 else { 8617 this.includeProperties(context, includeChildrenRecursively); 8618 } 8619 } 8620 includeCallArguments(context, parameters) { 8621 if (this.variable) { 8622 this.variable.includeCallArguments(context, parameters); 8623 } 8624 else { 8625 super.includeCallArguments(context, parameters); 8626 } 8627 } 8628 initialise() { 8629 super.initialise(); 8630 this.propertyKey = getResolvablePropertyKey(this); 8631 this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED }; 8632 } 8633 render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = parseAst_js.BLANK) { 8634 if (this.variable || this.isUndefined) { 8635 const { snippets: { getPropertyAccess } } = options; 8636 let replacement = this.variable ? this.variable.getName(getPropertyAccess) : 'undefined'; 8637 if (renderedParentType && isCalleeOfRenderedParent) 8638 replacement = '0, ' + replacement; 8639 code.overwrite(this.start, this.end, replacement, { 8640 contentOnly: true, 8641 storeName: true 8642 }); 8643 } 8644 else { 8645 if (renderedParentType && isCalleeOfRenderedParent) { 8646 code.appendRight(this.start, '0, '); 8647 } 8648 this.object.render(code, options, { renderedSurroundingElement }); 8649 this.property.render(code, options); 8650 } 8651 } 8652 setAssignedValue(value) { 8653 this.assignmentInteraction = { 8654 args: [this.object, value], 8655 type: INTERACTION_ASSIGNED 8656 }; 8657 } 8658 applyDeoptimizations() { 8659 this.deoptimized = true; 8660 const { propertyReadSideEffects } = this.scope.context.options 8661 .treeshake; 8662 if ( 8663 // Namespaces are not bound and should not be deoptimized 8664 this.bound && 8665 propertyReadSideEffects && 8666 !(this.variable || this.isUndefined)) { 8667 const propertyKey = this.getPropertyKey(); 8668 this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER); 8669 this.scope.context.requestTreeshakingPass(); 8670 } 8671 if (this.variable) { 8672 this.variable.addUsedPlace(this); 8673 this.scope.context.requestTreeshakingPass(); 8674 } 8675 } 8676 applyAssignmentDeoptimization() { 8677 this.assignmentDeoptimized = true; 8678 const { propertyReadSideEffects } = this.scope.context.options 8679 .treeshake; 8680 if ( 8681 // Namespaces are not bound and should not be deoptimized 8682 this.bound && 8683 propertyReadSideEffects && 8684 !(this.variable || this.isUndefined)) { 8685 this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER); 8686 this.scope.context.requestTreeshakingPass(); 8687 } 8688 } 8689 disallowNamespaceReassignment() { 8690 if (this.object instanceof Identifier) { 8691 const variable = this.scope.findVariable(this.object.name); 8692 if (variable.isNamespace) { 8693 if (this.variable) { 8694 this.scope.context.includeVariableInModule(this.variable); 8695 } 8696 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start); 8697 } 8698 } 8699 } 8700 getPropertyKey() { 8701 if (this.propertyKey === null) { 8702 this.propertyKey = UnknownKey; 8703 const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 8704 return (this.propertyKey = 8705 value === SymbolToStringTag 8706 ? value 8707 : typeof value === 'symbol' 8708 ? UnknownKey 8709 : String(value)); 8710 } 8711 return this.propertyKey; 8712 } 8713 hasAccessEffect(context) { 8714 const { propertyReadSideEffects } = this.scope.context.options 8715 .treeshake; 8716 return (!(this.variable || this.isUndefined) && 8717 propertyReadSideEffects && 8718 (propertyReadSideEffects === 'always' || 8719 this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context))); 8720 } 8721 includeProperties(context, includeChildrenRecursively) { 8722 if (!this.included) { 8723 this.included = true; 8724 if (this.variable) { 8725 this.scope.context.includeVariableInModule(this.variable); 8726 } 8727 } 8728 this.object.include(context, includeChildrenRecursively); 8729 this.property.include(context, includeChildrenRecursively); 8730 } 8731 } 8732 function resolveNamespaceVariables(baseVariable, path, astContext) { 8733 if (path.length === 0) 8734 return baseVariable; 8735 if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable) 8736 return null; 8737 const exportName = path[0].key; 8738 const variable = baseVariable.context.traceExport(exportName); 8739 if (!variable) { 8740 if (path.length === 1) { 8741 const fileName = baseVariable.context.fileName; 8742 astContext.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingExport(exportName, astContext.module.id, fileName), path[0].pos); 8743 return 'undefined'; 8744 } 8745 return null; 8746 } 8747 return resolveNamespaceVariables(variable, path.slice(1), astContext); 8748 } 8749 8750 const FILE_PREFIX = 'ROLLUP_FILE_URL_'; 8751 const IMPORT = 'import'; 8752 class MetaProperty extends NodeBase { 8753 constructor() { 8754 super(...arguments); 8755 this.metaProperty = null; 8756 this.preliminaryChunkId = null; 8757 this.referenceId = null; 8758 } 8759 getReferencedFileName(outputPluginDriver) { 8760 const { meta: { name }, metaProperty } = this; 8761 if (name === IMPORT && metaProperty?.startsWith(FILE_PREFIX)) { 8762 return outputPluginDriver.getFileName(metaProperty.slice(FILE_PREFIX.length)); 8763 } 8764 return null; 8765 } 8766 hasEffects() { 8767 return false; 8768 } 8769 hasEffectsOnInteractionAtPath(path, { type }) { 8770 return path.length > 1 || type !== INTERACTION_ACCESSED; 8771 } 8772 include() { 8773 if (!this.included) { 8774 this.included = true; 8775 if (this.meta.name === IMPORT) { 8776 this.scope.context.addImportMeta(this); 8777 const parent = this.parent; 8778 const metaProperty = (this.metaProperty = 8779 parent instanceof MemberExpression && typeof parent.propertyKey === 'string' 8780 ? parent.propertyKey 8781 : null); 8782 if (metaProperty?.startsWith(FILE_PREFIX)) { 8783 this.referenceId = metaProperty.slice(FILE_PREFIX.length); 8784 } 8785 } 8786 } 8787 } 8788 render(code, renderOptions) { 8789 const { format, pluginDriver, snippets } = renderOptions; 8790 const { scope: { context: { module } }, meta: { name }, metaProperty, parent, preliminaryChunkId, referenceId, start, end } = this; 8791 const { id: moduleId } = module; 8792 if (name !== IMPORT) 8793 return; 8794 const chunkId = preliminaryChunkId; 8795 if (referenceId) { 8796 const fileName = pluginDriver.getFileName(referenceId); 8797 const relativePath = parseAst_js.normalize(path.relative(path.dirname(chunkId), fileName)); 8798 const replacement = pluginDriver.hookFirstSync('resolveFileUrl', [ 8799 { chunkId, fileName, format, moduleId, referenceId, relativePath } 8800 ]) || relativeUrlMechanisms[format](relativePath); 8801 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true }); 8802 return; 8803 } 8804 let replacement = pluginDriver.hookFirstSync('resolveImportMeta', [ 8805 metaProperty, 8806 { chunkId, format, moduleId } 8807 ]); 8808 if (!replacement) { 8809 replacement = importMetaMechanisms[format]?.(metaProperty, { chunkId, snippets }); 8810 renderOptions.accessedDocumentCurrentScript ||= 8811 formatsMaybeAccessDocumentCurrentScript.includes(format) && replacement !== 'undefined'; 8812 } 8813 if (typeof replacement === 'string') { 8814 if (parent instanceof MemberExpression) { 8815 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true }); 8816 } 8817 else { 8818 code.overwrite(start, end, replacement, { contentOnly: true }); 8819 } 8820 } 8821 } 8822 setResolution(format, accessedGlobalsByScope, preliminaryChunkId) { 8823 this.preliminaryChunkId = preliminaryChunkId; 8824 const accessedGlobals = (this.metaProperty?.startsWith(FILE_PREFIX) ? accessedFileUrlGlobals : accessedMetaUrlGlobals)[format]; 8825 if (accessedGlobals.length > 0) { 8826 this.scope.addAccessedGlobals(accessedGlobals, accessedGlobalsByScope); 8827 } 8828 } 8829 } 8830 const formatsMaybeAccessDocumentCurrentScript = ['cjs', 'iife', 'umd']; 8831 const accessedMetaUrlGlobals = { 8832 amd: ['document', 'module', 'URL'], 8833 cjs: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT], 8834 es: [], 8835 iife: ['document', 'URL', DOCUMENT_CURRENT_SCRIPT], 8836 system: ['module'], 8837 umd: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT] 8838 }; 8839 const accessedFileUrlGlobals = { 8840 amd: ['document', 'require', 'URL'], 8841 cjs: ['document', 'require', 'URL'], 8842 es: [], 8843 iife: ['document', 'URL'], 8844 system: ['module', 'URL'], 8845 umd: ['document', 'require', 'URL'] 8846 }; 8847 const getResolveUrl = (path, URL = 'URL') => `new ${URL}(${path}).href`; 8848 const getRelativeUrlFromDocument = (relativePath, umd = false) => getResolveUrl(`'${escapeId(relativePath)}', ${umd ? `typeof document === 'undefined' ? location.href : ` : ''}document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT' && document.currentScript.src || document.baseURI`); 8849 const getGenericImportMetaMechanism = (getUrl) => (property, { chunkId }) => { 8850 const urlMechanism = getUrl(chunkId); 8851 return property === null 8852 ? `({ url: ${urlMechanism} })` 8853 : property === 'url' 8854 ? urlMechanism 8855 : 'undefined'; 8856 }; 8857 const getFileUrlFromFullPath = (path) => `require('u' + 'rl').pathToFileURL(${path}).href`; 8858 const getFileUrlFromRelativePath = (path) => getFileUrlFromFullPath(`__dirname + '/${escapeId(path)}'`); 8859 const getUrlFromDocument = (chunkId, umd = false) => `${umd ? `typeof document === 'undefined' ? location.href : ` : ''}(${DOCUMENT_CURRENT_SCRIPT} && ${DOCUMENT_CURRENT_SCRIPT}.tagName.toUpperCase() === 'SCRIPT' && ${DOCUMENT_CURRENT_SCRIPT}.src || new URL('${escapeId(chunkId)}', document.baseURI).href)`; 8860 const relativeUrlMechanisms = { 8861 amd: relativePath => { 8862 if (relativePath[0] !== '.') 8863 relativePath = './' + relativePath; 8864 return getResolveUrl(`require.toUrl('${escapeId(relativePath)}'), document.baseURI`); 8865 }, 8866 cjs: relativePath => `(typeof document === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath)})`, 8867 es: relativePath => getResolveUrl(`'${escapeId(relativePath)}', import.meta.url`), 8868 iife: relativePath => getRelativeUrlFromDocument(relativePath), 8869 system: relativePath => getResolveUrl(`'${escapeId(relativePath)}', module.meta.url`), 8870 umd: relativePath => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath, true)})` 8871 }; 8872 const importMetaMechanisms = { 8873 amd: getGenericImportMetaMechanism(() => getResolveUrl(`module.uri, document.baseURI`)), 8874 cjs: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId)})`), 8875 iife: getGenericImportMetaMechanism(chunkId => getUrlFromDocument(chunkId)), 8876 system: (property, { snippets: { getPropertyAccess } }) => property === null ? `module.meta` : `module.meta${getPropertyAccess(property)}`, 8877 umd: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId, true)})`) 8878 }; 8879 8880 class UndefinedVariable extends Variable { 8881 constructor() { 8882 super('undefined'); 8883 } 8884 getLiteralValueAtPath() { 8885 return undefined; 8886 } 8887 } 8888 8889 class ExportDefaultVariable extends LocalVariable { 8890 constructor(name, exportDefaultDeclaration, context) { 8891 super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other'); 8892 this.hasId = false; 8893 this.originalId = null; 8894 this.originalVariable = null; 8895 const declaration = exportDefaultDeclaration.declaration; 8896 if ((declaration instanceof FunctionDeclaration || declaration instanceof ClassDeclaration) && 8897 declaration.id) { 8898 this.hasId = true; 8899 this.originalId = declaration.id; 8900 } 8901 else if (declaration instanceof Identifier) { 8902 this.originalId = declaration; 8903 } 8904 } 8905 addReference(identifier) { 8906 if (!this.hasId) { 8907 this.name = identifier.name; 8908 } 8909 } 8910 addUsedPlace(usedPlace) { 8911 const original = this.getOriginalVariable(); 8912 if (original === this) { 8913 super.addUsedPlace(usedPlace); 8914 } 8915 else { 8916 original.addUsedPlace(usedPlace); 8917 } 8918 } 8919 forbidName(name) { 8920 const original = this.getOriginalVariable(); 8921 if (original === this) { 8922 super.forbidName(name); 8923 } 8924 else { 8925 original.forbidName(name); 8926 } 8927 } 8928 getAssignedVariableName() { 8929 return (this.originalId && this.originalId.name) || null; 8930 } 8931 getBaseVariableName() { 8932 const original = this.getOriginalVariable(); 8933 return original === this ? super.getBaseVariableName() : original.getBaseVariableName(); 8934 } 8935 getDirectOriginalVariable() { 8936 return this.originalId && 8937 (this.hasId || 8938 !(this.originalId.isPossibleTDZ() || 8939 this.originalId.variable.isReassigned || 8940 this.originalId.variable instanceof UndefinedVariable || 8941 // this avoids a circular dependency 8942 'syntheticNamespace' in this.originalId.variable)) 8943 ? this.originalId.variable 8944 : null; 8945 } 8946 getName(getPropertyAccess) { 8947 const original = this.getOriginalVariable(); 8948 return original === this 8949 ? super.getName(getPropertyAccess) 8950 : original.getName(getPropertyAccess); 8951 } 8952 getOriginalVariable() { 8953 if (this.originalVariable) 8954 return this.originalVariable; 8955 // eslint-disable-next-line @typescript-eslint/no-this-alias 8956 let original = this; 8957 let currentVariable; 8958 const checkedVariables = new Set(); 8959 do { 8960 checkedVariables.add(original); 8961 currentVariable = original; 8962 original = currentVariable.getDirectOriginalVariable(); 8963 } while (original instanceof ExportDefaultVariable && !checkedVariables.has(original)); 8964 return (this.originalVariable = original || currentVariable); 8965 } 8966 } 8967 8968 class NamespaceVariable extends Variable { 8969 constructor(context) { 8970 super(context.getModuleName()); 8971 this.memberVariables = null; 8972 this.mergedNamespaces = []; 8973 this.referencedEarly = false; 8974 this.references = []; 8975 this.context = context; 8976 this.module = context.module; 8977 } 8978 addReference(identifier) { 8979 this.references.push(identifier); 8980 this.name = identifier.name; 8981 } 8982 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 8983 if (path.length > 1 || (path.length === 1 && interaction.type === INTERACTION_CALLED)) { 8984 const key = path[0]; 8985 if (typeof key === 'string') { 8986 this.getMemberVariables()[key]?.deoptimizeArgumentsOnInteractionAtPath(interaction, path.slice(1), recursionTracker); 8987 } 8988 else { 8989 deoptimizeInteraction(interaction); 8990 } 8991 } 8992 } 8993 deoptimizePath(path) { 8994 if (path.length > 1) { 8995 const key = path[0]; 8996 if (typeof key === 'string') { 8997 this.getMemberVariables()[key]?.deoptimizePath(path.slice(1)); 8998 } 8999 } 9000 } 9001 getLiteralValueAtPath(path) { 9002 if (path[0] === SymbolToStringTag) { 9003 return 'Module'; 9004 } 9005 return UnknownValue; 9006 } 9007 getMemberVariables() { 9008 if (this.memberVariables) { 9009 return this.memberVariables; 9010 } 9011 const memberVariables = Object.create(null); 9012 const sortedExports = [...this.context.getExports(), ...this.context.getReexports()].sort(); 9013 for (const name of sortedExports) { 9014 if (name[0] !== '*' && name !== this.module.info.syntheticNamedExports) { 9015 const exportedVariable = this.context.traceExport(name); 9016 if (exportedVariable) { 9017 memberVariables[name] = exportedVariable; 9018 } 9019 } 9020 } 9021 return (this.memberVariables = memberVariables); 9022 } 9023 hasEffectsOnInteractionAtPath(path, interaction, context) { 9024 const { type } = interaction; 9025 if (path.length === 0) { 9026 // This can only be a call anyway 9027 return true; 9028 } 9029 if (path.length === 1 && type !== INTERACTION_CALLED) { 9030 return type === INTERACTION_ASSIGNED; 9031 } 9032 const key = path[0]; 9033 if (typeof key !== 'string') { 9034 return true; 9035 } 9036 const memberVariable = this.getMemberVariables()[key]; 9037 return (!memberVariable || 9038 memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context)); 9039 } 9040 include() { 9041 super.include(); 9042 this.context.includeAllExports(); 9043 } 9044 prepare(accessedGlobalsByScope) { 9045 if (this.mergedNamespaces.length > 0) { 9046 this.module.scope.addAccessedGlobals([MERGE_NAMESPACES_VARIABLE], accessedGlobalsByScope); 9047 } 9048 } 9049 renderBlock(options) { 9050 const { exportNamesByVariable, format, freeze, indent: t, symbols, snippets: { _, cnst, getObject, getPropertyAccess, n, s } } = options; 9051 const memberVariables = this.getMemberVariables(); 9052 const members = Object.entries(memberVariables) 9053 .filter(([_, variable]) => variable.included) 9054 .map(([name, variable]) => { 9055 if (this.referencedEarly || variable.isReassigned || variable === this) { 9056 return [ 9057 null, 9058 `get ${stringifyObjectKeyIfNeeded(name)}${_}()${_}{${_}return ${variable.getName(getPropertyAccess)}${s}${_}}` 9059 ]; 9060 } 9061 return [name, variable.getName(getPropertyAccess)]; 9062 }); 9063 members.unshift([null, `__proto__:${_}null`]); 9064 let output = getObject(members, { lineBreakIndent: { base: '', t } }); 9065 if (this.mergedNamespaces.length > 0) { 9066 const assignmentArguments = this.mergedNamespaces.map(variable => variable.getName(getPropertyAccess)); 9067 output = `/*#__PURE__*/${MERGE_NAMESPACES_VARIABLE}(${output},${_}[${assignmentArguments.join(`,${_}`)}])`; 9068 } 9069 else { 9070 // The helper to merge namespaces will also take care of freezing and toStringTag 9071 if (symbols) { 9072 output = `/*#__PURE__*/Object.defineProperty(${output},${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)})`; 9073 } 9074 if (freeze) { 9075 output = `/*#__PURE__*/Object.freeze(${output})`; 9076 } 9077 } 9078 const name = this.getName(getPropertyAccess); 9079 output = `${cnst} ${name}${_}=${_}${output};`; 9080 if (format === 'system' && exportNamesByVariable.has(this)) { 9081 output += `${n}${getSystemExportStatement([this], options)};`; 9082 } 9083 return output; 9084 } 9085 renderFirst() { 9086 return this.referencedEarly; 9087 } 9088 setMergedNamespaces(mergedNamespaces) { 9089 this.mergedNamespaces = mergedNamespaces; 9090 const moduleExecIndex = this.context.getModuleExecIndex(); 9091 for (const identifier of this.references) { 9092 const { context } = identifier.scope; 9093 if (context.getModuleExecIndex() <= moduleExecIndex) { 9094 this.referencedEarly = true; 9095 break; 9096 } 9097 } 9098 } 9099 } 9100 NamespaceVariable.prototype.isNamespace = true; 9101 9102 class SyntheticNamedExportVariable extends Variable { 9103 constructor(context, name, syntheticNamespace) { 9104 super(name); 9105 this.baseVariable = null; 9106 this.context = context; 9107 this.module = context.module; 9108 this.syntheticNamespace = syntheticNamespace; 9109 } 9110 getBaseVariable() { 9111 if (this.baseVariable) 9112 return this.baseVariable; 9113 let baseVariable = this.syntheticNamespace; 9114 while (baseVariable instanceof ExportDefaultVariable || 9115 baseVariable instanceof SyntheticNamedExportVariable) { 9116 if (baseVariable instanceof ExportDefaultVariable) { 9117 const original = baseVariable.getOriginalVariable(); 9118 if (original === baseVariable) 9119 break; 9120 baseVariable = original; 9121 } 9122 if (baseVariable instanceof SyntheticNamedExportVariable) { 9123 baseVariable = baseVariable.syntheticNamespace; 9124 } 9125 } 9126 return (this.baseVariable = baseVariable); 9127 } 9128 getBaseVariableName() { 9129 return this.syntheticNamespace.getBaseVariableName(); 9130 } 9131 getName(getPropertyAccess) { 9132 return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`; 9133 } 9134 include() { 9135 super.include(); 9136 this.context.includeVariableInModule(this.syntheticNamespace); 9137 } 9138 setRenderNames(baseName, name) { 9139 super.setRenderNames(baseName, name); 9140 } 9141 } 9142 9143 class ExternalChunk { 9144 constructor(module, options, inputBase) { 9145 this.options = options; 9146 this.inputBase = inputBase; 9147 this.defaultVariableName = ''; 9148 this.namespaceVariableName = ''; 9149 this.variableName = ''; 9150 this.fileName = null; 9151 this.importAttributes = null; 9152 this.id = module.id; 9153 this.moduleInfo = module.info; 9154 this.renormalizeRenderPath = module.renormalizeRenderPath; 9155 this.suggestedVariableName = module.suggestedVariableName; 9156 } 9157 getFileName() { 9158 if (this.fileName) { 9159 return this.fileName; 9160 } 9161 const { paths } = this.options; 9162 return (this.fileName = 9163 (typeof paths === 'function' ? paths(this.id) : paths[this.id]) || 9164 (this.renormalizeRenderPath ? parseAst_js.normalize(path.relative(this.inputBase, this.id)) : this.id)); 9165 } 9166 getImportAttributes(snippets) { 9167 return (this.importAttributes ||= formatAttributes(this.options.format === 'es' && 9168 this.options.externalImportAttributes && 9169 this.moduleInfo.attributes, snippets)); 9170 } 9171 getImportPath(importer) { 9172 return escapeId(this.renormalizeRenderPath 9173 ? parseAst_js.getImportPath(importer, this.getFileName(), this.options.format === 'amd', false) 9174 : this.getFileName()); 9175 } 9176 } 9177 function formatAttributes(attributes, { getObject }) { 9178 if (!attributes) { 9179 return null; 9180 } 9181 const assertionEntries = Object.entries(attributes).map(([key, value]) => [key, `'${value}'`]); 9182 if (assertionEntries.length > 0) { 9183 return getObject(assertionEntries, { lineBreakIndent: null }); 9184 } 9185 return null; 9186 } 9187 9188 function removeJsExtension(name) { 9189 return name.endsWith('.js') ? name.slice(0, -3) : name; 9190 } 9191 9192 function getCompleteAmdId(options, chunkId) { 9193 if (options.autoId) { 9194 return `${options.basePath ? options.basePath + '/' : ''}${removeJsExtension(chunkId)}`; 9195 } 9196 return options.id ?? ''; 9197 } 9198 9199 function getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, mechanism = 'return ') { 9200 const { _, getDirectReturnFunction, getFunctionIntro, getPropertyAccess, n, s } = snippets; 9201 if (!namedExportsMode) { 9202 return `${n}${n}${mechanism}${getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess)};`; 9203 } 9204 let exportBlock = ''; 9205 if (namedExportsMode) { 9206 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) { 9207 if (!reexports) { 9208 continue; 9209 } 9210 for (const specifier of reexports) { 9211 if (specifier.reexported !== '*') { 9212 const importName = getReexportedImportName(name, specifier.imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess); 9213 if (exportBlock) 9214 exportBlock += n; 9215 if (specifier.imported !== '*' && specifier.needsLiveBinding) { 9216 const [left, right] = getDirectReturnFunction([], { 9217 functionReturn: true, 9218 lineBreakIndent: null, 9219 name: null 9220 }); 9221 exportBlock += 9222 `Object.defineProperty(exports,${_}${JSON.stringify(specifier.reexported)},${_}{${n}` + 9223 `${t}enumerable:${_}true,${n}` + 9224 `${t}get:${_}${left}${importName}${right}${n}});`; 9225 } 9226 else if (specifier.reexported === '__proto__') { 9227 exportBlock += 9228 `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` + 9229 `${t}enumerable:${_}true,${n}` + 9230 `${t}value:${_}${importName}${n}});`; 9231 } 9232 else { 9233 exportBlock += `exports${getPropertyAccess(specifier.reexported)}${_}=${_}${importName};`; 9234 } 9235 } 9236 } 9237 } 9238 } 9239 for (const { exported, local } of exports) { 9240 const lhs = `exports${getPropertyAccess(exported)}`; 9241 const rhs = local; 9242 if (lhs !== rhs) { 9243 if (exportBlock) 9244 exportBlock += n; 9245 exportBlock += 9246 exported === '__proto__' 9247 ? `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` + 9248 `${t}enumerable:${_}true,${n}` + 9249 `${t}value:${_}${rhs}${n}});` 9250 : `${lhs}${_}=${_}${rhs};`; 9251 } 9252 } 9253 if (namedExportsMode) { 9254 for (const { name, reexports } of dependencies) { 9255 if (!reexports) { 9256 continue; 9257 } 9258 for (const specifier of reexports) { 9259 if (specifier.reexported === '*') { 9260 if (exportBlock) 9261 exportBlock += n; 9262 if (!specifier.needsLiveBinding && reexportProtoFromExternal) { 9263 const protoString = "'__proto__'"; 9264 exportBlock += 9265 `Object.prototype.hasOwnProperty.call(${name},${_}${protoString})${_}&&${n}` + 9266 `${t}!Object.prototype.hasOwnProperty.call(exports,${_}${protoString})${_}&&${n}` + 9267 `${t}Object.defineProperty(exports,${_}${protoString},${_}{${n}` + 9268 `${t}${t}enumerable:${_}true,${n}` + 9269 `${t}${t}value:${_}${name}[${protoString}]${n}` + 9270 `${t}});${n}${n}`; 9271 } 9272 const copyPropertyIfNecessary = `{${n}${t}if${_}(k${_}!==${_}'default'${_}&&${_}!Object.prototype.hasOwnProperty.call(exports,${_}k))${_}${getDefineProperty(name, specifier.needsLiveBinding, t, snippets)}${s}${n}}`; 9273 exportBlock += `Object.keys(${name}).forEach(${getFunctionIntro(['k'], { 9274 isAsync: false, 9275 name: null 9276 })}${copyPropertyIfNecessary});`; 9277 } 9278 } 9279 } 9280 } 9281 if (exportBlock) { 9282 return `${n}${n}${exportBlock}`; 9283 } 9284 return ''; 9285 } 9286 function getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess) { 9287 if (exports.length > 0) { 9288 return exports[0].local; 9289 } 9290 else { 9291 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) { 9292 if (reexports) { 9293 return getReexportedImportName(name, reexports[0].imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess); 9294 } 9295 } 9296 } 9297 } 9298 function getReexportedImportName(moduleVariableName, imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, moduleId, externalLiveBindings, getPropertyAccess) { 9299 if (imported === 'default') { 9300 if (!isChunk) { 9301 const moduleInterop = interop(moduleId); 9302 const variableName = defaultInteropHelpersByInteropType[moduleInterop] 9303 ? defaultVariableName 9304 : moduleVariableName; 9305 return isDefaultAProperty(moduleInterop, externalLiveBindings) 9306 ? `${variableName}${getPropertyAccess('default')}` 9307 : variableName; 9308 } 9309 return depNamedExportsMode 9310 ? `${moduleVariableName}${getPropertyAccess('default')}` 9311 : moduleVariableName; 9312 } 9313 if (imported === '*') { 9314 return (isChunk ? !depNamedExportsMode : namespaceInteropHelpersByInteropType[interop(moduleId)]) 9315 ? namespaceVariableName 9316 : moduleVariableName; 9317 } 9318 return `${moduleVariableName}${getPropertyAccess(imported)}`; 9319 } 9320 function getEsModuleValue(getObject) { 9321 return getObject([['value', 'true']], { 9322 lineBreakIndent: null 9323 }); 9324 } 9325 function getNamespaceMarkers(hasNamedExports, addEsModule, addNamespaceToStringTag, { _, getObject }) { 9326 if (hasNamedExports) { 9327 if (addEsModule) { 9328 if (addNamespaceToStringTag) { 9329 return `Object.defineProperties(exports,${_}${getObject([ 9330 ['__esModule', getEsModuleValue(getObject)], 9331 [null, `[Symbol.toStringTag]:${_}${getToStringTagValue(getObject)}`] 9332 ], { 9333 lineBreakIndent: null 9334 })});`; 9335 } 9336 return `Object.defineProperty(exports,${_}'__esModule',${_}${getEsModuleValue(getObject)});`; 9337 } 9338 if (addNamespaceToStringTag) { 9339 return `Object.defineProperty(exports,${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)});`; 9340 } 9341 } 9342 return ''; 9343 } 9344 const getDefineProperty = (name, needsLiveBinding, t, { _, getDirectReturnFunction, n }) => { 9345 if (needsLiveBinding) { 9346 const [left, right] = getDirectReturnFunction([], { 9347 functionReturn: true, 9348 lineBreakIndent: null, 9349 name: null 9350 }); 9351 return (`Object.defineProperty(exports,${_}k,${_}{${n}` + 9352 `${t}${t}enumerable:${_}true,${n}` + 9353 `${t}${t}get:${_}${left}${name}[k]${right}${n}${t}})`); 9354 } 9355 return `exports[k]${_}=${_}${name}[k]`; 9356 }; 9357 9358 function getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, indent, snippets) { 9359 const { _, cnst, n } = snippets; 9360 const neededInteropHelpers = new Set(); 9361 const interopStatements = []; 9362 const addInteropStatement = (helperVariableName, helper, dependencyVariableName) => { 9363 neededInteropHelpers.add(helper); 9364 interopStatements.push(`${cnst} ${helperVariableName}${_}=${_}/*#__PURE__*/${helper}(${dependencyVariableName});`); 9365 }; 9366 for (const { defaultVariableName, imports, importPath, isChunk, name, namedExportsMode, namespaceVariableName, reexports } of dependencies) { 9367 if (isChunk) { 9368 for (const { imported, reexported } of [ 9369 ...(imports || []), 9370 ...(reexports || []) 9371 ]) { 9372 if (imported === '*' && reexported !== '*') { 9373 if (!namedExportsMode) { 9374 addInteropStatement(namespaceVariableName, INTEROP_NAMESPACE_DEFAULT_ONLY_VARIABLE, name); 9375 } 9376 break; 9377 } 9378 } 9379 } 9380 else { 9381 const moduleInterop = interop(importPath); 9382 let hasDefault = false; 9383 let hasNamespace = false; 9384 for (const { imported, reexported } of [ 9385 ...(imports || []), 9386 ...(reexports || []) 9387 ]) { 9388 let helper; 9389 let variableName; 9390 if (imported === 'default') { 9391 if (!hasDefault) { 9392 hasDefault = true; 9393 if (defaultVariableName !== namespaceVariableName) { 9394 variableName = defaultVariableName; 9395 helper = defaultInteropHelpersByInteropType[moduleInterop]; 9396 } 9397 } 9398 } 9399 else if (imported === '*' && reexported !== '*' && !hasNamespace) { 9400 hasNamespace = true; 9401 helper = namespaceInteropHelpersByInteropType[moduleInterop]; 9402 variableName = namespaceVariableName; 9403 } 9404 if (helper) { 9405 addInteropStatement(variableName, helper, name); 9406 } 9407 } 9408 } 9409 } 9410 return `${getHelpersBlock(neededInteropHelpers, accessedGlobals, indent, snippets, externalLiveBindings, freeze, symbols)}${interopStatements.length > 0 ? `${interopStatements.join(n)}${n}${n}` : ''}`; 9411 } 9412 9413 function addJsExtension(name) { 9414 return name.endsWith('.js') ? name : name + '.js'; 9415 } 9416 9417 // AMD resolution will only respect the AMD baseUrl if the .js extension is omitted. 9418 // The assumption is that this makes sense for all relative ids: 9419 // https://requirejs.org/docs/api.html#jsfiles 9420 function updateExtensionForRelativeAmdId(id, forceJsExtensionForImports) { 9421 if (id[0] !== '.') { 9422 return id; 9423 } 9424 return forceJsExtensionForImports ? addJsExtension(id) : removeJsExtension(id); 9425 } 9426 9427 const builtinModules = [ 9428 "assert", 9429 "assert/strict", 9430 "async_hooks", 9431 "buffer", 9432 "child_process", 9433 "cluster", 9434 "console", 9435 "constants", 9436 "crypto", 9437 "dgram", 9438 "diagnostics_channel", 9439 "dns", 9440 "dns/promises", 9441 "domain", 9442 "events", 9443 "fs", 9444 "fs/promises", 9445 "http", 9446 "http2", 9447 "https", 9448 "inspector", 9449 "inspector/promises", 9450 "module", 9451 "net", 9452 "os", 9453 "path", 9454 "path/posix", 9455 "path/win32", 9456 "perf_hooks", 9457 "process", 9458 "punycode", 9459 "querystring", 9460 "readline", 9461 "readline/promises", 9462 "repl", 9463 "stream", 9464 "stream/consumers", 9465 "stream/promises", 9466 "stream/web", 9467 "string_decoder", 9468 "timers", 9469 "timers/promises", 9470 "tls", 9471 "trace_events", 9472 "tty", 9473 "url", 9474 "util", 9475 "util/types", 9476 "v8", 9477 "vm", 9478 "wasi", 9479 "worker_threads", 9480 "zlib" 9481 ]; 9482 9483 const nodeBuiltins = new Set(builtinModules); 9484 function warnOnBuiltins(log, dependencies) { 9485 const externalBuiltins = dependencies 9486 .map(({ importPath }) => importPath) 9487 .filter(importPath => nodeBuiltins.has(importPath) || importPath.startsWith('node:')); 9488 if (externalBuiltins.length === 0) 9489 return; 9490 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingNodeBuiltins(externalBuiltins)); 9491 } 9492 9493 function amd(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, id, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, log, outro, snippets }, { amd, esModule, externalLiveBindings, freeze, generatedCode: { symbols }, interop, reexportProtoFromExternal, strict }) { 9494 warnOnBuiltins(log, dependencies); 9495 const deps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); 9496 const parameters = dependencies.map(m => m.name); 9497 const { n, getNonArrowFunctionIntro, _ } = snippets; 9498 if (namedExportsMode && hasExports) { 9499 parameters.unshift(`exports`); 9500 deps.unshift(`'exports'`); 9501 } 9502 if (accessedGlobals.has('require')) { 9503 parameters.unshift('require'); 9504 deps.unshift(`'require'`); 9505 } 9506 if (accessedGlobals.has('module')) { 9507 parameters.unshift('module'); 9508 deps.unshift(`'module'`); 9509 } 9510 const completeAmdId = getCompleteAmdId(amd, id); 9511 const defineParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) + 9512 (deps.length > 0 ? `[${deps.join(`,${_}`)}],${_}` : ``); 9513 const useStrict = strict ? `${_}'use strict';` : ''; 9514 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`); 9515 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 9516 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets); 9517 if (namespaceMarkers) { 9518 namespaceMarkers = n + n + namespaceMarkers; 9519 } 9520 magicString 9521 .append(`${exportBlock}${namespaceMarkers}${outro}`) 9522 .indent(t) 9523 // factory function should be wrapped by parentheses to avoid lazy parsing, 9524 // cf. https://v8.dev/blog/preparser#pife 9525 .prepend(`${amd.define}(${defineParameters}(${getNonArrowFunctionIntro(parameters, { 9526 isAsync: false, 9527 name: null 9528 })}{${useStrict}${n}${n}`) 9529 .append(`${n}${n}}));`); 9530 } 9531 9532 function cjs(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, outro, snippets }, { compact, esModule, externalLiveBindings, freeze, interop, generatedCode: { symbols }, reexportProtoFromExternal, strict }) { 9533 const { _, n } = snippets; 9534 const useStrict = strict ? `'use strict';${n}${n}` : ''; 9535 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets); 9536 if (namespaceMarkers) { 9537 namespaceMarkers += n + n; 9538 } 9539 const importBlock = getImportBlock$1(dependencies, snippets, compact); 9540 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets); 9541 magicString.prepend(`${useStrict}${intro}${namespaceMarkers}${importBlock}${interopBlock}`); 9542 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, `module.exports${_}=${_}`); 9543 magicString.append(`${exportBlock}${outro}`); 9544 } 9545 function getImportBlock$1(dependencies, { _, cnst, n }, compact) { 9546 let importBlock = ''; 9547 let definingVariable = false; 9548 for (const { importPath, name, reexports, imports } of dependencies) { 9549 if (!reexports && !imports) { 9550 if (importBlock) { 9551 importBlock += compact && !definingVariable ? ',' : `;${n}`; 9552 } 9553 definingVariable = false; 9554 importBlock += `require('${importPath}')`; 9555 } 9556 else { 9557 importBlock += compact && definingVariable ? ',' : `${importBlock ? `;${n}` : ''}${cnst} `; 9558 definingVariable = true; 9559 importBlock += `${name}${_}=${_}require('${importPath}')`; 9560 } 9561 } 9562 if (importBlock) { 9563 return `${importBlock};${n}${n}`; 9564 } 9565 return ''; 9566 } 9567 9568 function es(magicString, { accessedGlobals, indent: t, intro, outro, dependencies, exports, snippets }, { externalLiveBindings, freeze, generatedCode: { symbols }, importAttributesKey }) { 9569 const { n } = snippets; 9570 const importBlock = getImportBlock(dependencies, importAttributesKey, snippets); 9571 if (importBlock.length > 0) 9572 intro += importBlock.join(n) + n + n; 9573 intro += getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols); 9574 if (intro) 9575 magicString.prepend(intro); 9576 const exportBlock = getExportBlock(exports, snippets); 9577 if (exportBlock.length > 0) 9578 magicString.append(n + n + exportBlock.join(n).trim()); 9579 if (outro) 9580 magicString.append(outro); 9581 magicString.trim(); 9582 } 9583 function getImportBlock(dependencies, importAttributesKey, { _ }) { 9584 const importBlock = []; 9585 for (const { importPath, reexports, imports, name, attributes } of dependencies) { 9586 const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : ''; 9587 const pathWithAssertion = `'${importPath}'${assertion};`; 9588 if (!reexports && !imports) { 9589 importBlock.push(`import${_}${pathWithAssertion}`); 9590 continue; 9591 } 9592 if (imports) { 9593 let defaultImport = null; 9594 let starImport = null; 9595 const importedNames = []; 9596 for (const specifier of imports) { 9597 if (specifier.imported === 'default') { 9598 defaultImport = specifier; 9599 } 9600 else if (specifier.imported === '*') { 9601 starImport = specifier; 9602 } 9603 else { 9604 importedNames.push(specifier); 9605 } 9606 } 9607 if (starImport) { 9608 importBlock.push(`import${_}*${_}as ${starImport.local} from${_}${pathWithAssertion}`); 9609 } 9610 if (defaultImport && importedNames.length === 0) { 9611 importBlock.push(`import ${defaultImport.local} from${_}${pathWithAssertion}`); 9612 } 9613 else if (importedNames.length > 0) { 9614 importBlock.push(`import ${defaultImport ? `${defaultImport.local},${_}` : ''}{${_}${importedNames 9615 .map(specifier => specifier.imported === specifier.local 9616 ? specifier.imported 9617 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${specifier.local}`) 9618 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`); 9619 } 9620 } 9621 if (reexports) { 9622 let starExport = null; 9623 const namespaceReexports = []; 9624 const namedReexports = []; 9625 for (const specifier of reexports) { 9626 if (specifier.reexported === '*') { 9627 starExport = specifier; 9628 } 9629 else if (specifier.imported === '*') { 9630 namespaceReexports.push(specifier); 9631 } 9632 else { 9633 namedReexports.push(specifier); 9634 } 9635 } 9636 if (starExport) { 9637 importBlock.push(`export${_}*${_}from${_}${pathWithAssertion}`); 9638 } 9639 if (namespaceReexports.length > 0) { 9640 if (!imports || 9641 !imports.some(specifier => specifier.imported === '*' && specifier.local === name)) { 9642 importBlock.push(`import${_}*${_}as ${name} from${_}${pathWithAssertion}`); 9643 } 9644 for (const specifier of namespaceReexports) { 9645 importBlock.push(`export${_}{${_}${name === specifier.reexported 9646 ? name 9647 : `${name} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`} };`); 9648 } 9649 } 9650 if (namedReexports.length > 0) { 9651 importBlock.push(`export${_}{${_}${namedReexports 9652 .map(specifier => specifier.imported === specifier.reexported 9653 ? stringifyIdentifierIfNeeded(specifier.imported) 9654 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`) 9655 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`); 9656 } 9657 } 9658 } 9659 return importBlock; 9660 } 9661 function getExportBlock(exports, { _, cnst }) { 9662 const exportBlock = []; 9663 const exportDeclaration = new Array(exports.length); 9664 let index = 0; 9665 for (const specifier of exports) { 9666 if (specifier.expression) { 9667 exportBlock.push(`${cnst} ${specifier.local}${_}=${_}${specifier.expression};`); 9668 } 9669 exportDeclaration[index++] = 9670 specifier.exported === specifier.local 9671 ? specifier.local 9672 : `${specifier.local} as ${stringifyIdentifierIfNeeded(specifier.exported)}`; 9673 } 9674 if (exportDeclaration.length > 0) { 9675 exportBlock.push(`export${_}{${_}${exportDeclaration.join(`,${_}`)}${_}};`); 9676 } 9677 return exportBlock; 9678 } 9679 9680 const keypath = (keypath, getPropertyAccess) => keypath.split('.').map(getPropertyAccess).join(''); 9681 9682 function setupNamespace(name, root, globals, { _, getPropertyAccess, s }, compact, log) { 9683 const parts = name.split('.'); 9684 // Check if the key exists in the object's prototype. 9685 const isReserved = parts[0] in Object.prototype; 9686 if (log && isReserved) { 9687 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logReservedNamespace(parts[0])); 9688 } 9689 parts[0] = 9690 (typeof globals === 'function' 9691 ? globals(parts[0]) 9692 : isReserved 9693 ? parts[0] 9694 : globals[parts[0]]) || parts[0]; 9695 parts.pop(); 9696 let propertyPath = root; 9697 return (parts 9698 .map(part => { 9699 propertyPath += getPropertyAccess(part); 9700 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}${s}`; 9701 }) 9702 .join(compact ? ',' : '\n') + (compact && parts.length > 0 ? ';' : '\n')); 9703 } 9704 function assignToDeepVariable(deepName, root, globals, assignment, { _, getPropertyAccess }, log) { 9705 const parts = deepName.split('.'); 9706 // Check if the key exists in the object's prototype. 9707 const isReserved = parts[0] in Object.prototype; 9708 if (log && isReserved) { 9709 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logReservedNamespace(parts[0])); 9710 } 9711 parts[0] = 9712 (typeof globals === 'function' 9713 ? globals(parts[0]) 9714 : isReserved 9715 ? parts[0] 9716 : globals[parts[0]]) || parts[0]; 9717 const last = parts.pop(); 9718 let propertyPath = root; 9719 let deepAssignment = [ 9720 ...parts.map(part => { 9721 propertyPath += getPropertyAccess(part); 9722 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}`; 9723 }), 9724 `${propertyPath}${getPropertyAccess(last)}` 9725 ].join(`,${_}`) + `${_}=${_}${assignment}`; 9726 if (parts.length > 0) { 9727 deepAssignment = `(${deepAssignment})`; 9728 } 9729 return deepAssignment; 9730 } 9731 9732 function trimEmptyImports(dependencies) { 9733 let index = dependencies.length; 9734 while (index--) { 9735 const { imports, reexports } = dependencies[index]; 9736 if (imports || reexports) { 9737 return dependencies.slice(0, index + 1); 9738 } 9739 } 9740 return []; 9741 } 9742 9743 function iife(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, indent: t, intro, namedExportsMode, log, outro, snippets }, { compact, esModule, extend, freeze, externalLiveBindings, reexportProtoFromExternal, globals, interop, name, generatedCode: { symbols }, strict }) { 9744 const { _, getNonArrowFunctionIntro, getPropertyAccess, n } = snippets; 9745 const isNamespaced = name && name.includes('.'); 9746 const useVariableAssignment = !extend && !isNamespaced; 9747 if (name && useVariableAssignment && !isLegal(name)) { 9748 return parseAst_js.error(parseAst_js.logIllegalIdentifierAsName(name)); 9749 } 9750 warnOnBuiltins(log, dependencies); 9751 const external = trimEmptyImports(dependencies); 9752 const deps = external.map(dep => dep.globalName || 'null'); 9753 const parameters = external.map(m => m.name); 9754 if (hasExports && !name) { 9755 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingNameOptionForIifeExport()); 9756 } 9757 if (namedExportsMode && hasExports) { 9758 if (extend) { 9759 deps.unshift(`this${keypath(name, getPropertyAccess)}${_}=${_}this${keypath(name, getPropertyAccess)}${_}||${_}{}`); 9760 parameters.unshift('exports'); 9761 } 9762 else { 9763 deps.unshift('{}'); 9764 parameters.unshift('exports'); 9765 } 9766 } 9767 const useStrict = strict ? `${t}'use strict';${n}` : ''; 9768 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets); 9769 magicString.prepend(`${intro}${interopBlock}`); 9770 let wrapperIntro = `(${getNonArrowFunctionIntro(parameters, { 9771 isAsync: false, 9772 name: null 9773 })}{${n}${useStrict}${n}`; 9774 if (hasExports) { 9775 if (name && !(extend && namedExportsMode)) { 9776 wrapperIntro = 9777 (useVariableAssignment ? `var ${name}` : `this${keypath(name, getPropertyAccess)}`) + 9778 `${_}=${_}${wrapperIntro}`; 9779 } 9780 if (isNamespaced) { 9781 wrapperIntro = setupNamespace(name, 'this', globals, snippets, compact, log) + wrapperIntro; 9782 } 9783 } 9784 let wrapperOutro = `${n}${n}})(${deps.join(`,${_}`)});`; 9785 if (hasExports && !extend && namedExportsMode) { 9786 wrapperOutro = `${n}${n}${t}return exports;${wrapperOutro}`; 9787 } 9788 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 9789 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets); 9790 if (namespaceMarkers) { 9791 namespaceMarkers = n + n + namespaceMarkers; 9792 } 9793 magicString 9794 .append(`${exportBlock}${namespaceMarkers}${outro}`) 9795 .indent(t) 9796 .prepend(wrapperIntro) 9797 .append(wrapperOutro); 9798 } 9799 9800 const MISSING_EXPORT_SHIM_VARIABLE = '_missingExportShim'; 9801 9802 function system(magicString, { accessedGlobals, dependencies, exports, hasExports, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) { 9803 const { _, getFunctionIntro, getNonArrowFunctionIntro, n, s } = snippets; 9804 const { importBindings, setters, starExcludes } = analyzeDependencies(dependencies, exports, t, snippets); 9805 const registeredName = name ? `'${name}',${_}` : ''; 9806 const wrapperParameters = accessedGlobals.has('module') 9807 ? ['exports', 'module'] 9808 : hasExports 9809 ? ['exports'] 9810 : []; 9811 // factory function should be wrapped by parentheses to avoid lazy parsing, 9812 // cf. https://v8.dev/blog/preparser#pife 9813 let wrapperStart = `System.register(${registeredName}[` + 9814 dependencies.map(({ importPath }) => `'${importPath}'`).join(`,${_}`) + 9815 `],${_}(${getNonArrowFunctionIntro(wrapperParameters, { 9816 isAsync: false, 9817 name: null 9818 })}{${n}${t}${strict ? "'use strict';" : ''}` + 9819 getStarExcludesBlock(starExcludes, t, snippets) + 9820 getImportBindingsBlock(importBindings, t, snippets) + 9821 `${n}${t}return${_}{${setters.length > 0 9822 ? `${n}${t}${t}setters:${_}[${setters 9823 .map(setter => setter 9824 ? `${getFunctionIntro(['module'], { 9825 isAsync: false, 9826 name: null 9827 })}{${n}${t}${t}${t}${setter}${n}${t}${t}}` 9828 : systemNullSetters 9829 ? `null` 9830 : `${getFunctionIntro([], { isAsync: false, name: null })}{}`) 9831 .join(`,${_}`)}],` 9832 : ''}${n}`; 9833 wrapperStart += `${t}${t}execute:${_}(${getNonArrowFunctionIntro([], { 9834 isAsync: usesTopLevelAwait, 9835 name: null 9836 })}{${n}${n}`; 9837 const wrapperEnd = `${t}${t}})${n}${t}}${s}${n}}));`; 9838 magicString 9839 .prepend(intro + 9840 getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols) + 9841 getHoistedExportsBlock(exports, t, snippets)) 9842 .append(`${outro}${n}${n}` + 9843 getSyntheticExportsBlock(exports, t, snippets) + 9844 getMissingExportsBlock(exports, t, snippets)) 9845 .indent(`${t}${t}${t}`) 9846 .append(wrapperEnd) 9847 .prepend(wrapperStart); 9848 } 9849 function analyzeDependencies(dependencies, exports, t, { _, cnst, getObject, getPropertyAccess, n }) { 9850 const importBindings = []; 9851 const setters = []; 9852 let starExcludes = null; 9853 for (const { imports, reexports } of dependencies) { 9854 const setter = []; 9855 if (imports) { 9856 for (const specifier of imports) { 9857 importBindings.push(specifier.local); 9858 if (specifier.imported === '*') { 9859 setter.push(`${specifier.local}${_}=${_}module;`); 9860 } 9861 else { 9862 setter.push(`${specifier.local}${_}=${_}module${getPropertyAccess(specifier.imported)};`); 9863 } 9864 } 9865 } 9866 if (reexports) { 9867 const reexportedNames = []; 9868 let hasStarReexport = false; 9869 for (const { imported, reexported } of reexports) { 9870 if (reexported === '*') { 9871 hasStarReexport = true; 9872 } 9873 else { 9874 reexportedNames.push([ 9875 reexported, 9876 imported === '*' ? 'module' : `module${getPropertyAccess(imported)}` 9877 ]); 9878 } 9879 } 9880 if (reexportedNames.length > 1 || hasStarReexport) { 9881 if (hasStarReexport) { 9882 if (!starExcludes) { 9883 starExcludes = getStarExcludes({ dependencies, exports }); 9884 } 9885 reexportedNames.unshift([null, `__proto__:${_}null`]); 9886 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null }); 9887 setter.push(`${cnst} setter${_}=${_}${exportMapping};`, `for${_}(${cnst} name in module)${_}{`, `${t}if${_}(!_starExcludes[name])${_}setter[name]${_}=${_}module[name];`, '}', 'exports(setter);'); 9888 } 9889 else { 9890 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null }); 9891 setter.push(`exports(${exportMapping});`); 9892 } 9893 } 9894 else { 9895 const [key, value] = reexportedNames[0]; 9896 setter.push(`exports(${JSON.stringify(key)},${_}${value});`); 9897 } 9898 } 9899 setters.push(setter.join(`${n}${t}${t}${t}`)); 9900 } 9901 return { importBindings, setters, starExcludes }; 9902 } 9903 const getStarExcludes = ({ dependencies, exports }) => { 9904 const starExcludes = new Set(exports.map(expt => expt.exported)); 9905 starExcludes.add('default'); 9906 for (const { reexports } of dependencies) { 9907 if (reexports) { 9908 for (const reexport of reexports) { 9909 if (reexport.reexported !== '*') 9910 starExcludes.add(reexport.reexported); 9911 } 9912 } 9913 } 9914 return starExcludes; 9915 }; 9916 const getStarExcludesBlock = (starExcludes, t, { _, cnst, getObject, n }) => { 9917 if (starExcludes) { 9918 const fields = [...starExcludes].map(property => [ 9919 property, 9920 '1' 9921 ]); 9922 fields.unshift([null, `__proto__:${_}null`]); 9923 return `${n}${t}${cnst} _starExcludes${_}=${_}${getObject(fields, { 9924 lineBreakIndent: { base: t, t } 9925 })};`; 9926 } 9927 return ''; 9928 }; 9929 const getImportBindingsBlock = (importBindings, t, { _, n }) => (importBindings.length > 0 ? `${n}${t}var ${importBindings.join(`,${_}`)};` : ''); 9930 const getHoistedExportsBlock = (exports, t, snippets) => getExportsBlock(exports.filter(expt => expt.hoisted).map(expt => ({ name: expt.exported, value: expt.local })), t, snippets); 9931 function getExportsBlock(exports, t, { _, n }) { 9932 if (exports.length === 0) { 9933 return ''; 9934 } 9935 if (exports.length === 1) { 9936 return `exports(${JSON.stringify(exports[0].name)},${_}${exports[0].value});${n}${n}`; 9937 } 9938 return (`exports({${n}` + 9939 exports 9940 .map(({ name, value }) => `${t}${stringifyObjectKeyIfNeeded(name)}:${_}${value}`) 9941 .join(`,${n}`) + 9942 `${n}});${n}${n}`); 9943 } 9944 const getSyntheticExportsBlock = (exports, t, snippets) => getExportsBlock(exports 9945 .filter(expt => expt.expression) 9946 .map(expt => ({ name: expt.exported, value: expt.local })), t, snippets); 9947 const getMissingExportsBlock = (exports, t, snippets) => getExportsBlock(exports 9948 .filter(expt => expt.local === MISSING_EXPORT_SHIM_VARIABLE) 9949 .map(expt => ({ name: expt.exported, value: MISSING_EXPORT_SHIM_VARIABLE })), t, snippets); 9950 9951 function globalProperty(name, globalVariable, getPropertyAccess) { 9952 if (!name) 9953 return 'null'; 9954 return `${globalVariable}${keypath(name, getPropertyAccess)}`; 9955 } 9956 function safeAccess(name, globalVariable, { _, getPropertyAccess }) { 9957 let propertyPath = globalVariable; 9958 return name 9959 .split('.') 9960 .map(part => (propertyPath += getPropertyAccess(part))) 9961 .join(`${_}&&${_}`); 9962 } 9963 function umd(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, id, indent: t, intro, namedExportsMode, log, outro, snippets }, { amd, compact, esModule, extend, externalLiveBindings, freeze, interop, name, generatedCode: { symbols }, globals, noConflict, reexportProtoFromExternal, strict }) { 9964 const { _, cnst, getFunctionIntro, getNonArrowFunctionIntro, getPropertyAccess, n, s } = snippets; 9965 const factoryVariable = compact ? 'f' : 'factory'; 9966 const globalVariable = compact ? 'g' : 'global'; 9967 if (hasExports && !name) { 9968 return parseAst_js.error(parseAst_js.logMissingNameOptionForUmdExport()); 9969 } 9970 warnOnBuiltins(log, dependencies); 9971 const amdDeps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); 9972 const cjsDeps = dependencies.map(m => `require('${m.importPath}')`); 9973 const trimmedImports = trimEmptyImports(dependencies); 9974 const globalDeps = trimmedImports.map(module => globalProperty(module.globalName, globalVariable, getPropertyAccess)); 9975 const factoryParameters = trimmedImports.map(m => m.name); 9976 if (namedExportsMode && (hasExports || noConflict)) { 9977 amdDeps.unshift(`'exports'`); 9978 cjsDeps.unshift(`exports`); 9979 globalDeps.unshift(assignToDeepVariable(name, globalVariable, globals, `${extend ? `${globalProperty(name, globalVariable, getPropertyAccess)}${_}||${_}` : ''}{}`, snippets, log)); 9980 factoryParameters.unshift('exports'); 9981 } 9982 const completeAmdId = getCompleteAmdId(amd, id); 9983 const amdParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) + 9984 (amdDeps.length > 0 ? `[${amdDeps.join(`,${_}`)}],${_}` : ``); 9985 const define = amd.define; 9986 const cjsExport = !namedExportsMode && hasExports ? `module.exports${_}=${_}` : ``; 9987 const useStrict = strict ? `${_}'use strict';${n}` : ``; 9988 let iifeExport; 9989 if (noConflict) { 9990 const noConflictExportsVariable = compact ? 'e' : 'exports'; 9991 let factory; 9992 if (!namedExportsMode && hasExports) { 9993 factory = `${cnst} ${noConflictExportsVariable}${_}=${_}${assignToDeepVariable(name, globalVariable, globals, `${factoryVariable}(${globalDeps.join(`,${_}`)})`, snippets, log)};`; 9994 } 9995 else { 9996 const module = globalDeps.shift(); 9997 factory = 9998 `${cnst} ${noConflictExportsVariable}${_}=${_}${module};${n}` + 9999 `${t}${t}${factoryVariable}(${[noConflictExportsVariable, ...globalDeps].join(`,${_}`)});`; 10000 } 10001 iifeExport = 10002 `(${getFunctionIntro([], { isAsync: false, name: null })}{${n}` + 10003 `${t}${t}${cnst} current${_}=${_}${safeAccess(name, globalVariable, snippets)};${n}` + 10004 `${t}${t}${factory}${n}` + 10005 `${t}${t}${noConflictExportsVariable}.noConflict${_}=${_}${getFunctionIntro([], { 10006 isAsync: false, 10007 name: null 10008 })}{${_}` + 10009 `${globalProperty(name, globalVariable, getPropertyAccess)}${_}=${_}current;${_}return ${noConflictExportsVariable}${s}${_}};${n}` + 10010 `${t}})()`; 10011 } 10012 else { 10013 iifeExport = `${factoryVariable}(${globalDeps.join(`,${_}`)})`; 10014 if (!namedExportsMode && hasExports) { 10015 iifeExport = assignToDeepVariable(name, globalVariable, globals, iifeExport, snippets, log); 10016 } 10017 } 10018 const iifeNeedsGlobal = hasExports || (noConflict && namedExportsMode) || globalDeps.length > 0; 10019 const wrapperParameters = [factoryVariable]; 10020 if (iifeNeedsGlobal) { 10021 wrapperParameters.unshift(globalVariable); 10022 } 10023 const globalArgument = iifeNeedsGlobal ? `this,${_}` : ''; 10024 const iifeStart = iifeNeedsGlobal 10025 ? `(${globalVariable}${_}=${_}typeof globalThis${_}!==${_}'undefined'${_}?${_}globalThis${_}:${_}${globalVariable}${_}||${_}self,${_}` 10026 : ''; 10027 const iifeEnd = iifeNeedsGlobal ? ')' : ''; 10028 const cjsIntro = iifeNeedsGlobal 10029 ? `${t}typeof exports${_}===${_}'object'${_}&&${_}typeof module${_}!==${_}'undefined'${_}?` + 10030 `${_}${cjsExport}${factoryVariable}(${cjsDeps.join(`,${_}`)})${_}:${n}` 10031 : ''; 10032 const wrapperIntro = `(${getNonArrowFunctionIntro(wrapperParameters, { isAsync: false, name: null })}{${n}` + 10033 cjsIntro + 10034 `${t}typeof ${define}${_}===${_}'function'${_}&&${_}${define}.amd${_}?${_}${define}(${amdParameters}${factoryVariable})${_}:${n}` + 10035 `${t}${iifeStart}${iifeExport}${iifeEnd};${n}` + 10036 // factory function should be wrapped by parentheses to avoid lazy parsing, 10037 // cf. https://v8.dev/blog/preparser#pife 10038 `})(${globalArgument}(${getNonArrowFunctionIntro(factoryParameters, { 10039 isAsync: false, 10040 name: null 10041 })}{${useStrict}${n}`; 10042 const wrapperOutro = n + n + '}));'; 10043 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`); 10044 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 10045 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets); 10046 if (namespaceMarkers) { 10047 namespaceMarkers = n + n + namespaceMarkers; 10048 } 10049 magicString 10050 .append(`${exportBlock}${namespaceMarkers}${outro}`) 10051 .trim() 10052 .indent(t) 10053 .append(wrapperOutro) 10054 .prepend(wrapperIntro); 10055 } 10056 10057 const finalisers = { amd, cjs, es, iife, system, umd }; 10058 10059 function getDefaultExportFromCjs (x) { 10060 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 10061 } 10062 10063 function getAugmentedNamespace(n) { 10064 if (n.__esModule) return n; 10065 var f = n.default; 10066 if (typeof f == "function") { 10067 var a = function a () { 10068 if (this instanceof a) { 10069 return Reflect.construct(f, arguments, this.constructor); 10070 } 10071 return f.apply(this, arguments); 10072 }; 10073 a.prototype = f.prototype; 10074 } else a = {}; 10075 Object.defineProperty(a, '__esModule', {value: true}); 10076 Object.keys(n).forEach(function (k) { 10077 var d = Object.getOwnPropertyDescriptor(n, k); 10078 Object.defineProperty(a, k, d.get ? d : { 10079 enumerable: true, 10080 get: function () { 10081 return n[k]; 10082 } 10083 }); 10084 }); 10085 return a; 10086 } 10087 10088 var utils = {}; 10089 10090 var constants; 10091 var hasRequiredConstants; 10092 10093 function requireConstants () { 10094 if (hasRequiredConstants) return constants; 10095 hasRequiredConstants = 1; 10096 10097 const WIN_SLASH = '\\\\/'; 10098 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 10099 10100 /** 10101 * Posix glob regex 10102 */ 10103 10104 const DOT_LITERAL = '\\.'; 10105 const PLUS_LITERAL = '\\+'; 10106 const QMARK_LITERAL = '\\?'; 10107 const SLASH_LITERAL = '\\/'; 10108 const ONE_CHAR = '(?=.)'; 10109 const QMARK = '[^/]'; 10110 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 10111 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 10112 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 10113 const NO_DOT = `(?!${DOT_LITERAL})`; 10114 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 10115 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 10116 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 10117 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 10118 const STAR = `${QMARK}*?`; 10119 const SEP = '/'; 10120 10121 const POSIX_CHARS = { 10122 DOT_LITERAL, 10123 PLUS_LITERAL, 10124 QMARK_LITERAL, 10125 SLASH_LITERAL, 10126 ONE_CHAR, 10127 QMARK, 10128 END_ANCHOR, 10129 DOTS_SLASH, 10130 NO_DOT, 10131 NO_DOTS, 10132 NO_DOT_SLASH, 10133 NO_DOTS_SLASH, 10134 QMARK_NO_DOT, 10135 STAR, 10136 START_ANCHOR, 10137 SEP 10138 }; 10139 10140 /** 10141 * Windows glob regex 10142 */ 10143 10144 const WINDOWS_CHARS = { 10145 ...POSIX_CHARS, 10146 10147 SLASH_LITERAL: `[${WIN_SLASH}]`, 10148 QMARK: WIN_NO_SLASH, 10149 STAR: `${WIN_NO_SLASH}*?`, 10150 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, 10151 NO_DOT: `(?!${DOT_LITERAL})`, 10152 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 10153 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, 10154 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 10155 QMARK_NO_DOT: `[^.${WIN_SLASH}]`, 10156 START_ANCHOR: `(?:^|[${WIN_SLASH}])`, 10157 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`, 10158 SEP: '\\' 10159 }; 10160 10161 /** 10162 * POSIX Bracket Regex 10163 */ 10164 10165 const POSIX_REGEX_SOURCE = { 10166 alnum: 'a-zA-Z0-9', 10167 alpha: 'a-zA-Z', 10168 ascii: '\\x00-\\x7F', 10169 blank: ' \\t', 10170 cntrl: '\\x00-\\x1F\\x7F', 10171 digit: '0-9', 10172 graph: '\\x21-\\x7E', 10173 lower: 'a-z', 10174 print: '\\x20-\\x7E ', 10175 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', 10176 space: ' \\t\\r\\n\\v\\f', 10177 upper: 'A-Z', 10178 word: 'A-Za-z0-9_', 10179 xdigit: 'A-Fa-f0-9' 10180 }; 10181 10182 constants = { 10183 MAX_LENGTH: 1024 * 64, 10184 POSIX_REGEX_SOURCE, 10185 10186 // regular expressions 10187 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, 10188 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, 10189 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, 10190 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, 10191 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, 10192 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, 10193 10194 // Replace globs with equivalent patterns to reduce parsing time. 10195 REPLACEMENTS: { 10196 '***': '*', 10197 '**/**': '**', 10198 '**/**/**': '**' 10199 }, 10200 10201 // Digits 10202 CHAR_0: 48, /* 0 */ 10203 CHAR_9: 57, /* 9 */ 10204 10205 // Alphabet chars. 10206 CHAR_UPPERCASE_A: 65, /* A */ 10207 CHAR_LOWERCASE_A: 97, /* a */ 10208 CHAR_UPPERCASE_Z: 90, /* Z */ 10209 CHAR_LOWERCASE_Z: 122, /* z */ 10210 10211 CHAR_LEFT_PARENTHESES: 40, /* ( */ 10212 CHAR_RIGHT_PARENTHESES: 41, /* ) */ 10213 10214 CHAR_ASTERISK: 42, /* * */ 10215 10216 // Non-alphabetic chars. 10217 CHAR_AMPERSAND: 38, /* & */ 10218 CHAR_AT: 64, /* @ */ 10219 CHAR_BACKWARD_SLASH: 92, /* \ */ 10220 CHAR_CARRIAGE_RETURN: 13, /* \r */ 10221 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ 10222 CHAR_COLON: 58, /* : */ 10223 CHAR_COMMA: 44, /* , */ 10224 CHAR_DOT: 46, /* . */ 10225 CHAR_DOUBLE_QUOTE: 34, /* " */ 10226 CHAR_EQUAL: 61, /* = */ 10227 CHAR_EXCLAMATION_MARK: 33, /* ! */ 10228 CHAR_FORM_FEED: 12, /* \f */ 10229 CHAR_FORWARD_SLASH: 47, /* / */ 10230 CHAR_GRAVE_ACCENT: 96, /* ` */ 10231 CHAR_HASH: 35, /* # */ 10232 CHAR_HYPHEN_MINUS: 45, /* - */ 10233 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ 10234 CHAR_LEFT_CURLY_BRACE: 123, /* { */ 10235 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ 10236 CHAR_LINE_FEED: 10, /* \n */ 10237 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ 10238 CHAR_PERCENT: 37, /* % */ 10239 CHAR_PLUS: 43, /* + */ 10240 CHAR_QUESTION_MARK: 63, /* ? */ 10241 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ 10242 CHAR_RIGHT_CURLY_BRACE: 125, /* } */ 10243 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ 10244 CHAR_SEMICOLON: 59, /* ; */ 10245 CHAR_SINGLE_QUOTE: 39, /* ' */ 10246 CHAR_SPACE: 32, /* */ 10247 CHAR_TAB: 9, /* \t */ 10248 CHAR_UNDERSCORE: 95, /* _ */ 10249 CHAR_VERTICAL_LINE: 124, /* | */ 10250 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ 10251 10252 /** 10253 * Create EXTGLOB_CHARS 10254 */ 10255 10256 extglobChars(chars) { 10257 return { 10258 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, 10259 '?': { type: 'qmark', open: '(?:', close: ')?' }, 10260 '+': { type: 'plus', open: '(?:', close: ')+' }, 10261 '*': { type: 'star', open: '(?:', close: ')*' }, 10262 '@': { type: 'at', open: '(?:', close: ')' } 10263 }; 10264 }, 10265 10266 /** 10267 * Create GLOB_CHARS 10268 */ 10269 10270 globChars(win32) { 10271 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; 10272 } 10273 }; 10274 return constants; 10275 } 10276 10277 /*global navigator*/ 10278 10279 var hasRequiredUtils; 10280 10281 function requireUtils () { 10282 if (hasRequiredUtils) return utils; 10283 hasRequiredUtils = 1; 10284 (function (exports) { 10285 10286 const { 10287 REGEX_BACKSLASH, 10288 REGEX_REMOVE_BACKSLASH, 10289 REGEX_SPECIAL_CHARS, 10290 REGEX_SPECIAL_CHARS_GLOBAL 10291 } = /*@__PURE__*/ requireConstants(); 10292 10293 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 10294 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); 10295 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); 10296 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); 10297 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); 10298 10299 exports.isWindows = () => { 10300 if (typeof navigator !== 'undefined' && navigator.platform) { 10301 const platform = navigator.platform.toLowerCase(); 10302 return platform === 'win32' || platform === 'windows'; 10303 } 10304 10305 if (typeof process !== 'undefined' && process.platform) { 10306 return process.platform === 'win32'; 10307 } 10308 10309 return false; 10310 }; 10311 10312 exports.removeBackslashes = str => { 10313 return str.replace(REGEX_REMOVE_BACKSLASH, match => { 10314 return match === '\\' ? '' : match; 10315 }); 10316 }; 10317 10318 exports.escapeLast = (input, char, lastIdx) => { 10319 const idx = input.lastIndexOf(char, lastIdx); 10320 if (idx === -1) return input; 10321 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); 10322 return `${input.slice(0, idx)}\\${input.slice(idx)}`; 10323 }; 10324 10325 exports.removePrefix = (input, state = {}) => { 10326 let output = input; 10327 if (output.startsWith('./')) { 10328 output = output.slice(2); 10329 state.prefix = './'; 10330 } 10331 return output; 10332 }; 10333 10334 exports.wrapOutput = (input, state = {}, options = {}) => { 10335 const prepend = options.contains ? '' : '^'; 10336 const append = options.contains ? '' : '$'; 10337 10338 let output = `${prepend}(?:${input})${append}`; 10339 if (state.negated === true) { 10340 output = `(?:^(?!${output}).*$)`; 10341 } 10342 return output; 10343 }; 10344 10345 exports.basename = (path, { windows } = {}) => { 10346 const segs = path.split(windows ? /[\\/]/ : '/'); 10347 const last = segs[segs.length - 1]; 10348 10349 if (last === '') { 10350 return segs[segs.length - 2]; 10351 } 10352 10353 return last; 10354 }; 10355 } (utils)); 10356 return utils; 10357 } 10358 10359 var scan_1; 10360 var hasRequiredScan; 10361 10362 function requireScan () { 10363 if (hasRequiredScan) return scan_1; 10364 hasRequiredScan = 1; 10365 10366 const utils = /*@__PURE__*/ requireUtils(); 10367 const { 10368 CHAR_ASTERISK, /* * */ 10369 CHAR_AT, /* @ */ 10370 CHAR_BACKWARD_SLASH, /* \ */ 10371 CHAR_COMMA, /* , */ 10372 CHAR_DOT, /* . */ 10373 CHAR_EXCLAMATION_MARK, /* ! */ 10374 CHAR_FORWARD_SLASH, /* / */ 10375 CHAR_LEFT_CURLY_BRACE, /* { */ 10376 CHAR_LEFT_PARENTHESES, /* ( */ 10377 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 10378 CHAR_PLUS, /* + */ 10379 CHAR_QUESTION_MARK, /* ? */ 10380 CHAR_RIGHT_CURLY_BRACE, /* } */ 10381 CHAR_RIGHT_PARENTHESES, /* ) */ 10382 CHAR_RIGHT_SQUARE_BRACKET /* ] */ 10383 } = /*@__PURE__*/ requireConstants(); 10384 10385 const isPathSeparator = code => { 10386 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; 10387 }; 10388 10389 const depth = token => { 10390 if (token.isPrefix !== true) { 10391 token.depth = token.isGlobstar ? Infinity : 1; 10392 } 10393 }; 10394 10395 /** 10396 * Quickly scans a glob pattern and returns an object with a handful of 10397 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), 10398 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not 10399 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). 10400 * 10401 * ```js 10402 * const pm = require('picomatch'); 10403 * console.log(pm.scan('foo/bar/*.js')); 10404 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } 10405 * ``` 10406 * @param {String} `str` 10407 * @param {Object} `options` 10408 * @return {Object} Returns an object with tokens and regex source string. 10409 * @api public 10410 */ 10411 10412 const scan = (input, options) => { 10413 const opts = options || {}; 10414 10415 const length = input.length - 1; 10416 const scanToEnd = opts.parts === true || opts.scanToEnd === true; 10417 const slashes = []; 10418 const tokens = []; 10419 const parts = []; 10420 10421 let str = input; 10422 let index = -1; 10423 let start = 0; 10424 let lastIndex = 0; 10425 let isBrace = false; 10426 let isBracket = false; 10427 let isGlob = false; 10428 let isExtglob = false; 10429 let isGlobstar = false; 10430 let braceEscaped = false; 10431 let backslashes = false; 10432 let negated = false; 10433 let negatedExtglob = false; 10434 let finished = false; 10435 let braces = 0; 10436 let prev; 10437 let code; 10438 let token = { value: '', depth: 0, isGlob: false }; 10439 10440 const eos = () => index >= length; 10441 const peek = () => str.charCodeAt(index + 1); 10442 const advance = () => { 10443 prev = code; 10444 return str.charCodeAt(++index); 10445 }; 10446 10447 while (index < length) { 10448 code = advance(); 10449 let next; 10450 10451 if (code === CHAR_BACKWARD_SLASH) { 10452 backslashes = token.backslashes = true; 10453 code = advance(); 10454 10455 if (code === CHAR_LEFT_CURLY_BRACE) { 10456 braceEscaped = true; 10457 } 10458 continue; 10459 } 10460 10461 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { 10462 braces++; 10463 10464 while (eos() !== true && (code = advance())) { 10465 if (code === CHAR_BACKWARD_SLASH) { 10466 backslashes = token.backslashes = true; 10467 advance(); 10468 continue; 10469 } 10470 10471 if (code === CHAR_LEFT_CURLY_BRACE) { 10472 braces++; 10473 continue; 10474 } 10475 10476 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { 10477 isBrace = token.isBrace = true; 10478 isGlob = token.isGlob = true; 10479 finished = true; 10480 10481 if (scanToEnd === true) { 10482 continue; 10483 } 10484 10485 break; 10486 } 10487 10488 if (braceEscaped !== true && code === CHAR_COMMA) { 10489 isBrace = token.isBrace = true; 10490 isGlob = token.isGlob = true; 10491 finished = true; 10492 10493 if (scanToEnd === true) { 10494 continue; 10495 } 10496 10497 break; 10498 } 10499 10500 if (code === CHAR_RIGHT_CURLY_BRACE) { 10501 braces--; 10502 10503 if (braces === 0) { 10504 braceEscaped = false; 10505 isBrace = token.isBrace = true; 10506 finished = true; 10507 break; 10508 } 10509 } 10510 } 10511 10512 if (scanToEnd === true) { 10513 continue; 10514 } 10515 10516 break; 10517 } 10518 10519 if (code === CHAR_FORWARD_SLASH) { 10520 slashes.push(index); 10521 tokens.push(token); 10522 token = { value: '', depth: 0, isGlob: false }; 10523 10524 if (finished === true) continue; 10525 if (prev === CHAR_DOT && index === (start + 1)) { 10526 start += 2; 10527 continue; 10528 } 10529 10530 lastIndex = index + 1; 10531 continue; 10532 } 10533 10534 if (opts.noext !== true) { 10535 const isExtglobChar = code === CHAR_PLUS 10536 || code === CHAR_AT 10537 || code === CHAR_ASTERISK 10538 || code === CHAR_QUESTION_MARK 10539 || code === CHAR_EXCLAMATION_MARK; 10540 10541 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { 10542 isGlob = token.isGlob = true; 10543 isExtglob = token.isExtglob = true; 10544 finished = true; 10545 if (code === CHAR_EXCLAMATION_MARK && index === start) { 10546 negatedExtglob = true; 10547 } 10548 10549 if (scanToEnd === true) { 10550 while (eos() !== true && (code = advance())) { 10551 if (code === CHAR_BACKWARD_SLASH) { 10552 backslashes = token.backslashes = true; 10553 code = advance(); 10554 continue; 10555 } 10556 10557 if (code === CHAR_RIGHT_PARENTHESES) { 10558 isGlob = token.isGlob = true; 10559 finished = true; 10560 break; 10561 } 10562 } 10563 continue; 10564 } 10565 break; 10566 } 10567 } 10568 10569 if (code === CHAR_ASTERISK) { 10570 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; 10571 isGlob = token.isGlob = true; 10572 finished = true; 10573 10574 if (scanToEnd === true) { 10575 continue; 10576 } 10577 break; 10578 } 10579 10580 if (code === CHAR_QUESTION_MARK) { 10581 isGlob = token.isGlob = true; 10582 finished = true; 10583 10584 if (scanToEnd === true) { 10585 continue; 10586 } 10587 break; 10588 } 10589 10590 if (code === CHAR_LEFT_SQUARE_BRACKET) { 10591 while (eos() !== true && (next = advance())) { 10592 if (next === CHAR_BACKWARD_SLASH) { 10593 backslashes = token.backslashes = true; 10594 advance(); 10595 continue; 10596 } 10597 10598 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 10599 isBracket = token.isBracket = true; 10600 isGlob = token.isGlob = true; 10601 finished = true; 10602 break; 10603 } 10604 } 10605 10606 if (scanToEnd === true) { 10607 continue; 10608 } 10609 10610 break; 10611 } 10612 10613 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { 10614 negated = token.negated = true; 10615 start++; 10616 continue; 10617 } 10618 10619 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { 10620 isGlob = token.isGlob = true; 10621 10622 if (scanToEnd === true) { 10623 while (eos() !== true && (code = advance())) { 10624 if (code === CHAR_LEFT_PARENTHESES) { 10625 backslashes = token.backslashes = true; 10626 code = advance(); 10627 continue; 10628 } 10629 10630 if (code === CHAR_RIGHT_PARENTHESES) { 10631 finished = true; 10632 break; 10633 } 10634 } 10635 continue; 10636 } 10637 break; 10638 } 10639 10640 if (isGlob === true) { 10641 finished = true; 10642 10643 if (scanToEnd === true) { 10644 continue; 10645 } 10646 10647 break; 10648 } 10649 } 10650 10651 if (opts.noext === true) { 10652 isExtglob = false; 10653 isGlob = false; 10654 } 10655 10656 let base = str; 10657 let prefix = ''; 10658 let glob = ''; 10659 10660 if (start > 0) { 10661 prefix = str.slice(0, start); 10662 str = str.slice(start); 10663 lastIndex -= start; 10664 } 10665 10666 if (base && isGlob === true && lastIndex > 0) { 10667 base = str.slice(0, lastIndex); 10668 glob = str.slice(lastIndex); 10669 } else if (isGlob === true) { 10670 base = ''; 10671 glob = str; 10672 } else { 10673 base = str; 10674 } 10675 10676 if (base && base !== '' && base !== '/' && base !== str) { 10677 if (isPathSeparator(base.charCodeAt(base.length - 1))) { 10678 base = base.slice(0, -1); 10679 } 10680 } 10681 10682 if (opts.unescape === true) { 10683 if (glob) glob = utils.removeBackslashes(glob); 10684 10685 if (base && backslashes === true) { 10686 base = utils.removeBackslashes(base); 10687 } 10688 } 10689 10690 const state = { 10691 prefix, 10692 input, 10693 start, 10694 base, 10695 glob, 10696 isBrace, 10697 isBracket, 10698 isGlob, 10699 isExtglob, 10700 isGlobstar, 10701 negated, 10702 negatedExtglob 10703 }; 10704 10705 if (opts.tokens === true) { 10706 state.maxDepth = 0; 10707 if (!isPathSeparator(code)) { 10708 tokens.push(token); 10709 } 10710 state.tokens = tokens; 10711 } 10712 10713 if (opts.parts === true || opts.tokens === true) { 10714 let prevIndex; 10715 10716 for (let idx = 0; idx < slashes.length; idx++) { 10717 const n = prevIndex ? prevIndex + 1 : start; 10718 const i = slashes[idx]; 10719 const value = input.slice(n, i); 10720 if (opts.tokens) { 10721 if (idx === 0 && start !== 0) { 10722 tokens[idx].isPrefix = true; 10723 tokens[idx].value = prefix; 10724 } else { 10725 tokens[idx].value = value; 10726 } 10727 depth(tokens[idx]); 10728 state.maxDepth += tokens[idx].depth; 10729 } 10730 if (idx !== 0 || value !== '') { 10731 parts.push(value); 10732 } 10733 prevIndex = i; 10734 } 10735 10736 if (prevIndex && prevIndex + 1 < input.length) { 10737 const value = input.slice(prevIndex + 1); 10738 parts.push(value); 10739 10740 if (opts.tokens) { 10741 tokens[tokens.length - 1].value = value; 10742 depth(tokens[tokens.length - 1]); 10743 state.maxDepth += tokens[tokens.length - 1].depth; 10744 } 10745 } 10746 10747 state.slashes = slashes; 10748 state.parts = parts; 10749 } 10750 10751 return state; 10752 }; 10753 10754 scan_1 = scan; 10755 return scan_1; 10756 } 10757 10758 var parse_1; 10759 var hasRequiredParse; 10760 10761 function requireParse () { 10762 if (hasRequiredParse) return parse_1; 10763 hasRequiredParse = 1; 10764 10765 const constants = /*@__PURE__*/ requireConstants(); 10766 const utils = /*@__PURE__*/ requireUtils(); 10767 10768 /** 10769 * Constants 10770 */ 10771 10772 const { 10773 MAX_LENGTH, 10774 POSIX_REGEX_SOURCE, 10775 REGEX_NON_SPECIAL_CHARS, 10776 REGEX_SPECIAL_CHARS_BACKREF, 10777 REPLACEMENTS 10778 } = constants; 10779 10780 /** 10781 * Helpers 10782 */ 10783 10784 const expandRange = (args, options) => { 10785 if (typeof options.expandRange === 'function') { 10786 return options.expandRange(...args, options); 10787 } 10788 10789 args.sort(); 10790 const value = `[${args.join('-')}]`; 10791 10792 return value; 10793 }; 10794 10795 /** 10796 * Create the message for a syntax error 10797 */ 10798 10799 const syntaxError = (type, char) => { 10800 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; 10801 }; 10802 10803 /** 10804 * Parse the given input string. 10805 * @param {String} input 10806 * @param {Object} options 10807 * @return {Object} 10808 */ 10809 10810 const parse = (input, options) => { 10811 if (typeof input !== 'string') { 10812 throw new TypeError('Expected a string'); 10813 } 10814 10815 input = REPLACEMENTS[input] || input; 10816 10817 const opts = { ...options }; 10818 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 10819 10820 let len = input.length; 10821 if (len > max) { 10822 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 10823 } 10824 10825 const bos = { type: 'bos', value: '', output: opts.prepend || '' }; 10826 const tokens = [bos]; 10827 10828 const capture = opts.capture ? '' : '?:'; 10829 10830 // create constants based on platform, for windows or posix 10831 const PLATFORM_CHARS = constants.globChars(opts.windows); 10832 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); 10833 10834 const { 10835 DOT_LITERAL, 10836 PLUS_LITERAL, 10837 SLASH_LITERAL, 10838 ONE_CHAR, 10839 DOTS_SLASH, 10840 NO_DOT, 10841 NO_DOT_SLASH, 10842 NO_DOTS_SLASH, 10843 QMARK, 10844 QMARK_NO_DOT, 10845 STAR, 10846 START_ANCHOR 10847 } = PLATFORM_CHARS; 10848 10849 const globstar = opts => { 10850 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 10851 }; 10852 10853 const nodot = opts.dot ? '' : NO_DOT; 10854 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; 10855 let star = opts.bash === true ? globstar(opts) : STAR; 10856 10857 if (opts.capture) { 10858 star = `(${star})`; 10859 } 10860 10861 // minimatch options support 10862 if (typeof opts.noext === 'boolean') { 10863 opts.noextglob = opts.noext; 10864 } 10865 10866 const state = { 10867 input, 10868 index: -1, 10869 start: 0, 10870 dot: opts.dot === true, 10871 consumed: '', 10872 output: '', 10873 prefix: '', 10874 backtrack: false, 10875 negated: false, 10876 brackets: 0, 10877 braces: 0, 10878 parens: 0, 10879 quotes: 0, 10880 globstar: false, 10881 tokens 10882 }; 10883 10884 input = utils.removePrefix(input, state); 10885 len = input.length; 10886 10887 const extglobs = []; 10888 const braces = []; 10889 const stack = []; 10890 let prev = bos; 10891 let value; 10892 10893 /** 10894 * Tokenizing helpers 10895 */ 10896 10897 const eos = () => state.index === len - 1; 10898 const peek = state.peek = (n = 1) => input[state.index + n]; 10899 const advance = state.advance = () => input[++state.index] || ''; 10900 const remaining = () => input.slice(state.index + 1); 10901 const consume = (value = '', num = 0) => { 10902 state.consumed += value; 10903 state.index += num; 10904 }; 10905 10906 const append = token => { 10907 state.output += token.output != null ? token.output : token.value; 10908 consume(token.value); 10909 }; 10910 10911 const negate = () => { 10912 let count = 1; 10913 10914 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { 10915 advance(); 10916 state.start++; 10917 count++; 10918 } 10919 10920 if (count % 2 === 0) { 10921 return false; 10922 } 10923 10924 state.negated = true; 10925 state.start++; 10926 return true; 10927 }; 10928 10929 const increment = type => { 10930 state[type]++; 10931 stack.push(type); 10932 }; 10933 10934 const decrement = type => { 10935 state[type]--; 10936 stack.pop(); 10937 }; 10938 10939 /** 10940 * Push tokens onto the tokens array. This helper speeds up 10941 * tokenizing by 1) helping us avoid backtracking as much as possible, 10942 * and 2) helping us avoid creating extra tokens when consecutive 10943 * characters are plain text. This improves performance and simplifies 10944 * lookbehinds. 10945 */ 10946 10947 const push = tok => { 10948 if (prev.type === 'globstar') { 10949 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); 10950 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); 10951 10952 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { 10953 state.output = state.output.slice(0, -prev.output.length); 10954 prev.type = 'star'; 10955 prev.value = '*'; 10956 prev.output = star; 10957 state.output += prev.output; 10958 } 10959 } 10960 10961 if (extglobs.length && tok.type !== 'paren') { 10962 extglobs[extglobs.length - 1].inner += tok.value; 10963 } 10964 10965 if (tok.value || tok.output) append(tok); 10966 if (prev && prev.type === 'text' && tok.type === 'text') { 10967 prev.output = (prev.output || prev.value) + tok.value; 10968 prev.value += tok.value; 10969 return; 10970 } 10971 10972 tok.prev = prev; 10973 tokens.push(tok); 10974 prev = tok; 10975 }; 10976 10977 const extglobOpen = (type, value) => { 10978 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; 10979 10980 token.prev = prev; 10981 token.parens = state.parens; 10982 token.output = state.output; 10983 const output = (opts.capture ? '(' : '') + token.open; 10984 10985 increment('parens'); 10986 push({ type, value, output: state.output ? '' : ONE_CHAR }); 10987 push({ type: 'paren', extglob: true, value: advance(), output }); 10988 extglobs.push(token); 10989 }; 10990 10991 const extglobClose = token => { 10992 let output = token.close + (opts.capture ? ')' : ''); 10993 let rest; 10994 10995 if (token.type === 'negate') { 10996 let extglobStar = star; 10997 10998 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { 10999 extglobStar = globstar(opts); 11000 } 11001 11002 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { 11003 output = token.close = `)$))${extglobStar}`; 11004 } 11005 11006 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { 11007 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. 11008 // In this case, we need to parse the string and use it in the output of the original pattern. 11009 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. 11010 // 11011 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. 11012 const expression = parse(rest, { ...options, fastpaths: false }).output; 11013 11014 output = token.close = `)${expression})${extglobStar})`; 11015 } 11016 11017 if (token.prev.type === 'bos') { 11018 state.negatedExtglob = true; 11019 } 11020 } 11021 11022 push({ type: 'paren', extglob: true, value, output }); 11023 decrement('parens'); 11024 }; 11025 11026 /** 11027 * Fast paths 11028 */ 11029 11030 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { 11031 let backslashes = false; 11032 11033 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { 11034 if (first === '\\') { 11035 backslashes = true; 11036 return m; 11037 } 11038 11039 if (first === '?') { 11040 if (esc) { 11041 return esc + first + (rest ? QMARK.repeat(rest.length) : ''); 11042 } 11043 if (index === 0) { 11044 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); 11045 } 11046 return QMARK.repeat(chars.length); 11047 } 11048 11049 if (first === '.') { 11050 return DOT_LITERAL.repeat(chars.length); 11051 } 11052 11053 if (first === '*') { 11054 if (esc) { 11055 return esc + first + (rest ? star : ''); 11056 } 11057 return star; 11058 } 11059 return esc ? m : `\\${m}`; 11060 }); 11061 11062 if (backslashes === true) { 11063 if (opts.unescape === true) { 11064 output = output.replace(/\\/g, ''); 11065 } else { 11066 output = output.replace(/\\+/g, m => { 11067 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); 11068 }); 11069 } 11070 } 11071 11072 if (output === input && opts.contains === true) { 11073 state.output = input; 11074 return state; 11075 } 11076 11077 state.output = utils.wrapOutput(output, state, options); 11078 return state; 11079 } 11080 11081 /** 11082 * Tokenize input until we reach end-of-string 11083 */ 11084 11085 while (!eos()) { 11086 value = advance(); 11087 11088 if (value === '\u0000') { 11089 continue; 11090 } 11091 11092 /** 11093 * Escaped characters 11094 */ 11095 11096 if (value === '\\') { 11097 const next = peek(); 11098 11099 if (next === '/' && opts.bash !== true) { 11100 continue; 11101 } 11102 11103 if (next === '.' || next === ';') { 11104 continue; 11105 } 11106 11107 if (!next) { 11108 value += '\\'; 11109 push({ type: 'text', value }); 11110 continue; 11111 } 11112 11113 // collapse slashes to reduce potential for exploits 11114 const match = /^\\+/.exec(remaining()); 11115 let slashes = 0; 11116 11117 if (match && match[0].length > 2) { 11118 slashes = match[0].length; 11119 state.index += slashes; 11120 if (slashes % 2 !== 0) { 11121 value += '\\'; 11122 } 11123 } 11124 11125 if (opts.unescape === true) { 11126 value = advance(); 11127 } else { 11128 value += advance(); 11129 } 11130 11131 if (state.brackets === 0) { 11132 push({ type: 'text', value }); 11133 continue; 11134 } 11135 } 11136 11137 /** 11138 * If we're inside a regex character class, continue 11139 * until we reach the closing bracket. 11140 */ 11141 11142 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { 11143 if (opts.posix !== false && value === ':') { 11144 const inner = prev.value.slice(1); 11145 if (inner.includes('[')) { 11146 prev.posix = true; 11147 11148 if (inner.includes(':')) { 11149 const idx = prev.value.lastIndexOf('['); 11150 const pre = prev.value.slice(0, idx); 11151 const rest = prev.value.slice(idx + 2); 11152 const posix = POSIX_REGEX_SOURCE[rest]; 11153 if (posix) { 11154 prev.value = pre + posix; 11155 state.backtrack = true; 11156 advance(); 11157 11158 if (!bos.output && tokens.indexOf(prev) === 1) { 11159 bos.output = ONE_CHAR; 11160 } 11161 continue; 11162 } 11163 } 11164 } 11165 } 11166 11167 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { 11168 value = `\\${value}`; 11169 } 11170 11171 if (value === ']' && (prev.value === '[' || prev.value === '[^')) { 11172 value = `\\${value}`; 11173 } 11174 11175 if (opts.posix === true && value === '!' && prev.value === '[') { 11176 value = '^'; 11177 } 11178 11179 prev.value += value; 11180 append({ value }); 11181 continue; 11182 } 11183 11184 /** 11185 * If we're inside a quoted string, continue 11186 * until we reach the closing double quote. 11187 */ 11188 11189 if (state.quotes === 1 && value !== '"') { 11190 value = utils.escapeRegex(value); 11191 prev.value += value; 11192 append({ value }); 11193 continue; 11194 } 11195 11196 /** 11197 * Double quotes 11198 */ 11199 11200 if (value === '"') { 11201 state.quotes = state.quotes === 1 ? 0 : 1; 11202 if (opts.keepQuotes === true) { 11203 push({ type: 'text', value }); 11204 } 11205 continue; 11206 } 11207 11208 /** 11209 * Parentheses 11210 */ 11211 11212 if (value === '(') { 11213 increment('parens'); 11214 push({ type: 'paren', value }); 11215 continue; 11216 } 11217 11218 if (value === ')') { 11219 if (state.parens === 0 && opts.strictBrackets === true) { 11220 throw new SyntaxError(syntaxError('opening', '(')); 11221 } 11222 11223 const extglob = extglobs[extglobs.length - 1]; 11224 if (extglob && state.parens === extglob.parens + 1) { 11225 extglobClose(extglobs.pop()); 11226 continue; 11227 } 11228 11229 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); 11230 decrement('parens'); 11231 continue; 11232 } 11233 11234 /** 11235 * Square brackets 11236 */ 11237 11238 if (value === '[') { 11239 if (opts.nobracket === true || !remaining().includes(']')) { 11240 if (opts.nobracket !== true && opts.strictBrackets === true) { 11241 throw new SyntaxError(syntaxError('closing', ']')); 11242 } 11243 11244 value = `\\${value}`; 11245 } else { 11246 increment('brackets'); 11247 } 11248 11249 push({ type: 'bracket', value }); 11250 continue; 11251 } 11252 11253 if (value === ']') { 11254 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { 11255 push({ type: 'text', value, output: `\\${value}` }); 11256 continue; 11257 } 11258 11259 if (state.brackets === 0) { 11260 if (opts.strictBrackets === true) { 11261 throw new SyntaxError(syntaxError('opening', '[')); 11262 } 11263 11264 push({ type: 'text', value, output: `\\${value}` }); 11265 continue; 11266 } 11267 11268 decrement('brackets'); 11269 11270 const prevValue = prev.value.slice(1); 11271 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { 11272 value = `/${value}`; 11273 } 11274 11275 prev.value += value; 11276 append({ value }); 11277 11278 // when literal brackets are explicitly disabled 11279 // assume we should match with a regex character class 11280 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { 11281 continue; 11282 } 11283 11284 const escaped = utils.escapeRegex(prev.value); 11285 state.output = state.output.slice(0, -prev.value.length); 11286 11287 // when literal brackets are explicitly enabled 11288 // assume we should escape the brackets to match literal characters 11289 if (opts.literalBrackets === true) { 11290 state.output += escaped; 11291 prev.value = escaped; 11292 continue; 11293 } 11294 11295 // when the user specifies nothing, try to match both 11296 prev.value = `(${capture}${escaped}|${prev.value})`; 11297 state.output += prev.value; 11298 continue; 11299 } 11300 11301 /** 11302 * Braces 11303 */ 11304 11305 if (value === '{' && opts.nobrace !== true) { 11306 increment('braces'); 11307 11308 const open = { 11309 type: 'brace', 11310 value, 11311 output: '(', 11312 outputIndex: state.output.length, 11313 tokensIndex: state.tokens.length 11314 }; 11315 11316 braces.push(open); 11317 push(open); 11318 continue; 11319 } 11320 11321 if (value === '}') { 11322 const brace = braces[braces.length - 1]; 11323 11324 if (opts.nobrace === true || !brace) { 11325 push({ type: 'text', value, output: value }); 11326 continue; 11327 } 11328 11329 let output = ')'; 11330 11331 if (brace.dots === true) { 11332 const arr = tokens.slice(); 11333 const range = []; 11334 11335 for (let i = arr.length - 1; i >= 0; i--) { 11336 tokens.pop(); 11337 if (arr[i].type === 'brace') { 11338 break; 11339 } 11340 if (arr[i].type !== 'dots') { 11341 range.unshift(arr[i].value); 11342 } 11343 } 11344 11345 output = expandRange(range, opts); 11346 state.backtrack = true; 11347 } 11348 11349 if (brace.comma !== true && brace.dots !== true) { 11350 const out = state.output.slice(0, brace.outputIndex); 11351 const toks = state.tokens.slice(brace.tokensIndex); 11352 brace.value = brace.output = '\\{'; 11353 value = output = '\\}'; 11354 state.output = out; 11355 for (const t of toks) { 11356 state.output += (t.output || t.value); 11357 } 11358 } 11359 11360 push({ type: 'brace', value, output }); 11361 decrement('braces'); 11362 braces.pop(); 11363 continue; 11364 } 11365 11366 /** 11367 * Pipes 11368 */ 11369 11370 if (value === '|') { 11371 if (extglobs.length > 0) { 11372 extglobs[extglobs.length - 1].conditions++; 11373 } 11374 push({ type: 'text', value }); 11375 continue; 11376 } 11377 11378 /** 11379 * Commas 11380 */ 11381 11382 if (value === ',') { 11383 let output = value; 11384 11385 const brace = braces[braces.length - 1]; 11386 if (brace && stack[stack.length - 1] === 'braces') { 11387 brace.comma = true; 11388 output = '|'; 11389 } 11390 11391 push({ type: 'comma', value, output }); 11392 continue; 11393 } 11394 11395 /** 11396 * Slashes 11397 */ 11398 11399 if (value === '/') { 11400 // if the beginning of the glob is "./", advance the start 11401 // to the current index, and don't add the "./" characters 11402 // to the state. This greatly simplifies lookbehinds when 11403 // checking for BOS characters like "!" and "." (not "./") 11404 if (prev.type === 'dot' && state.index === state.start + 1) { 11405 state.start = state.index + 1; 11406 state.consumed = ''; 11407 state.output = ''; 11408 tokens.pop(); 11409 prev = bos; // reset "prev" to the first token 11410 continue; 11411 } 11412 11413 push({ type: 'slash', value, output: SLASH_LITERAL }); 11414 continue; 11415 } 11416 11417 /** 11418 * Dots 11419 */ 11420 11421 if (value === '.') { 11422 if (state.braces > 0 && prev.type === 'dot') { 11423 if (prev.value === '.') prev.output = DOT_LITERAL; 11424 const brace = braces[braces.length - 1]; 11425 prev.type = 'dots'; 11426 prev.output += value; 11427 prev.value += value; 11428 brace.dots = true; 11429 continue; 11430 } 11431 11432 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { 11433 push({ type: 'text', value, output: DOT_LITERAL }); 11434 continue; 11435 } 11436 11437 push({ type: 'dot', value, output: DOT_LITERAL }); 11438 continue; 11439 } 11440 11441 /** 11442 * Question marks 11443 */ 11444 11445 if (value === '?') { 11446 const isGroup = prev && prev.value === '('; 11447 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 11448 extglobOpen('qmark', value); 11449 continue; 11450 } 11451 11452 if (prev && prev.type === 'paren') { 11453 const next = peek(); 11454 let output = value; 11455 11456 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { 11457 output = `\\${value}`; 11458 } 11459 11460 push({ type: 'text', value, output }); 11461 continue; 11462 } 11463 11464 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { 11465 push({ type: 'qmark', value, output: QMARK_NO_DOT }); 11466 continue; 11467 } 11468 11469 push({ type: 'qmark', value, output: QMARK }); 11470 continue; 11471 } 11472 11473 /** 11474 * Exclamation 11475 */ 11476 11477 if (value === '!') { 11478 if (opts.noextglob !== true && peek() === '(') { 11479 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { 11480 extglobOpen('negate', value); 11481 continue; 11482 } 11483 } 11484 11485 if (opts.nonegate !== true && state.index === 0) { 11486 negate(); 11487 continue; 11488 } 11489 } 11490 11491 /** 11492 * Plus 11493 */ 11494 11495 if (value === '+') { 11496 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 11497 extglobOpen('plus', value); 11498 continue; 11499 } 11500 11501 if ((prev && prev.value === '(') || opts.regex === false) { 11502 push({ type: 'plus', value, output: PLUS_LITERAL }); 11503 continue; 11504 } 11505 11506 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { 11507 push({ type: 'plus', value }); 11508 continue; 11509 } 11510 11511 push({ type: 'plus', value: PLUS_LITERAL }); 11512 continue; 11513 } 11514 11515 /** 11516 * Plain text 11517 */ 11518 11519 if (value === '@') { 11520 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 11521 push({ type: 'at', extglob: true, value, output: '' }); 11522 continue; 11523 } 11524 11525 push({ type: 'text', value }); 11526 continue; 11527 } 11528 11529 /** 11530 * Plain text 11531 */ 11532 11533 if (value !== '*') { 11534 if (value === '$' || value === '^') { 11535 value = `\\${value}`; 11536 } 11537 11538 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); 11539 if (match) { 11540 value += match[0]; 11541 state.index += match[0].length; 11542 } 11543 11544 push({ type: 'text', value }); 11545 continue; 11546 } 11547 11548 /** 11549 * Stars 11550 */ 11551 11552 if (prev && (prev.type === 'globstar' || prev.star === true)) { 11553 prev.type = 'star'; 11554 prev.star = true; 11555 prev.value += value; 11556 prev.output = star; 11557 state.backtrack = true; 11558 state.globstar = true; 11559 consume(value); 11560 continue; 11561 } 11562 11563 let rest = remaining(); 11564 if (opts.noextglob !== true && /^\([^?]/.test(rest)) { 11565 extglobOpen('star', value); 11566 continue; 11567 } 11568 11569 if (prev.type === 'star') { 11570 if (opts.noglobstar === true) { 11571 consume(value); 11572 continue; 11573 } 11574 11575 const prior = prev.prev; 11576 const before = prior.prev; 11577 const isStart = prior.type === 'slash' || prior.type === 'bos'; 11578 const afterStar = before && (before.type === 'star' || before.type === 'globstar'); 11579 11580 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { 11581 push({ type: 'star', value, output: '' }); 11582 continue; 11583 } 11584 11585 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); 11586 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); 11587 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { 11588 push({ type: 'star', value, output: '' }); 11589 continue; 11590 } 11591 11592 // strip consecutive `/**/` 11593 while (rest.slice(0, 3) === '/**') { 11594 const after = input[state.index + 4]; 11595 if (after && after !== '/') { 11596 break; 11597 } 11598 rest = rest.slice(3); 11599 consume('/**', 3); 11600 } 11601 11602 if (prior.type === 'bos' && eos()) { 11603 prev.type = 'globstar'; 11604 prev.value += value; 11605 prev.output = globstar(opts); 11606 state.output = prev.output; 11607 state.globstar = true; 11608 consume(value); 11609 continue; 11610 } 11611 11612 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { 11613 state.output = state.output.slice(0, -(prior.output + prev.output).length); 11614 prior.output = `(?:${prior.output}`; 11615 11616 prev.type = 'globstar'; 11617 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); 11618 prev.value += value; 11619 state.globstar = true; 11620 state.output += prior.output + prev.output; 11621 consume(value); 11622 continue; 11623 } 11624 11625 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { 11626 const end = rest[1] !== void 0 ? '|$' : ''; 11627 11628 state.output = state.output.slice(0, -(prior.output + prev.output).length); 11629 prior.output = `(?:${prior.output}`; 11630 11631 prev.type = 'globstar'; 11632 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; 11633 prev.value += value; 11634 11635 state.output += prior.output + prev.output; 11636 state.globstar = true; 11637 11638 consume(value + advance()); 11639 11640 push({ type: 'slash', value: '/', output: '' }); 11641 continue; 11642 } 11643 11644 if (prior.type === 'bos' && rest[0] === '/') { 11645 prev.type = 'globstar'; 11646 prev.value += value; 11647 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; 11648 state.output = prev.output; 11649 state.globstar = true; 11650 consume(value + advance()); 11651 push({ type: 'slash', value: '/', output: '' }); 11652 continue; 11653 } 11654 11655 // remove single star from output 11656 state.output = state.output.slice(0, -prev.output.length); 11657 11658 // reset previous token to globstar 11659 prev.type = 'globstar'; 11660 prev.output = globstar(opts); 11661 prev.value += value; 11662 11663 // reset output with globstar 11664 state.output += prev.output; 11665 state.globstar = true; 11666 consume(value); 11667 continue; 11668 } 11669 11670 const token = { type: 'star', value, output: star }; 11671 11672 if (opts.bash === true) { 11673 token.output = '.*?'; 11674 if (prev.type === 'bos' || prev.type === 'slash') { 11675 token.output = nodot + token.output; 11676 } 11677 push(token); 11678 continue; 11679 } 11680 11681 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { 11682 token.output = value; 11683 push(token); 11684 continue; 11685 } 11686 11687 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { 11688 if (prev.type === 'dot') { 11689 state.output += NO_DOT_SLASH; 11690 prev.output += NO_DOT_SLASH; 11691 11692 } else if (opts.dot === true) { 11693 state.output += NO_DOTS_SLASH; 11694 prev.output += NO_DOTS_SLASH; 11695 11696 } else { 11697 state.output += nodot; 11698 prev.output += nodot; 11699 } 11700 11701 if (peek() !== '*') { 11702 state.output += ONE_CHAR; 11703 prev.output += ONE_CHAR; 11704 } 11705 } 11706 11707 push(token); 11708 } 11709 11710 while (state.brackets > 0) { 11711 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); 11712 state.output = utils.escapeLast(state.output, '['); 11713 decrement('brackets'); 11714 } 11715 11716 while (state.parens > 0) { 11717 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); 11718 state.output = utils.escapeLast(state.output, '('); 11719 decrement('parens'); 11720 } 11721 11722 while (state.braces > 0) { 11723 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); 11724 state.output = utils.escapeLast(state.output, '{'); 11725 decrement('braces'); 11726 } 11727 11728 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { 11729 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); 11730 } 11731 11732 // rebuild the output if we had to backtrack at any point 11733 if (state.backtrack === true) { 11734 state.output = ''; 11735 11736 for (const token of state.tokens) { 11737 state.output += token.output != null ? token.output : token.value; 11738 11739 if (token.suffix) { 11740 state.output += token.suffix; 11741 } 11742 } 11743 } 11744 11745 return state; 11746 }; 11747 11748 /** 11749 * Fast paths for creating regular expressions for common glob patterns. 11750 * This can significantly speed up processing and has very little downside 11751 * impact when none of the fast paths match. 11752 */ 11753 11754 parse.fastpaths = (input, options) => { 11755 const opts = { ...options }; 11756 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 11757 const len = input.length; 11758 if (len > max) { 11759 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 11760 } 11761 11762 input = REPLACEMENTS[input] || input; 11763 11764 // create constants based on platform, for windows or posix 11765 const { 11766 DOT_LITERAL, 11767 SLASH_LITERAL, 11768 ONE_CHAR, 11769 DOTS_SLASH, 11770 NO_DOT, 11771 NO_DOTS, 11772 NO_DOTS_SLASH, 11773 STAR, 11774 START_ANCHOR 11775 } = constants.globChars(opts.windows); 11776 11777 const nodot = opts.dot ? NO_DOTS : NO_DOT; 11778 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; 11779 const capture = opts.capture ? '' : '?:'; 11780 const state = { negated: false, prefix: '' }; 11781 let star = opts.bash === true ? '.*?' : STAR; 11782 11783 if (opts.capture) { 11784 star = `(${star})`; 11785 } 11786 11787 const globstar = opts => { 11788 if (opts.noglobstar === true) return star; 11789 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 11790 }; 11791 11792 const create = str => { 11793 switch (str) { 11794 case '*': 11795 return `${nodot}${ONE_CHAR}${star}`; 11796 11797 case '.*': 11798 return `${DOT_LITERAL}${ONE_CHAR}${star}`; 11799 11800 case '*.*': 11801 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 11802 11803 case '*/*': 11804 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; 11805 11806 case '**': 11807 return nodot + globstar(opts); 11808 11809 case '**/*': 11810 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; 11811 11812 case '**/*.*': 11813 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 11814 11815 case '**/.*': 11816 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; 11817 11818 default: { 11819 const match = /^(.*?)\.(\w+)$/.exec(str); 11820 if (!match) return; 11821 11822 const source = create(match[1]); 11823 if (!source) return; 11824 11825 return source + DOT_LITERAL + match[2]; 11826 } 11827 } 11828 }; 11829 11830 const output = utils.removePrefix(input, state); 11831 let source = create(output); 11832 11833 if (source && opts.strictSlashes !== true) { 11834 source += `${SLASH_LITERAL}?`; 11835 } 11836 11837 return source; 11838 }; 11839 11840 parse_1 = parse; 11841 return parse_1; 11842 } 11843 11844 var picomatch_1$1; 11845 var hasRequiredPicomatch$1; 11846 11847 function requirePicomatch$1 () { 11848 if (hasRequiredPicomatch$1) return picomatch_1$1; 11849 hasRequiredPicomatch$1 = 1; 11850 11851 const scan = /*@__PURE__*/ requireScan(); 11852 const parse = /*@__PURE__*/ requireParse(); 11853 const utils = /*@__PURE__*/ requireUtils(); 11854 const constants = /*@__PURE__*/ requireConstants(); 11855 const isObject = val => val && typeof val === 'object' && !Array.isArray(val); 11856 11857 /** 11858 * Creates a matcher function from one or more glob patterns. The 11859 * returned function takes a string to match as its first argument, 11860 * and returns true if the string is a match. The returned matcher 11861 * function also takes a boolean as the second argument that, when true, 11862 * returns an object with additional information. 11863 * 11864 * ```js 11865 * const picomatch = require('picomatch'); 11866 * // picomatch(glob[, options]); 11867 * 11868 * const isMatch = picomatch('*.!(*a)'); 11869 * console.log(isMatch('a.a')); //=> false 11870 * console.log(isMatch('a.b')); //=> true 11871 * ``` 11872 * @name picomatch 11873 * @param {String|Array} `globs` One or more glob patterns. 11874 * @param {Object=} `options` 11875 * @return {Function=} Returns a matcher function. 11876 * @api public 11877 */ 11878 11879 const picomatch = (glob, options, returnState = false) => { 11880 if (Array.isArray(glob)) { 11881 const fns = glob.map(input => picomatch(input, options, returnState)); 11882 const arrayMatcher = str => { 11883 for (const isMatch of fns) { 11884 const state = isMatch(str); 11885 if (state) return state; 11886 } 11887 return false; 11888 }; 11889 return arrayMatcher; 11890 } 11891 11892 const isState = isObject(glob) && glob.tokens && glob.input; 11893 11894 if (glob === '' || (typeof glob !== 'string' && !isState)) { 11895 throw new TypeError('Expected pattern to be a non-empty string'); 11896 } 11897 11898 const opts = options || {}; 11899 const posix = opts.windows; 11900 const regex = isState 11901 ? picomatch.compileRe(glob, options) 11902 : picomatch.makeRe(glob, options, false, true); 11903 11904 const state = regex.state; 11905 delete regex.state; 11906 11907 let isIgnored = () => false; 11908 if (opts.ignore) { 11909 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; 11910 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); 11911 } 11912 11913 const matcher = (input, returnObject = false) => { 11914 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); 11915 const result = { glob, state, regex, posix, input, output, match, isMatch }; 11916 11917 if (typeof opts.onResult === 'function') { 11918 opts.onResult(result); 11919 } 11920 11921 if (isMatch === false) { 11922 result.isMatch = false; 11923 return returnObject ? result : false; 11924 } 11925 11926 if (isIgnored(input)) { 11927 if (typeof opts.onIgnore === 'function') { 11928 opts.onIgnore(result); 11929 } 11930 result.isMatch = false; 11931 return returnObject ? result : false; 11932 } 11933 11934 if (typeof opts.onMatch === 'function') { 11935 opts.onMatch(result); 11936 } 11937 return returnObject ? result : true; 11938 }; 11939 11940 if (returnState) { 11941 matcher.state = state; 11942 } 11943 11944 return matcher; 11945 }; 11946 11947 /** 11948 * Test `input` with the given `regex`. This is used by the main 11949 * `picomatch()` function to test the input string. 11950 * 11951 * ```js 11952 * const picomatch = require('picomatch'); 11953 * // picomatch.test(input, regex[, options]); 11954 * 11955 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); 11956 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } 11957 * ``` 11958 * @param {String} `input` String to test. 11959 * @param {RegExp} `regex` 11960 * @return {Object} Returns an object with matching info. 11961 * @api public 11962 */ 11963 11964 picomatch.test = (input, regex, options, { glob, posix } = {}) => { 11965 if (typeof input !== 'string') { 11966 throw new TypeError('Expected input to be a string'); 11967 } 11968 11969 if (input === '') { 11970 return { isMatch: false, output: '' }; 11971 } 11972 11973 const opts = options || {}; 11974 const format = opts.format || (posix ? utils.toPosixSlashes : null); 11975 let match = input === glob; 11976 let output = (match && format) ? format(input) : input; 11977 11978 if (match === false) { 11979 output = format ? format(input) : input; 11980 match = output === glob; 11981 } 11982 11983 if (match === false || opts.capture === true) { 11984 if (opts.matchBase === true || opts.basename === true) { 11985 match = picomatch.matchBase(input, regex, options, posix); 11986 } else { 11987 match = regex.exec(output); 11988 } 11989 } 11990 11991 return { isMatch: Boolean(match), match, output }; 11992 }; 11993 11994 /** 11995 * Match the basename of a filepath. 11996 * 11997 * ```js 11998 * const picomatch = require('picomatch'); 11999 * // picomatch.matchBase(input, glob[, options]); 12000 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true 12001 * ``` 12002 * @param {String} `input` String to test. 12003 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). 12004 * @return {Boolean} 12005 * @api public 12006 */ 12007 12008 picomatch.matchBase = (input, glob, options) => { 12009 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); 12010 return regex.test(utils.basename(input)); 12011 }; 12012 12013 /** 12014 * Returns true if **any** of the given glob `patterns` match the specified `string`. 12015 * 12016 * ```js 12017 * const picomatch = require('picomatch'); 12018 * // picomatch.isMatch(string, patterns[, options]); 12019 * 12020 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true 12021 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false 12022 * ``` 12023 * @param {String|Array} str The string to test. 12024 * @param {String|Array} patterns One or more glob patterns to use for matching. 12025 * @param {Object} [options] See available [options](#options). 12026 * @return {Boolean} Returns true if any patterns match `str` 12027 * @api public 12028 */ 12029 12030 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); 12031 12032 /** 12033 * Parse a glob pattern to create the source string for a regular 12034 * expression. 12035 * 12036 * ```js 12037 * const picomatch = require('picomatch'); 12038 * const result = picomatch.parse(pattern[, options]); 12039 * ``` 12040 * @param {String} `pattern` 12041 * @param {Object} `options` 12042 * @return {Object} Returns an object with useful properties and output to be used as a regex source string. 12043 * @api public 12044 */ 12045 12046 picomatch.parse = (pattern, options) => { 12047 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); 12048 return parse(pattern, { ...options, fastpaths: false }); 12049 }; 12050 12051 /** 12052 * Scan a glob pattern to separate the pattern into segments. 12053 * 12054 * ```js 12055 * const picomatch = require('picomatch'); 12056 * // picomatch.scan(input[, options]); 12057 * 12058 * const result = picomatch.scan('!./foo/*.js'); 12059 * console.log(result); 12060 * { prefix: '!./', 12061 * input: '!./foo/*.js', 12062 * start: 3, 12063 * base: 'foo', 12064 * glob: '*.js', 12065 * isBrace: false, 12066 * isBracket: false, 12067 * isGlob: true, 12068 * isExtglob: false, 12069 * isGlobstar: false, 12070 * negated: true } 12071 * ``` 12072 * @param {String} `input` Glob pattern to scan. 12073 * @param {Object} `options` 12074 * @return {Object} Returns an object with 12075 * @api public 12076 */ 12077 12078 picomatch.scan = (input, options) => scan(input, options); 12079 12080 /** 12081 * Compile a regular expression from the `state` object returned by the 12082 * [parse()](#parse) method. 12083 * 12084 * @param {Object} `state` 12085 * @param {Object} `options` 12086 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. 12087 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. 12088 * @return {RegExp} 12089 * @api public 12090 */ 12091 12092 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { 12093 if (returnOutput === true) { 12094 return state.output; 12095 } 12096 12097 const opts = options || {}; 12098 const prepend = opts.contains ? '' : '^'; 12099 const append = opts.contains ? '' : '$'; 12100 12101 let source = `${prepend}(?:${state.output})${append}`; 12102 if (state && state.negated === true) { 12103 source = `^(?!${source}).*$`; 12104 } 12105 12106 const regex = picomatch.toRegex(source, options); 12107 if (returnState === true) { 12108 regex.state = state; 12109 } 12110 12111 return regex; 12112 }; 12113 12114 /** 12115 * Create a regular expression from a parsed glob pattern. 12116 * 12117 * ```js 12118 * const picomatch = require('picomatch'); 12119 * const state = picomatch.parse('*.js'); 12120 * // picomatch.compileRe(state[, options]); 12121 * 12122 * console.log(picomatch.compileRe(state)); 12123 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 12124 * ``` 12125 * @param {String} `state` The object returned from the `.parse` method. 12126 * @param {Object} `options` 12127 * @param {Boolean} `returnOutput` Implementors may use this argument to return the compiled output, instead of a regular expression. This is not exposed on the options to prevent end-users from mutating the result. 12128 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. 12129 * @return {RegExp} Returns a regex created from the given pattern. 12130 * @api public 12131 */ 12132 12133 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { 12134 if (!input || typeof input !== 'string') { 12135 throw new TypeError('Expected a non-empty string'); 12136 } 12137 12138 let parsed = { negated: false, fastpaths: true }; 12139 12140 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { 12141 parsed.output = parse.fastpaths(input, options); 12142 } 12143 12144 if (!parsed.output) { 12145 parsed = parse(input, options); 12146 } 12147 12148 return picomatch.compileRe(parsed, options, returnOutput, returnState); 12149 }; 12150 12151 /** 12152 * Create a regular expression from the given regex source string. 12153 * 12154 * ```js 12155 * const picomatch = require('picomatch'); 12156 * // picomatch.toRegex(source[, options]); 12157 * 12158 * const { output } = picomatch.parse('*.js'); 12159 * console.log(picomatch.toRegex(output)); 12160 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 12161 * ``` 12162 * @param {String} `source` Regular expression source string. 12163 * @param {Object} `options` 12164 * @return {RegExp} 12165 * @api public 12166 */ 12167 12168 picomatch.toRegex = (source, options) => { 12169 try { 12170 const opts = options || {}; 12171 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); 12172 } catch (err) { 12173 if (options && options.debug === true) throw err; 12174 return /$^/; 12175 } 12176 }; 12177 12178 /** 12179 * Picomatch constants. 12180 * @return {Object} 12181 */ 12182 12183 picomatch.constants = constants; 12184 12185 /** 12186 * Expose "picomatch" 12187 */ 12188 12189 picomatch_1$1 = picomatch; 12190 return picomatch_1$1; 12191 } 12192 12193 var picomatch_1; 12194 var hasRequiredPicomatch; 12195 12196 function requirePicomatch () { 12197 if (hasRequiredPicomatch) return picomatch_1; 12198 hasRequiredPicomatch = 1; 12199 12200 const pico = /*@__PURE__*/ requirePicomatch$1(); 12201 const utils = /*@__PURE__*/ requireUtils(); 12202 12203 function picomatch(glob, options, returnState = false) { 12204 // default to os.platform() 12205 if (options && (options.windows === null || options.windows === undefined)) { 12206 // don't mutate the original options object 12207 options = { ...options, windows: utils.isWindows() }; 12208 } 12209 12210 return pico(glob, options, returnState); 12211 } 12212 12213 Object.assign(picomatch, pico); 12214 picomatch_1 = picomatch; 12215 return picomatch_1; 12216 } 12217 12218 var picomatchExports = /*@__PURE__*/ requirePicomatch(); 12219 const pm = /*@__PURE__*/getDefaultExportFromCjs(picomatchExports); 12220 12221 const extractors = { 12222 ArrayPattern(names, param) { 12223 for (const element of param.elements) { 12224 if (element) 12225 extractors[element.type](names, element); 12226 } 12227 }, 12228 AssignmentPattern(names, param) { 12229 extractors[param.left.type](names, param.left); 12230 }, 12231 Identifier(names, param) { 12232 names.push(param.name); 12233 }, 12234 MemberExpression() { }, 12235 ObjectPattern(names, param) { 12236 for (const prop of param.properties) { 12237 // @ts-ignore Typescript reports that this is not a valid type 12238 if (prop.type === 'RestElement') { 12239 extractors.RestElement(names, prop); 12240 } 12241 else { 12242 extractors[prop.value.type](names, prop.value); 12243 } 12244 } 12245 }, 12246 RestElement(names, param) { 12247 extractors[param.argument.type](names, param.argument); 12248 } 12249 }; 12250 const extractAssignedNames = function extractAssignedNames(param) { 12251 const names = []; 12252 extractors[param.type](names, param); 12253 return names; 12254 }; 12255 12256 // Helper since Typescript can't detect readonly arrays with Array.isArray 12257 function isArray(arg) { 12258 return Array.isArray(arg); 12259 } 12260 function ensureArray(thing) { 12261 if (isArray(thing)) 12262 return thing; 12263 if (thing == null) 12264 return []; 12265 return [thing]; 12266 } 12267 12268 const normalizePathRegExp = new RegExp(`\\${require$$0.win32.sep}`, 'g'); 12269 const normalizePath = function normalizePath(filename) { 12270 return filename.replace(normalizePathRegExp, require$$0.posix.sep); 12271 }; 12272 12273 function getMatcherString(id, resolutionBase) { 12274 if (resolutionBase === false || require$$0.isAbsolute(id) || id.startsWith('**')) { 12275 return normalizePath(id); 12276 } 12277 // resolve('') is valid and will default to process.cwd() 12278 const basePath = normalizePath(require$$0.resolve(resolutionBase || '')) 12279 // escape all possible (posix + win) path characters that might interfere with regex 12280 .replace(/[-^$*+?.()|[\]{}]/g, '\\$&'); 12281 // Note that we use posix.join because: 12282 // 1. the basePath has been normalized to use / 12283 // 2. the incoming glob (id) matcher, also uses / 12284 // otherwise Node will force backslash (\) on windows 12285 return require$$0.posix.join(basePath, normalizePath(id)); 12286 } 12287 const createFilter = function createFilter(include, exclude, options) { 12288 const resolutionBase = options && options.resolve; 12289 const getMatcher = (id) => id instanceof RegExp 12290 ? id 12291 : { 12292 test: (what) => { 12293 // this refactor is a tad overly verbose but makes for easy debugging 12294 const pattern = getMatcherString(id, resolutionBase); 12295 const fn = pm(pattern, { dot: true }); 12296 const result = fn(what); 12297 return result; 12298 } 12299 }; 12300 const includeMatchers = ensureArray(include).map(getMatcher); 12301 const excludeMatchers = ensureArray(exclude).map(getMatcher); 12302 if (!includeMatchers.length && !excludeMatchers.length) 12303 return (id) => typeof id === 'string' && !id.includes('\0'); 12304 return function result(id) { 12305 if (typeof id !== 'string') 12306 return false; 12307 if (id.includes('\0')) 12308 return false; 12309 const pathId = normalizePath(id); 12310 for (let i = 0; i < excludeMatchers.length; ++i) { 12311 const matcher = excludeMatchers[i]; 12312 if (matcher.test(pathId)) 12313 return false; 12314 } 12315 for (let i = 0; i < includeMatchers.length; ++i) { 12316 const matcher = includeMatchers[i]; 12317 if (matcher.test(pathId)) 12318 return true; 12319 } 12320 return !includeMatchers.length; 12321 }; 12322 }; 12323 12324 const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public'; 12325 const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl'; 12326 const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' ')); 12327 forbiddenIdentifiers.add(''); 12328 12329 class ArrayPattern extends NodeBase { 12330 addExportedVariables(variables, exportNamesByVariable) { 12331 for (const element of this.elements) { 12332 element?.addExportedVariables(variables, exportNamesByVariable); 12333 } 12334 } 12335 declare(kind) { 12336 const variables = []; 12337 for (const element of this.elements) { 12338 if (element !== null) { 12339 variables.push(...element.declare(kind, UNKNOWN_EXPRESSION)); 12340 } 12341 } 12342 return variables; 12343 } 12344 // Patterns can only be deoptimized at the empty path at the moment 12345 deoptimizePath() { 12346 for (const element of this.elements) { 12347 element?.deoptimizePath(EMPTY_PATH); 12348 } 12349 } 12350 // Patterns are only checked at the empty path at the moment 12351 hasEffectsOnInteractionAtPath(_path, interaction, context) { 12352 for (const element of this.elements) { 12353 if (element?.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)) 12354 return true; 12355 } 12356 return false; 12357 } 12358 markDeclarationReached() { 12359 for (const element of this.elements) { 12360 element?.markDeclarationReached(); 12361 } 12362 } 12363 } 12364 12365 class ArrowFunctionExpression extends FunctionBase { 12366 constructor() { 12367 super(...arguments); 12368 this.objectEntity = null; 12369 } 12370 get expression() { 12371 return isFlagSet(this.flags, 8388608 /* Flag.expression */); 12372 } 12373 set expression(value) { 12374 this.flags = setFlag(this.flags, 8388608 /* Flag.expression */, value); 12375 } 12376 createScope(parentScope) { 12377 this.scope = new ReturnValueScope(parentScope, false); 12378 } 12379 hasEffects() { 12380 if (!this.deoptimized) 12381 this.applyDeoptimizations(); 12382 return false; 12383 } 12384 hasEffectsOnInteractionAtPath(path, interaction, context) { 12385 if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) { 12386 return true; 12387 } 12388 if (this.annotationNoSideEffects) { 12389 return false; 12390 } 12391 if (interaction.type === INTERACTION_CALLED) { 12392 const { ignore, brokenFlow } = context; 12393 context.ignore = { 12394 breaks: false, 12395 continues: false, 12396 labels: new Set(), 12397 returnYield: true, 12398 this: false 12399 }; 12400 if (this.body.hasEffects(context)) 12401 return true; 12402 context.ignore = ignore; 12403 context.brokenFlow = brokenFlow; 12404 } 12405 return false; 12406 } 12407 onlyFunctionCallUsed() { 12408 const isIIFE = this.parent.type === parseAst_js.CallExpression && 12409 this.parent.callee === this; 12410 return isIIFE || super.onlyFunctionCallUsed(); 12411 } 12412 include(context, includeChildrenRecursively) { 12413 super.include(context, includeChildrenRecursively); 12414 for (const parameter of this.params) { 12415 if (!(parameter instanceof Identifier)) { 12416 parameter.include(context, includeChildrenRecursively); 12417 } 12418 } 12419 } 12420 getObjectEntity() { 12421 if (this.objectEntity !== null) { 12422 return this.objectEntity; 12423 } 12424 return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE)); 12425 } 12426 } 12427 12428 class ObjectPattern extends NodeBase { 12429 addExportedVariables(variables, exportNamesByVariable) { 12430 for (const property of this.properties) { 12431 if (property.type === parseAst_js.Property) { 12432 property.value.addExportedVariables(variables, exportNamesByVariable); 12433 } 12434 else { 12435 property.argument.addExportedVariables(variables, exportNamesByVariable); 12436 } 12437 } 12438 } 12439 declare(kind, init) { 12440 const variables = []; 12441 for (const property of this.properties) { 12442 variables.push(...property.declare(kind, init)); 12443 } 12444 return variables; 12445 } 12446 deoptimizePath(path) { 12447 if (path.length === 0) { 12448 for (const property of this.properties) { 12449 property.deoptimizePath(path); 12450 } 12451 } 12452 } 12453 hasEffectsOnInteractionAtPath( 12454 // At the moment, this is only triggered for assignment left-hand sides, 12455 // where the path is empty 12456 _path, interaction, context) { 12457 for (const property of this.properties) { 12458 if (property.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)) 12459 return true; 12460 } 12461 return false; 12462 } 12463 markDeclarationReached() { 12464 for (const property of this.properties) { 12465 property.markDeclarationReached(); 12466 } 12467 } 12468 } 12469 12470 class AssignmentExpression extends NodeBase { 12471 hasEffects(context) { 12472 const { deoptimized, left, operator, right } = this; 12473 if (!deoptimized) 12474 this.applyDeoptimizations(); 12475 // MemberExpressions do not access the property before assignments if the 12476 // operator is '='. 12477 return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '=')); 12478 } 12479 hasEffectsOnInteractionAtPath(path, interaction, context) { 12480 return this.right.hasEffectsOnInteractionAtPath(path, interaction, context); 12481 } 12482 include(context, includeChildrenRecursively) { 12483 const { deoptimized, left, right, operator } = this; 12484 if (!deoptimized) 12485 this.applyDeoptimizations(); 12486 this.included = true; 12487 if (includeChildrenRecursively || 12488 operator !== '=' || 12489 left.included || 12490 left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) { 12491 left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '='); 12492 } 12493 right.include(context, includeChildrenRecursively); 12494 } 12495 initialise() { 12496 super.initialise(); 12497 if (this.left instanceof Identifier) { 12498 const variable = this.scope.variables.get(this.left.name); 12499 if (variable?.kind === 'const') { 12500 this.scope.context.error(parseAst_js.logConstVariableReassignError(), this.left.start); 12501 } 12502 } 12503 this.left.setAssignedValue(this.right); 12504 } 12505 render(code, options, { preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) { 12506 const { left, right, start, end, parent } = this; 12507 if (left.included) { 12508 left.render(code, options); 12509 right.render(code, options); 12510 } 12511 else { 12512 const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', left.end) + 1); 12513 code.remove(start, inclusionStart); 12514 if (preventASI) { 12515 removeLineBreaks(code, inclusionStart, right.start); 12516 } 12517 right.render(code, options, { 12518 renderedParentType: renderedParentType || parent.type, 12519 renderedSurroundingElement: renderedSurroundingElement || parent.type 12520 }); 12521 } 12522 if (options.format === 'system') { 12523 if (left instanceof Identifier) { 12524 const variable = left.variable; 12525 const exportNames = options.exportNamesByVariable.get(variable); 12526 if (exportNames) { 12527 if (exportNames.length === 1) { 12528 renderSystemExportExpression(variable, start, end, code, options); 12529 } 12530 else { 12531 renderSystemExportSequenceAfterExpression(variable, start, end, parent.type !== parseAst_js.ExpressionStatement, code, options); 12532 } 12533 return; 12534 } 12535 } 12536 else { 12537 const systemPatternExports = []; 12538 left.addExportedVariables(systemPatternExports, options.exportNamesByVariable); 12539 if (systemPatternExports.length > 0) { 12540 renderSystemExportFunction(systemPatternExports, start, end, renderedSurroundingElement === parseAst_js.ExpressionStatement, code, options); 12541 return; 12542 } 12543 } 12544 } 12545 if (left.included && 12546 left instanceof ObjectPattern && 12547 (renderedSurroundingElement === parseAst_js.ExpressionStatement || 12548 renderedSurroundingElement === parseAst_js.ArrowFunctionExpression)) { 12549 code.appendRight(start, '('); 12550 code.prependLeft(end, ')'); 12551 } 12552 } 12553 applyDeoptimizations() { 12554 this.deoptimized = true; 12555 this.left.deoptimizePath(EMPTY_PATH); 12556 this.right.deoptimizePath(UNKNOWN_PATH); 12557 this.scope.context.requestTreeshakingPass(); 12558 } 12559 } 12560 12561 class AssignmentPattern extends NodeBase { 12562 addExportedVariables(variables, exportNamesByVariable) { 12563 this.left.addExportedVariables(variables, exportNamesByVariable); 12564 } 12565 declare(kind, init) { 12566 return this.left.declare(kind, init); 12567 } 12568 deoptimizePath(path) { 12569 if (path.length === 0) { 12570 this.left.deoptimizePath(path); 12571 } 12572 } 12573 hasEffectsOnInteractionAtPath(path, interaction, context) { 12574 return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)); 12575 } 12576 markDeclarationReached() { 12577 this.left.markDeclarationReached(); 12578 } 12579 render(code, options, { isShorthandProperty } = parseAst_js.BLANK) { 12580 this.left.render(code, options, { isShorthandProperty }); 12581 this.right.render(code, options); 12582 } 12583 applyDeoptimizations() { 12584 this.deoptimized = true; 12585 this.left.deoptimizePath(EMPTY_PATH); 12586 this.right.deoptimizePath(UNKNOWN_PATH); 12587 this.scope.context.requestTreeshakingPass(); 12588 } 12589 } 12590 12591 class AwaitExpression extends NodeBase { 12592 hasEffects() { 12593 if (!this.deoptimized) 12594 this.applyDeoptimizations(); 12595 return true; 12596 } 12597 include(context, includeChildrenRecursively) { 12598 if (!this.deoptimized) 12599 this.applyDeoptimizations(); 12600 if (!this.included) { 12601 this.included = true; 12602 checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) { 12603 let parent = this.parent; 12604 do { 12605 if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression) 12606 break checkTopLevelAwait; 12607 } while ((parent = parent.parent)); 12608 this.scope.context.usesTopLevelAwait = true; 12609 } 12610 } 12611 this.argument.include(context, includeChildrenRecursively); 12612 } 12613 } 12614 12615 const binaryOperators = { 12616 '!=': (left, right) => left != right, 12617 '!==': (left, right) => left !== right, 12618 '%': (left, right) => left % right, 12619 '&': (left, right) => left & right, 12620 '*': (left, right) => left * right, 12621 // At the moment, "**" will be transpiled to Math.pow 12622 '**': (left, right) => left ** right, 12623 '+': (left, right) => left + right, 12624 '-': (left, right) => left - right, 12625 '/': (left, right) => left / right, 12626 '<': (left, right) => left < right, 12627 '<<': (left, right) => left << right, 12628 '<=': (left, right) => left <= right, 12629 '==': (left, right) => left == right, 12630 '===': (left, right) => left === right, 12631 '>': (left, right) => left > right, 12632 '>=': (left, right) => left >= right, 12633 '>>': (left, right) => left >> right, 12634 '>>>': (left, right) => left >>> right, 12635 '^': (left, right) => left ^ right, 12636 '|': (left, right) => left | right 12637 // We use the fallback for cases where we return something unknown 12638 // in: () => UnknownValue, 12639 // instanceof: () => UnknownValue, 12640 }; 12641 class BinaryExpression extends NodeBase { 12642 deoptimizeCache() { } 12643 getLiteralValueAtPath(path, recursionTracker, origin) { 12644 if (path.length > 0) 12645 return UnknownValue; 12646 const leftValue = this.left.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin); 12647 if (typeof leftValue === 'symbol') 12648 return UnknownValue; 12649 const rightValue = this.right.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin); 12650 if (typeof rightValue === 'symbol') 12651 return UnknownValue; 12652 const operatorFunction = binaryOperators[this.operator]; 12653 if (!operatorFunction) 12654 return UnknownValue; 12655 return operatorFunction(leftValue, rightValue); 12656 } 12657 hasEffects(context) { 12658 // support some implicit type coercion runtime errors 12659 if (this.operator === '+' && 12660 this.parent instanceof ExpressionStatement && 12661 this.left.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) === '') { 12662 return true; 12663 } 12664 return super.hasEffects(context); 12665 } 12666 hasEffectsOnInteractionAtPath(path, { type }) { 12667 return type !== INTERACTION_ACCESSED || path.length > 1; 12668 } 12669 removeAnnotations(code) { 12670 this.left.removeAnnotations(code); 12671 } 12672 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 12673 this.left.render(code, options, { renderedSurroundingElement }); 12674 this.right.render(code, options); 12675 } 12676 } 12677 12678 class BreakStatement extends NodeBase { 12679 hasEffects(context) { 12680 if (this.label) { 12681 if (!context.ignore.labels.has(this.label.name)) 12682 return true; 12683 context.includedLabels.add(this.label.name); 12684 } 12685 else { 12686 if (!context.ignore.breaks) 12687 return true; 12688 context.hasBreak = true; 12689 } 12690 context.brokenFlow = true; 12691 return false; 12692 } 12693 include(context) { 12694 this.included = true; 12695 if (this.label) { 12696 this.label.include(); 12697 context.includedLabels.add(this.label.name); 12698 } 12699 else { 12700 context.hasBreak = true; 12701 } 12702 context.brokenFlow = true; 12703 } 12704 } 12705 12706 function renderCallArguments(code, options, node) { 12707 if (node.arguments.length > 0) { 12708 if (node.arguments[node.arguments.length - 1].included) { 12709 for (const argument of node.arguments) { 12710 argument.render(code, options); 12711 } 12712 } 12713 else { 12714 let lastIncludedIndex = node.arguments.length - 2; 12715 while (lastIncludedIndex >= 0 && !node.arguments[lastIncludedIndex].included) { 12716 lastIncludedIndex--; 12717 } 12718 if (lastIncludedIndex >= 0) { 12719 for (let index = 0; index <= lastIncludedIndex; index++) { 12720 node.arguments[index].render(code, options); 12721 } 12722 code.remove(findFirstOccurrenceOutsideComment(code.original, ',', node.arguments[lastIncludedIndex].end), node.end - 1); 12723 } 12724 else { 12725 code.remove(findFirstOccurrenceOutsideComment(code.original, '(', node.callee.end) + 1, node.end - 1); 12726 } 12727 } 12728 } 12729 } 12730 12731 class CallExpressionBase extends NodeBase { 12732 constructor() { 12733 super(...arguments); 12734 this.returnExpression = null; 12735 this.deoptimizableDependentExpressions = []; 12736 this.expressionsToBeDeoptimized = new Set(); 12737 } 12738 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 12739 const { args } = interaction; 12740 const [returnExpression, isPure] = this.getReturnExpression(recursionTracker); 12741 if (isPure) 12742 return; 12743 const deoptimizedExpressions = args.filter(expression => !!expression && expression !== UNKNOWN_EXPRESSION); 12744 if (deoptimizedExpressions.length === 0) 12745 return; 12746 if (returnExpression === UNKNOWN_EXPRESSION) { 12747 for (const expression of deoptimizedExpressions) { 12748 expression.deoptimizePath(UNKNOWN_PATH); 12749 } 12750 } 12751 else { 12752 recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 12753 for (const expression of deoptimizedExpressions) { 12754 this.expressionsToBeDeoptimized.add(expression); 12755 } 12756 returnExpression.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 12757 }, null); 12758 } 12759 } 12760 deoptimizeCache() { 12761 if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) { 12762 this.returnExpression = UNKNOWN_RETURN_EXPRESSION; 12763 const { deoptimizableDependentExpressions, expressionsToBeDeoptimized } = this; 12764 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_SET; 12765 this.deoptimizableDependentExpressions = parseAst_js.EMPTY_ARRAY; 12766 for (const expression of deoptimizableDependentExpressions) { 12767 expression.deoptimizeCache(); 12768 } 12769 for (const expression of expressionsToBeDeoptimized) { 12770 expression.deoptimizePath(UNKNOWN_PATH); 12771 } 12772 } 12773 } 12774 deoptimizePath(path) { 12775 if (path.length === 0 || 12776 this.scope.context.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) { 12777 return; 12778 } 12779 const [returnExpression] = this.getReturnExpression(); 12780 if (returnExpression !== UNKNOWN_EXPRESSION) { 12781 returnExpression.deoptimizePath(path); 12782 } 12783 } 12784 getLiteralValueAtPath(path, recursionTracker, origin) { 12785 const [returnExpression] = this.getReturnExpression(recursionTracker); 12786 if (returnExpression === UNKNOWN_EXPRESSION) { 12787 return UnknownValue; 12788 } 12789 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 12790 this.deoptimizableDependentExpressions.push(origin); 12791 return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin); 12792 }, UnknownValue); 12793 } 12794 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 12795 const returnExpression = this.getReturnExpression(recursionTracker); 12796 if (returnExpression[0] === UNKNOWN_EXPRESSION) { 12797 return returnExpression; 12798 } 12799 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 12800 this.deoptimizableDependentExpressions.push(origin); 12801 const [expression, isPure] = returnExpression[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 12802 return [expression, isPure || returnExpression[1]]; 12803 }, UNKNOWN_RETURN_EXPRESSION); 12804 } 12805 hasEffectsOnInteractionAtPath(path, interaction, context) { 12806 const { type } = interaction; 12807 if (type === INTERACTION_CALLED) { 12808 const { args, withNew } = interaction; 12809 if ((withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, args, this)) { 12810 return false; 12811 } 12812 } 12813 else if ((type === INTERACTION_ASSIGNED 12814 ? context.assigned 12815 : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) { 12816 return false; 12817 } 12818 const [returnExpression, isPure] = this.getReturnExpression(); 12819 return ((type === INTERACTION_ASSIGNED || !isPure) && 12820 returnExpression.hasEffectsOnInteractionAtPath(path, interaction, context)); 12821 } 12822 } 12823 12824 class CallExpression extends CallExpressionBase { 12825 get optional() { 12826 return isFlagSet(this.flags, 128 /* Flag.optional */); 12827 } 12828 set optional(value) { 12829 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value); 12830 } 12831 bind() { 12832 super.bind(); 12833 if (this.callee instanceof Identifier) { 12834 const variable = this.scope.findVariable(this.callee.name); 12835 if (variable.isNamespace) { 12836 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logCannotCallNamespace(this.callee.name), this.start); 12837 } 12838 if (this.callee.name === 'eval') { 12839 this.scope.context.log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logEval(this.scope.context.module.id), this.start); 12840 } 12841 } 12842 this.interaction = { 12843 args: [ 12844 this.callee instanceof MemberExpression && !this.callee.variable 12845 ? this.callee.object 12846 : null, 12847 ...this.arguments 12848 ], 12849 type: INTERACTION_CALLED, 12850 withNew: false 12851 }; 12852 } 12853 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) { 12854 return getChainElementLiteralValueAtPath(this, this.callee, path, recursionTracker, origin); 12855 } 12856 hasEffects(context) { 12857 if (!this.deoptimized) 12858 this.applyDeoptimizations(); 12859 for (const argument of this.arguments) { 12860 if (argument.hasEffects(context)) 12861 return true; 12862 } 12863 if (this.annotationPure) { 12864 return false; 12865 } 12866 return (this.callee.hasEffects(context) || 12867 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)); 12868 } 12869 hasEffectsAsChainElement(context) { 12870 const calleeHasEffects = 'hasEffectsAsChainElement' in this.callee 12871 ? this.callee.hasEffectsAsChainElement(context) 12872 : this.callee.hasEffects(context); 12873 if (calleeHasEffects === IS_SKIPPED_CHAIN) 12874 return IS_SKIPPED_CHAIN; 12875 if (this.optional && 12876 this.callee.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) { 12877 return (!this.annotationPure && calleeHasEffects) || IS_SKIPPED_CHAIN; 12878 } 12879 // We only apply deoptimizations lazily once we know we are not skipping 12880 if (!this.deoptimized) 12881 this.applyDeoptimizations(); 12882 for (const argument of this.arguments) { 12883 if (argument.hasEffects(context)) 12884 return true; 12885 } 12886 return (!this.annotationPure && 12887 (calleeHasEffects || 12888 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context))); 12889 } 12890 include(context, includeChildrenRecursively) { 12891 if (!this.deoptimized) 12892 this.applyDeoptimizations(); 12893 if (includeChildrenRecursively) { 12894 super.include(context, includeChildrenRecursively); 12895 if (includeChildrenRecursively === INCLUDE_PARAMETERS && 12896 this.callee instanceof Identifier && 12897 this.callee.variable) { 12898 this.callee.variable.markCalledFromTryStatement(); 12899 } 12900 } 12901 else { 12902 this.included = true; 12903 this.callee.include(context, false); 12904 } 12905 this.callee.includeCallArguments(context, this.arguments); 12906 } 12907 initialise() { 12908 super.initialise(); 12909 if (this.annotations && 12910 this.scope.context.options.treeshake.annotations) { 12911 this.annotationPure = this.annotations.some(comment => comment.type === 'pure'); 12912 } 12913 } 12914 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 12915 this.callee.render(code, options, { 12916 isCalleeOfRenderedParent: true, 12917 renderedSurroundingElement 12918 }); 12919 renderCallArguments(code, options, this); 12920 } 12921 applyDeoptimizations() { 12922 this.deoptimized = true; 12923 this.callee.deoptimizeArgumentsOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER); 12924 this.scope.context.requestTreeshakingPass(); 12925 } 12926 getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) { 12927 if (this.returnExpression === null) { 12928 this.returnExpression = UNKNOWN_RETURN_EXPRESSION; 12929 return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this)); 12930 } 12931 return this.returnExpression; 12932 } 12933 } 12934 12935 class CatchClause extends NodeBase { 12936 createScope(parentScope) { 12937 this.scope = new ParameterScope(parentScope, true); 12938 } 12939 parseNode(esTreeNode) { 12940 const { body, param, type } = esTreeNode; 12941 this.type = type; 12942 if (param) { 12943 this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param); 12944 this.param.declare('parameter', UNKNOWN_EXPRESSION); 12945 } 12946 this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body); 12947 return super.parseNode(esTreeNode); 12948 } 12949 } 12950 CatchClause.prototype.preventChildBlockScope = true; 12951 12952 class ChainExpression extends NodeBase { 12953 // deoptimizations are not relevant as we are not caching values 12954 deoptimizeCache() { } 12955 getLiteralValueAtPath(path, recursionTracker, origin) { 12956 const literalValue = this.expression.getLiteralValueAtPathAsChainElement(path, recursionTracker, origin); 12957 return literalValue === IS_SKIPPED_CHAIN ? undefined : literalValue; 12958 } 12959 hasEffects(context) { 12960 return this.expression.hasEffectsAsChainElement(context) === true; 12961 } 12962 removeAnnotations(code) { 12963 this.expression.removeAnnotations(code); 12964 } 12965 applyDeoptimizations() { } 12966 } 12967 12968 class ClassBodyScope extends ChildScope { 12969 constructor(parent, classNode) { 12970 const { context } = parent; 12971 super(parent, context); 12972 this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other'))); 12973 this.instanceScope = new ChildScope(this, context); 12974 this.instanceScope.variables.set('this', new ThisVariable(context)); 12975 } 12976 findLexicalBoundary() { 12977 return this; 12978 } 12979 } 12980 12981 class ClassBody extends NodeBase { 12982 createScope(parentScope) { 12983 this.scope = new ClassBodyScope(parentScope, this.parent); 12984 } 12985 include(context, includeChildrenRecursively) { 12986 this.included = true; 12987 this.scope.context.includeVariableInModule(this.scope.thisVariable); 12988 for (const definition of this.body) { 12989 definition.include(context, includeChildrenRecursively); 12990 } 12991 } 12992 parseNode(esTreeNode) { 12993 const body = (this.body = new Array(esTreeNode.body.length)); 12994 let index = 0; 12995 for (const definition of esTreeNode.body) { 12996 body[index++] = new (this.scope.context.getNodeConstructor(definition.type))(this, definition.static ? this.scope : this.scope.instanceScope).parseNode(definition); 12997 } 12998 return super.parseNode(esTreeNode); 12999 } 13000 applyDeoptimizations() { } 13001 } 13002 13003 class ClassExpression extends ClassNode { 13004 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 13005 super.render(code, options); 13006 if (renderedSurroundingElement === parseAst_js.ExpressionStatement) { 13007 code.appendRight(this.start, '('); 13008 code.prependLeft(this.end, ')'); 13009 } 13010 } 13011 } 13012 13013 class MultiExpression extends ExpressionEntity { 13014 constructor(expressions) { 13015 super(); 13016 this.expressions = expressions; 13017 } 13018 deoptimizePath(path) { 13019 for (const expression of this.expressions) { 13020 expression.deoptimizePath(path); 13021 } 13022 } 13023 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 13024 return [ 13025 new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])), 13026 false 13027 ]; 13028 } 13029 hasEffectsOnInteractionAtPath(path, interaction, context) { 13030 for (const expression of this.expressions) { 13031 if (expression.hasEffectsOnInteractionAtPath(path, interaction, context)) 13032 return true; 13033 } 13034 return false; 13035 } 13036 } 13037 13038 class ConditionalExpression extends NodeBase { 13039 constructor() { 13040 super(...arguments); 13041 this.expressionsToBeDeoptimized = []; 13042 this.usedBranch = null; 13043 } 13044 get isBranchResolutionAnalysed() { 13045 return isFlagSet(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */); 13046 } 13047 set isBranchResolutionAnalysed(value) { 13048 this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value); 13049 } 13050 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 13051 this.consequent.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 13052 this.alternate.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 13053 } 13054 deoptimizeCache() { 13055 if (this.usedBranch !== null) { 13056 const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent; 13057 this.usedBranch = null; 13058 unusedBranch.deoptimizePath(UNKNOWN_PATH); 13059 const { expressionsToBeDeoptimized } = this; 13060 this.expressionsToBeDeoptimized = parseAst_js.EMPTY_ARRAY; 13061 for (const expression of expressionsToBeDeoptimized) { 13062 expression.deoptimizeCache(); 13063 } 13064 } 13065 } 13066 deoptimizePath(path) { 13067 const usedBranch = this.getUsedBranch(); 13068 if (usedBranch) { 13069 usedBranch.deoptimizePath(path); 13070 } 13071 else { 13072 this.consequent.deoptimizePath(path); 13073 this.alternate.deoptimizePath(path); 13074 } 13075 } 13076 getLiteralValueAtPath(path, recursionTracker, origin) { 13077 const usedBranch = this.getUsedBranch(); 13078 if (!usedBranch) 13079 return UnknownValue; 13080 this.expressionsToBeDeoptimized.push(origin); 13081 return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin); 13082 } 13083 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 13084 const usedBranch = this.getUsedBranch(); 13085 if (!usedBranch) 13086 return [ 13087 new MultiExpression([ 13088 this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0], 13089 this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0] 13090 ]), 13091 false 13092 ]; 13093 this.expressionsToBeDeoptimized.push(origin); 13094 return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 13095 } 13096 hasEffects(context) { 13097 if (this.test.hasEffects(context)) 13098 return true; 13099 const usedBranch = this.getUsedBranch(); 13100 if (!usedBranch) { 13101 return this.consequent.hasEffects(context) || this.alternate.hasEffects(context); 13102 } 13103 return usedBranch.hasEffects(context); 13104 } 13105 hasEffectsOnInteractionAtPath(path, interaction, context) { 13106 const usedBranch = this.getUsedBranch(); 13107 if (!usedBranch) { 13108 return (this.consequent.hasEffectsOnInteractionAtPath(path, interaction, context) || 13109 this.alternate.hasEffectsOnInteractionAtPath(path, interaction, context)); 13110 } 13111 return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context); 13112 } 13113 include(context, includeChildrenRecursively) { 13114 this.included = true; 13115 const usedBranch = this.getUsedBranch(); 13116 if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) { 13117 this.test.include(context, includeChildrenRecursively); 13118 this.consequent.include(context, includeChildrenRecursively); 13119 this.alternate.include(context, includeChildrenRecursively); 13120 } 13121 else { 13122 usedBranch.include(context, includeChildrenRecursively); 13123 } 13124 } 13125 includeCallArguments(context, parameters) { 13126 const usedBranch = this.getUsedBranch(); 13127 if (usedBranch) { 13128 usedBranch.includeCallArguments(context, parameters); 13129 } 13130 else { 13131 this.consequent.includeCallArguments(context, parameters); 13132 this.alternate.includeCallArguments(context, parameters); 13133 } 13134 } 13135 removeAnnotations(code) { 13136 this.test.removeAnnotations(code); 13137 } 13138 render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = parseAst_js.BLANK) { 13139 const usedBranch = this.getUsedBranch(); 13140 if (this.test.included) { 13141 this.test.render(code, options, { renderedSurroundingElement }); 13142 this.consequent.render(code, options); 13143 this.alternate.render(code, options); 13144 } 13145 else { 13146 const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end); 13147 const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included 13148 ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end) 13149 : colonPos) + 1); 13150 if (preventASI) { 13151 removeLineBreaks(code, inclusionStart, usedBranch.start); 13152 } 13153 code.remove(this.start, inclusionStart); 13154 if (this.consequent.included) { 13155 code.remove(colonPos, this.end); 13156 } 13157 this.test.removeAnnotations(code); 13158 usedBranch.render(code, options, { 13159 isCalleeOfRenderedParent, 13160 preventASI: true, 13161 renderedParentType: renderedParentType || this.parent.type, 13162 renderedSurroundingElement: renderedSurroundingElement || this.parent.type 13163 }); 13164 } 13165 } 13166 getUsedBranch() { 13167 if (this.isBranchResolutionAnalysed) { 13168 return this.usedBranch; 13169 } 13170 this.isBranchResolutionAnalysed = true; 13171 const testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 13172 return typeof testValue === 'symbol' 13173 ? null 13174 : (this.usedBranch = testValue ? this.consequent : this.alternate); 13175 } 13176 } 13177 13178 class ContinueStatement extends NodeBase { 13179 hasEffects(context) { 13180 if (this.label) { 13181 if (!context.ignore.labels.has(this.label.name)) 13182 return true; 13183 context.includedLabels.add(this.label.name); 13184 } 13185 else { 13186 if (!context.ignore.continues) 13187 return true; 13188 context.hasContinue = true; 13189 } 13190 context.brokenFlow = true; 13191 return false; 13192 } 13193 include(context) { 13194 this.included = true; 13195 if (this.label) { 13196 this.label.include(); 13197 context.includedLabels.add(this.label.name); 13198 } 13199 else { 13200 context.hasContinue = true; 13201 } 13202 context.brokenFlow = true; 13203 } 13204 } 13205 13206 class DebuggerStatement extends NodeBase { 13207 hasEffects() { 13208 return true; 13209 } 13210 } 13211 13212 class Decorator extends NodeBase { 13213 hasEffects(context) { 13214 return (this.expression.hasEffects(context) || 13215 this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context)); 13216 } 13217 } 13218 13219 function hasLoopBodyEffects(context, body) { 13220 const { brokenFlow, hasBreak, hasContinue, ignore } = context; 13221 const { breaks, continues } = ignore; 13222 ignore.breaks = true; 13223 ignore.continues = true; 13224 context.hasBreak = false; 13225 context.hasContinue = false; 13226 if (body.hasEffects(context)) 13227 return true; 13228 ignore.breaks = breaks; 13229 ignore.continues = continues; 13230 context.hasBreak = hasBreak; 13231 context.hasContinue = hasContinue; 13232 context.brokenFlow = brokenFlow; 13233 return false; 13234 } 13235 function includeLoopBody(context, body, includeChildrenRecursively) { 13236 const { brokenFlow, hasBreak, hasContinue } = context; 13237 context.hasBreak = false; 13238 context.hasContinue = false; 13239 body.include(context, includeChildrenRecursively, { asSingleStatement: true }); 13240 context.hasBreak = hasBreak; 13241 context.hasContinue = hasContinue; 13242 context.brokenFlow = brokenFlow; 13243 } 13244 13245 class DoWhileStatement extends NodeBase { 13246 hasEffects(context) { 13247 if (this.test.hasEffects(context)) 13248 return true; 13249 return hasLoopBodyEffects(context, this.body); 13250 } 13251 include(context, includeChildrenRecursively) { 13252 this.included = true; 13253 this.test.include(context, includeChildrenRecursively); 13254 includeLoopBody(context, this.body, includeChildrenRecursively); 13255 } 13256 } 13257 13258 class EmptyStatement extends NodeBase { 13259 hasEffects() { 13260 return false; 13261 } 13262 } 13263 13264 class ExportAllDeclaration extends NodeBase { 13265 hasEffects() { 13266 return false; 13267 } 13268 initialise() { 13269 super.initialise(); 13270 this.scope.context.addExport(this); 13271 } 13272 render(code, _options, nodeRenderOptions) { 13273 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 13274 } 13275 applyDeoptimizations() { } 13276 } 13277 ExportAllDeclaration.prototype.needsBoundaries = true; 13278 13279 class ExportNamedDeclaration extends NodeBase { 13280 bind() { 13281 // Do not bind specifiers 13282 this.declaration?.bind(); 13283 } 13284 hasEffects(context) { 13285 return !!this.declaration?.hasEffects(context); 13286 } 13287 initialise() { 13288 super.initialise(); 13289 this.scope.context.addExport(this); 13290 } 13291 removeAnnotations(code) { 13292 this.declaration?.removeAnnotations(code); 13293 } 13294 render(code, options, nodeRenderOptions) { 13295 const { start, end } = nodeRenderOptions; 13296 if (this.declaration === null) { 13297 code.remove(start, end); 13298 } 13299 else { 13300 code.remove(this.start, this.declaration.start); 13301 this.declaration.render(code, options, { end, start }); 13302 } 13303 } 13304 applyDeoptimizations() { } 13305 } 13306 ExportNamedDeclaration.prototype.needsBoundaries = true; 13307 13308 class ExportSpecifier extends NodeBase { 13309 applyDeoptimizations() { } 13310 } 13311 13312 class ForInStatement extends NodeBase { 13313 createScope(parentScope) { 13314 this.scope = new BlockScope(parentScope); 13315 } 13316 hasEffects(context) { 13317 const { body, deoptimized, left, right } = this; 13318 if (!deoptimized) 13319 this.applyDeoptimizations(); 13320 if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context)) 13321 return true; 13322 return hasLoopBodyEffects(context, body); 13323 } 13324 include(context, includeChildrenRecursively) { 13325 const { body, deoptimized, left, right } = this; 13326 if (!deoptimized) 13327 this.applyDeoptimizations(); 13328 this.included = true; 13329 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 13330 right.include(context, includeChildrenRecursively); 13331 includeLoopBody(context, body, includeChildrenRecursively); 13332 } 13333 initialise() { 13334 super.initialise(); 13335 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 13336 } 13337 render(code, options) { 13338 this.left.render(code, options, NO_SEMICOLON); 13339 this.right.render(code, options, NO_SEMICOLON); 13340 // handle no space between "in" and the right side 13341 if (code.original.charCodeAt(this.right.start - 1) === 110 /* n */) { 13342 code.prependLeft(this.right.start, ' '); 13343 } 13344 this.body.render(code, options); 13345 } 13346 applyDeoptimizations() { 13347 this.deoptimized = true; 13348 this.left.deoptimizePath(EMPTY_PATH); 13349 this.scope.context.requestTreeshakingPass(); 13350 } 13351 } 13352 13353 class ForOfStatement extends NodeBase { 13354 get await() { 13355 return isFlagSet(this.flags, 131072 /* Flag.await */); 13356 } 13357 set await(value) { 13358 this.flags = setFlag(this.flags, 131072 /* Flag.await */, value); 13359 } 13360 createScope(parentScope) { 13361 this.scope = new BlockScope(parentScope); 13362 } 13363 hasEffects() { 13364 if (!this.deoptimized) 13365 this.applyDeoptimizations(); 13366 // Placeholder until proper Symbol.Iterator support 13367 return true; 13368 } 13369 include(context, includeChildrenRecursively) { 13370 const { body, deoptimized, left, right } = this; 13371 if (!deoptimized) 13372 this.applyDeoptimizations(); 13373 this.included = true; 13374 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 13375 right.include(context, includeChildrenRecursively); 13376 includeLoopBody(context, body, includeChildrenRecursively); 13377 } 13378 initialise() { 13379 super.initialise(); 13380 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 13381 } 13382 render(code, options) { 13383 this.left.render(code, options, NO_SEMICOLON); 13384 this.right.render(code, options, NO_SEMICOLON); 13385 // handle no space between "of" and the right side 13386 if (code.original.charCodeAt(this.right.start - 1) === 102 /* f */) { 13387 code.prependLeft(this.right.start, ' '); 13388 } 13389 this.body.render(code, options); 13390 } 13391 applyDeoptimizations() { 13392 this.deoptimized = true; 13393 this.left.deoptimizePath(EMPTY_PATH); 13394 this.right.deoptimizePath(UNKNOWN_PATH); 13395 this.scope.context.requestTreeshakingPass(); 13396 } 13397 } 13398 13399 class ForStatement extends NodeBase { 13400 createScope(parentScope) { 13401 this.scope = new BlockScope(parentScope); 13402 } 13403 hasEffects(context) { 13404 if (this.init?.hasEffects(context) || 13405 this.test?.hasEffects(context) || 13406 this.update?.hasEffects(context)) { 13407 return true; 13408 } 13409 return hasLoopBodyEffects(context, this.body); 13410 } 13411 include(context, includeChildrenRecursively) { 13412 this.included = true; 13413 this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true }); 13414 this.test?.include(context, includeChildrenRecursively); 13415 this.update?.include(context, includeChildrenRecursively); 13416 includeLoopBody(context, this.body, includeChildrenRecursively); 13417 } 13418 render(code, options) { 13419 this.init?.render(code, options, NO_SEMICOLON); 13420 this.test?.render(code, options, NO_SEMICOLON); 13421 this.update?.render(code, options, NO_SEMICOLON); 13422 this.body.render(code, options); 13423 } 13424 } 13425 13426 class FunctionExpression extends FunctionNode { 13427 createScope(parentScope) { 13428 super.createScope((this.idScope = new ChildScope(parentScope, parentScope.context))); 13429 } 13430 parseNode(esTreeNode) { 13431 if (esTreeNode.id !== null) { 13432 this.id = new Identifier(this, this.idScope).parseNode(esTreeNode.id); 13433 } 13434 return super.parseNode(esTreeNode); 13435 } 13436 onlyFunctionCallUsed() { 13437 const isIIFE = this.parent.type === parseAst_js.CallExpression && 13438 this.parent.callee === this && 13439 (this.id === null || this.id.variable.getOnlyFunctionCallUsed()); 13440 return isIIFE || super.onlyFunctionCallUsed(); 13441 } 13442 render(code, options, { renderedSurroundingElement } = parseAst_js.BLANK) { 13443 super.render(code, options); 13444 if (renderedSurroundingElement === parseAst_js.ExpressionStatement) { 13445 code.appendRight(this.start, '('); 13446 code.prependLeft(this.end, ')'); 13447 } 13448 } 13449 } 13450 13451 class TrackingScope extends BlockScope { 13452 constructor() { 13453 super(...arguments); 13454 this.hoistedDeclarations = []; 13455 } 13456 addDeclaration(identifier, context, init, kind) { 13457 this.hoistedDeclarations.push(identifier); 13458 return super.addDeclaration(identifier, context, init, kind); 13459 } 13460 } 13461 13462 const unset = Symbol('unset'); 13463 class IfStatement extends NodeBase { 13464 constructor() { 13465 super(...arguments); 13466 this.testValue = unset; 13467 } 13468 deoptimizeCache() { 13469 this.testValue = UnknownValue; 13470 } 13471 hasEffects(context) { 13472 if (this.test.hasEffects(context)) { 13473 return true; 13474 } 13475 const testValue = this.getTestValue(); 13476 if (typeof testValue === 'symbol') { 13477 const { brokenFlow } = context; 13478 if (this.consequent.hasEffects(context)) 13479 return true; 13480 const consequentBrokenFlow = context.brokenFlow; 13481 context.brokenFlow = brokenFlow; 13482 if (this.alternate === null) 13483 return false; 13484 if (this.alternate.hasEffects(context)) 13485 return true; 13486 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 13487 return false; 13488 } 13489 return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context); 13490 } 13491 include(context, includeChildrenRecursively) { 13492 this.included = true; 13493 if (includeChildrenRecursively) { 13494 this.includeRecursively(includeChildrenRecursively, context); 13495 } 13496 else { 13497 const testValue = this.getTestValue(); 13498 if (typeof testValue === 'symbol') { 13499 this.includeUnknownTest(context); 13500 } 13501 else { 13502 this.includeKnownTest(context, testValue); 13503 } 13504 } 13505 } 13506 parseNode(esTreeNode) { 13507 this.consequent = new (this.scope.context.getNodeConstructor(esTreeNode.consequent.type))(this, (this.consequentScope = new TrackingScope(this.scope))).parseNode(esTreeNode.consequent); 13508 if (esTreeNode.alternate) { 13509 this.alternate = new (this.scope.context.getNodeConstructor(esTreeNode.alternate.type))(this, (this.alternateScope = new TrackingScope(this.scope))).parseNode(esTreeNode.alternate); 13510 } 13511 return super.parseNode(esTreeNode); 13512 } 13513 render(code, options) { 13514 const { snippets: { getPropertyAccess } } = options; 13515 // Note that unknown test values are always included 13516 const testValue = this.getTestValue(); 13517 const hoistedDeclarations = []; 13518 const includesIfElse = this.test.included; 13519 const noTreeshake = !this.scope.context.options.treeshake; 13520 if (includesIfElse) { 13521 this.test.render(code, options); 13522 } 13523 else { 13524 code.remove(this.start, this.consequent.start); 13525 } 13526 if (this.consequent.included && (noTreeshake || typeof testValue === 'symbol' || testValue)) { 13527 this.consequent.render(code, options); 13528 } 13529 else { 13530 code.overwrite(this.consequent.start, this.consequent.end, includesIfElse ? ';' : ''); 13531 hoistedDeclarations.push(...this.consequentScope.hoistedDeclarations); 13532 } 13533 if (this.alternate) { 13534 if (this.alternate.included && (noTreeshake || typeof testValue === 'symbol' || !testValue)) { 13535 if (includesIfElse) { 13536 if (code.original.charCodeAt(this.alternate.start - 1) === 101) { 13537 code.prependLeft(this.alternate.start, ' '); 13538 } 13539 } 13540 else { 13541 code.remove(this.consequent.end, this.alternate.start); 13542 } 13543 this.alternate.render(code, options); 13544 } 13545 else { 13546 if (includesIfElse && this.shouldKeepAlternateBranch()) { 13547 code.overwrite(this.alternate.start, this.end, ';'); 13548 } 13549 else { 13550 code.remove(this.consequent.end, this.end); 13551 } 13552 hoistedDeclarations.push(...this.alternateScope.hoistedDeclarations); 13553 } 13554 } 13555 this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess); 13556 } 13557 applyDeoptimizations() { } 13558 getTestValue() { 13559 if (this.testValue === unset) { 13560 return (this.testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)); 13561 } 13562 return this.testValue; 13563 } 13564 includeKnownTest(context, testValue) { 13565 if (this.test.shouldBeIncluded(context)) { 13566 this.test.include(context, false); 13567 } 13568 if (testValue && this.consequent.shouldBeIncluded(context)) { 13569 this.consequent.include(context, false, { asSingleStatement: true }); 13570 } 13571 if (!testValue && this.alternate?.shouldBeIncluded(context)) { 13572 this.alternate.include(context, false, { asSingleStatement: true }); 13573 } 13574 } 13575 includeRecursively(includeChildrenRecursively, context) { 13576 this.test.include(context, includeChildrenRecursively); 13577 this.consequent.include(context, includeChildrenRecursively); 13578 this.alternate?.include(context, includeChildrenRecursively); 13579 } 13580 includeUnknownTest(context) { 13581 this.test.include(context, false); 13582 const { brokenFlow } = context; 13583 let consequentBrokenFlow = false; 13584 if (this.consequent.shouldBeIncluded(context)) { 13585 this.consequent.include(context, false, { asSingleStatement: true }); 13586 consequentBrokenFlow = context.brokenFlow; 13587 context.brokenFlow = brokenFlow; 13588 } 13589 if (this.alternate?.shouldBeIncluded(context)) { 13590 this.alternate.include(context, false, { asSingleStatement: true }); 13591 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 13592 } 13593 } 13594 renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess) { 13595 const hoistedVariables = [ 13596 ...new Set(hoistedDeclarations.map(identifier => { 13597 const variable = identifier.variable; 13598 return variable.included ? variable.getName(getPropertyAccess) : ''; 13599 })) 13600 ] 13601 .filter(Boolean) 13602 .join(', '); 13603 if (hoistedVariables) { 13604 const parentType = this.parent.type; 13605 const needsBraces = parentType !== parseAst_js.Program && parentType !== parseAst_js.BlockStatement; 13606 code.prependRight(this.start, `${needsBraces ? '{ ' : ''}var ${hoistedVariables}; `); 13607 if (needsBraces) { 13608 code.appendLeft(this.end, ` }`); 13609 } 13610 } 13611 } 13612 shouldKeepAlternateBranch() { 13613 let currentParent = this.parent; 13614 do { 13615 if (currentParent instanceof IfStatement && currentParent.alternate) { 13616 return true; 13617 } 13618 if (currentParent instanceof BlockStatement) { 13619 return false; 13620 } 13621 currentParent = currentParent.parent; 13622 } while (currentParent); 13623 return false; 13624 } 13625 } 13626 13627 class ImportAttribute extends NodeBase { 13628 } 13629 13630 class ImportDeclaration extends NodeBase { 13631 // Do not bind specifiers or attributes 13632 bind() { } 13633 hasEffects() { 13634 return false; 13635 } 13636 initialise() { 13637 super.initialise(); 13638 this.scope.context.addImport(this); 13639 } 13640 render(code, _options, nodeRenderOptions) { 13641 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 13642 } 13643 applyDeoptimizations() { } 13644 } 13645 ImportDeclaration.prototype.needsBoundaries = true; 13646 13647 class ImportDefaultSpecifier extends NodeBase { 13648 applyDeoptimizations() { } 13649 } 13650 12117 13651 function isReassignedExportsMember(variable, exportNamesByVariable) { 12118 13652 return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned); … … 12473 14007 } 12474 14008 14009 class JSXIdentifier extends IdentifierBase { 14010 constructor() { 14011 super(...arguments); 14012 this.isNativeElement = false; 14013 } 14014 bind() { 14015 const type = this.getType(); 14016 if (type === 0 /* IdentifierType.Reference */) { 14017 this.variable = this.scope.findVariable(this.name); 14018 this.variable.addReference(this); 14019 } 14020 else if (type === 1 /* IdentifierType.NativeElementName */) { 14021 this.isNativeElement = true; 14022 } 14023 } 14024 render(code, { snippets: { getPropertyAccess }, useOriginalName }) { 14025 if (this.variable) { 14026 const name = this.variable.getName(getPropertyAccess, useOriginalName); 14027 if (name !== this.name) { 14028 code.overwrite(this.start, this.end, name, { 14029 contentOnly: true, 14030 storeName: true 14031 }); 14032 } 14033 } 14034 else if (this.isNativeElement && 14035 this.scope.context.options.jsx.mode !== 'preserve') { 14036 code.update(this.start, this.end, JSON.stringify(this.name)); 14037 } 14038 } 14039 getType() { 14040 switch (this.parent.type) { 14041 case 'JSXOpeningElement': 14042 case 'JSXClosingElement': { 14043 return this.name.startsWith(this.name.charAt(0).toUpperCase()) 14044 ? 0 /* IdentifierType.Reference */ 14045 : 1 /* IdentifierType.NativeElementName */; 14046 } 14047 case 'JSXMemberExpression': { 14048 return this.parent.object === this 14049 ? 0 /* IdentifierType.Reference */ 14050 : 2 /* IdentifierType.Other */; 14051 } 14052 case 'JSXAttribute': 14053 case 'JSXNamespacedName': { 14054 return 2 /* IdentifierType.Other */; 14055 } 14056 default: { 14057 /* istanbul ignore next */ 14058 throw new Error(`Unexpected parent node type for JSXIdentifier: ${this.parent.type}`); 14059 } 14060 } 14061 } 14062 } 14063 14064 class JSXAttribute extends NodeBase { 14065 render(code, options, { jsxMode } = parseAst_js.BLANK) { 14066 super.render(code, options); 14067 if (['classic', 'automatic'].includes(jsxMode)) { 14068 const { name, value } = this; 14069 const key = name instanceof JSXIdentifier ? name.name : `${name.namespace.name}:${name.name.name}`; 14070 if (!(jsxMode === 'automatic' && key === 'key')) { 14071 const safeKey = stringifyObjectKeyIfNeeded(key); 14072 if (key !== safeKey) { 14073 code.overwrite(name.start, name.end, safeKey, { contentOnly: true }); 14074 } 14075 if (value) { 14076 code.overwrite(name.end, value.start, ': ', { contentOnly: true }); 14077 } 14078 else { 14079 code.appendLeft(name.end, ': true'); 14080 } 14081 } 14082 } 14083 } 14084 } 14085 14086 class JSXClosingBase extends NodeBase { 14087 render(code, options) { 14088 const { mode } = this.scope.context.options.jsx; 14089 if (mode !== 'preserve') { 14090 code.overwrite(this.start, this.end, ')', { contentOnly: true }); 14091 } 14092 else { 14093 super.render(code, options); 14094 } 14095 } 14096 } 14097 14098 class JSXClosingElement extends JSXClosingBase { 14099 } 14100 14101 class JSXClosingFragment extends JSXClosingBase { 14102 } 14103 14104 class JSXSpreadAttribute extends NodeBase { 14105 render(code, options) { 14106 this.argument.render(code, options); 14107 const { mode } = this.scope.context.options.jsx; 14108 if (mode !== 'preserve') { 14109 code.overwrite(this.start, this.argument.start, '', { contentOnly: true }); 14110 code.overwrite(this.argument.end, this.end, '', { contentOnly: true }); 14111 } 14112 } 14113 } 14114 14115 class JSXEmptyExpression extends NodeBase { 14116 } 14117 14118 class JSXExpressionContainer extends NodeBase { 14119 render(code, options) { 14120 const { mode } = this.scope.context.options.jsx; 14121 if (mode !== 'preserve') { 14122 code.remove(this.start, this.expression.start); 14123 code.remove(this.expression.end, this.end); 14124 } 14125 this.expression.render(code, options); 14126 } 14127 } 14128 14129 function getRenderedJsxChildren(children) { 14130 let renderedChildren = 0; 14131 for (const child of children) { 14132 if (!(child instanceof JSXExpressionContainer && child.expression instanceof JSXEmptyExpression)) { 14133 renderedChildren++; 14134 } 14135 } 14136 return renderedChildren; 14137 } 14138 14139 function getAndIncludeFactoryVariable(factory, preserve, importSource, node) { 14140 const [baseName, nestedName] = factory.split('.'); 14141 let factoryVariable; 14142 if (importSource) { 14143 factoryVariable = node.scope.context.getImportedJsxFactoryVariable(nestedName ? 'default' : baseName, node.start, importSource); 14144 if (preserve) { 14145 // This pretends we are accessing an included global variable of the same name 14146 const globalVariable = node.scope.findGlobal(baseName); 14147 globalVariable.include(); 14148 // This excludes this variable from renaming 14149 factoryVariable.globalName = baseName; 14150 } 14151 } 14152 else { 14153 factoryVariable = node.scope.findGlobal(baseName); 14154 } 14155 node.scope.context.includeVariableInModule(factoryVariable); 14156 if (factoryVariable instanceof LocalVariable) { 14157 factoryVariable.consolidateInitializers(); 14158 factoryVariable.addUsedPlace(node); 14159 node.scope.context.requestTreeshakingPass(); 14160 } 14161 return factoryVariable; 14162 } 14163 14164 class JSXElementBase extends NodeBase { 14165 constructor() { 14166 super(...arguments); 14167 this.factoryVariable = null; 14168 this.factory = null; 14169 } 14170 initialise() { 14171 super.initialise(); 14172 const { importSource } = (this.jsxMode = this.getRenderingMode()); 14173 if (importSource) { 14174 this.scope.context.addImportSource(importSource); 14175 } 14176 } 14177 include(context, includeChildrenRecursively) { 14178 if (!this.included) { 14179 const { factory, importSource, mode } = this.jsxMode; 14180 if (factory) { 14181 this.factory = factory; 14182 this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this); 14183 } 14184 } 14185 super.include(context, includeChildrenRecursively); 14186 } 14187 applyDeoptimizations() { } 14188 getRenderingMode() { 14189 const jsx = this.scope.context.options.jsx; 14190 const { mode, factory, importSource } = jsx; 14191 if (mode === 'automatic') { 14192 return { 14193 factory: getRenderedJsxChildren(this.children) > 1 ? 'jsxs' : 'jsx', 14194 importSource: jsx.jsxImportSource, 14195 mode 14196 }; 14197 } 14198 return { factory, importSource, mode }; 14199 } 14200 renderChildren(code, options, openingEnd) { 14201 const { children } = this; 14202 let hasMultipleChildren = false; 14203 let childrenEnd = openingEnd; 14204 let firstChild = null; 14205 for (const child of children) { 14206 if (child instanceof JSXExpressionContainer && 14207 child.expression instanceof JSXEmptyExpression) { 14208 code.remove(childrenEnd, child.end); 14209 } 14210 else { 14211 code.appendLeft(childrenEnd, ', '); 14212 child.render(code, options); 14213 if (firstChild) { 14214 hasMultipleChildren = true; 14215 } 14216 else { 14217 firstChild = child; 14218 } 14219 } 14220 childrenEnd = child.end; 14221 } 14222 return { childrenEnd, firstChild, hasMultipleChildren }; 14223 } 14224 } 14225 14226 class JSXElement extends JSXElementBase { 14227 render(code, options) { 14228 switch (this.jsxMode.mode) { 14229 case 'classic': { 14230 this.renderClassicMode(code, options); 14231 break; 14232 } 14233 case 'automatic': { 14234 this.renderAutomaticMode(code, options); 14235 break; 14236 } 14237 default: { 14238 super.render(code, options); 14239 } 14240 } 14241 } 14242 getRenderingMode() { 14243 const jsx = this.scope.context.options.jsx; 14244 const { mode, factory, importSource } = jsx; 14245 if (mode === 'automatic') { 14246 // In the case there is a key after a spread attribute, we fall back to 14247 // classic mode, see https://github.com/facebook/react/issues/20031#issuecomment-710346866 14248 // for reasoning. 14249 let hasSpread = false; 14250 for (const attribute of this.openingElement.attributes) { 14251 if (attribute instanceof JSXSpreadAttribute) { 14252 hasSpread = true; 14253 } 14254 else if (hasSpread && attribute.name.name === 'key') { 14255 return { factory, importSource, mode: 'classic' }; 14256 } 14257 } 14258 } 14259 return super.getRenderingMode(); 14260 } 14261 renderClassicMode(code, options) { 14262 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14263 const { closingElement, end, factory, factoryVariable, openingElement: { end: openingEnd, selfClosing } } = this; 14264 const [, ...nestedName] = factory.split('.'); 14265 const { firstAttribute, hasAttributes, hasSpread, inObject, previousEnd } = this.renderAttributes(code, options, [factoryVariable.getName(getPropertyAccess, useOriginalName), ...nestedName].join('.'), false); 14266 this.wrapAttributes(code, inObject, hasAttributes, hasSpread, firstAttribute, 'null', previousEnd); 14267 this.renderChildren(code, options, openingEnd); 14268 if (selfClosing) { 14269 code.appendLeft(end, ')'); 14270 } 14271 else { 14272 closingElement.render(code, options); 14273 } 14274 } 14275 renderAutomaticMode(code, options) { 14276 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14277 const { closingElement, end, factoryVariable, openingElement: { end: openindEnd, selfClosing } } = this; 14278 let { firstAttribute, hasAttributes, hasSpread, inObject, keyAttribute, previousEnd } = this.renderAttributes(code, options, factoryVariable.getName(getPropertyAccess, useOriginalName), true); 14279 const { firstChild, hasMultipleChildren, childrenEnd } = this.renderChildren(code, options, openindEnd); 14280 if (firstChild) { 14281 code.prependRight(firstChild.start, `children: ${hasMultipleChildren ? '[' : ''}`); 14282 if (!inObject) { 14283 code.prependRight(firstChild.start, '{ '); 14284 inObject = true; 14285 } 14286 previousEnd = closingElement.start; 14287 if (hasMultipleChildren) { 14288 code.appendLeft(previousEnd, ']'); 14289 } 14290 } 14291 this.wrapAttributes(code, inObject, hasAttributes || !!firstChild, hasSpread, firstAttribute || firstChild, '{}', childrenEnd); 14292 if (keyAttribute) { 14293 const { value } = keyAttribute; 14294 // This will appear to the left of the moved code... 14295 code.appendLeft(childrenEnd, ', '); 14296 if (value) { 14297 code.move(value.start, value.end, childrenEnd); 14298 } 14299 else { 14300 code.appendLeft(childrenEnd, 'true'); 14301 } 14302 } 14303 if (selfClosing) { 14304 // Moving the key attribute will also move the parenthesis to the right position 14305 code.appendLeft(keyAttribute?.value?.end || end, ')'); 14306 } 14307 else { 14308 closingElement.render(code, options); 14309 } 14310 } 14311 renderAttributes(code, options, factoryName, extractKeyAttribute) { 14312 const { jsxMode: { mode }, openingElement } = this; 14313 const { attributes, end: openingEnd, start: openingStart, name: { start: nameStart, end: nameEnd } } = openingElement; 14314 code.update(openingStart, nameStart, `/*#__PURE__*/${factoryName}(`); 14315 openingElement.render(code, options, { jsxMode: mode }); 14316 let keyAttribute = null; 14317 let hasSpread = false; 14318 let inObject = false; 14319 let previousEnd = nameEnd; 14320 let hasAttributes = false; 14321 let firstAttribute = null; 14322 for (const attribute of attributes) { 14323 if (attribute instanceof JSXAttribute) { 14324 if (extractKeyAttribute && attribute.name.name === 'key') { 14325 keyAttribute = attribute; 14326 code.remove(previousEnd, attribute.value?.start || attribute.end); 14327 continue; 14328 } 14329 code.appendLeft(previousEnd, ','); 14330 if (!inObject) { 14331 code.prependRight(attribute.start, '{ '); 14332 inObject = true; 14333 } 14334 hasAttributes = true; 14335 } 14336 else { 14337 if (inObject) { 14338 if (hasAttributes) { 14339 code.appendLeft(previousEnd, ' '); 14340 } 14341 code.appendLeft(previousEnd, '},'); 14342 inObject = false; 14343 } 14344 else { 14345 code.appendLeft(previousEnd, ','); 14346 } 14347 hasSpread = true; 14348 } 14349 previousEnd = attribute.end; 14350 if (!firstAttribute) { 14351 firstAttribute = attribute; 14352 } 14353 } 14354 code.remove(attributes.at(-1)?.end || previousEnd, openingEnd); 14355 return { firstAttribute, hasAttributes, hasSpread, inObject, keyAttribute, previousEnd }; 14356 } 14357 wrapAttributes(code, inObject, hasAttributes, hasSpread, firstAttribute, missingAttributesFallback, attributesEnd) { 14358 if (inObject) { 14359 code.appendLeft(attributesEnd, ' }'); 14360 } 14361 if (hasSpread) { 14362 if (hasAttributes) { 14363 const { start } = firstAttribute; 14364 if (firstAttribute instanceof JSXSpreadAttribute) { 14365 code.prependRight(start, '{}, '); 14366 } 14367 code.prependRight(start, 'Object.assign('); 14368 code.appendLeft(attributesEnd, ')'); 14369 } 14370 } 14371 else if (!hasAttributes) { 14372 code.appendLeft(attributesEnd, `, ${missingAttributesFallback}`); 14373 } 14374 } 14375 } 14376 14377 class JSXFragment extends JSXElementBase { 14378 render(code, options) { 14379 switch (this.jsxMode.mode) { 14380 case 'classic': { 14381 this.renderClassicMode(code, options); 14382 break; 14383 } 14384 case 'automatic': { 14385 this.renderAutomaticMode(code, options); 14386 break; 14387 } 14388 default: { 14389 super.render(code, options); 14390 } 14391 } 14392 } 14393 renderClassicMode(code, options) { 14394 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14395 const { closingFragment, factory, factoryVariable, openingFragment, start } = this; 14396 const [, ...nestedName] = factory.split('.'); 14397 openingFragment.render(code, options); 14398 code.prependRight(start, `/*#__PURE__*/${[ 14399 factoryVariable.getName(getPropertyAccess, useOriginalName), 14400 ...nestedName 14401 ].join('.')}(`); 14402 code.appendLeft(openingFragment.end, ', null'); 14403 this.renderChildren(code, options, openingFragment.end); 14404 closingFragment.render(code, options); 14405 } 14406 renderAutomaticMode(code, options) { 14407 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14408 const { closingFragment, factoryVariable, openingFragment, start } = this; 14409 openingFragment.render(code, options); 14410 code.prependRight(start, `/*#__PURE__*/${factoryVariable.getName(getPropertyAccess, useOriginalName)}(`); 14411 const { firstChild, hasMultipleChildren, childrenEnd } = this.renderChildren(code, options, openingFragment.end); 14412 if (firstChild) { 14413 code.prependRight(firstChild.start, `{ children: ${hasMultipleChildren ? '[' : ''}`); 14414 if (hasMultipleChildren) { 14415 code.appendLeft(closingFragment.start, ']'); 14416 } 14417 code.appendLeft(childrenEnd, ' }'); 14418 } 14419 else { 14420 code.appendLeft(openingFragment.end, ', {}'); 14421 } 14422 closingFragment.render(code, options); 14423 } 14424 } 14425 14426 class JSXMemberExpression extends NodeBase { 14427 } 14428 14429 class JSXNamespacedName extends NodeBase { 14430 } 14431 14432 class JSXOpeningElement extends NodeBase { 14433 render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) { 14434 this.name.render(code, options); 14435 for (const attribute of this.attributes) { 14436 attribute.render(code, options, { jsxMode }); 14437 } 14438 } 14439 } 14440 14441 class JSXOpeningFragment extends NodeBase { 14442 constructor() { 14443 super(...arguments); 14444 this.fragment = null; 14445 this.fragmentVariable = null; 14446 } 14447 include(context, includeChildrenRecursively) { 14448 if (!this.included) { 14449 const jsx = this.scope.context.options.jsx; 14450 if (jsx.mode === 'automatic') { 14451 this.fragment = 'Fragment'; 14452 this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this); 14453 } 14454 else { 14455 const { fragment, importSource, mode } = jsx; 14456 if (fragment != null) { 14457 this.fragment = fragment; 14458 this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this); 14459 } 14460 } 14461 } 14462 super.include(context, includeChildrenRecursively); 14463 } 14464 render(code, options) { 14465 const { mode } = this.scope.context.options.jsx; 14466 if (mode !== 'preserve') { 14467 const { snippets: { getPropertyAccess }, useOriginalName } = options; 14468 const [, ...nestedFragment] = this.fragment.split('.'); 14469 const fragment = [ 14470 this.fragmentVariable.getName(getPropertyAccess, useOriginalName), 14471 ...nestedFragment 14472 ].join('.'); 14473 code.update(this.start, this.end, fragment); 14474 } 14475 } 14476 } 14477 14478 class JSXSpreadChild extends NodeBase { 14479 render(code, options) { 14480 super.render(code, options); 14481 const { mode } = this.scope.context.options.jsx; 14482 if (mode !== 'preserve') { 14483 code.overwrite(this.start, this.expression.start, '...', { contentOnly: true }); 14484 code.overwrite(this.expression.end, this.end, '', { contentOnly: true }); 14485 } 14486 } 14487 } 14488 14489 class JSXText extends NodeBase { 14490 render(code) { 14491 const { mode } = this.scope.context.options.jsx; 14492 if (mode !== 'preserve') { 14493 code.overwrite(this.start, this.end, JSON.stringify(this.value), { 14494 contentOnly: true 14495 }); 14496 } 14497 } 14498 } 14499 12475 14500 class LabeledStatement extends NodeBase { 12476 14501 hasEffects(context) { … … 12660 14685 } 12661 14686 12662 const FILE_PREFIX = 'ROLLUP_FILE_URL_';12663 const IMPORT = 'import';12664 class MetaProperty extends NodeBase {12665 constructor() {12666 super(...arguments);12667 this.metaProperty = null;12668 this.preliminaryChunkId = null;12669 this.referenceId = null;12670 }12671 getReferencedFileName(outputPluginDriver) {12672 const { meta: { name }, metaProperty } = this;12673 if (name === IMPORT && metaProperty?.startsWith(FILE_PREFIX)) {12674 return outputPluginDriver.getFileName(metaProperty.slice(FILE_PREFIX.length));12675 }12676 return null;12677 }12678 hasEffects() {12679 return false;12680 }12681 hasEffectsOnInteractionAtPath(path, { type }) {12682 return path.length > 1 || type !== INTERACTION_ACCESSED;12683 }12684 include() {12685 if (!this.included) {12686 this.included = true;12687 if (this.meta.name === IMPORT) {12688 this.scope.context.addImportMeta(this);12689 const parent = this.parent;12690 const metaProperty = (this.metaProperty =12691 parent instanceof MemberExpression && typeof parent.propertyKey === 'string'12692 ? parent.propertyKey12693 : null);12694 if (metaProperty?.startsWith(FILE_PREFIX)) {12695 this.referenceId = metaProperty.slice(FILE_PREFIX.length);12696 }12697 }12698 }12699 }12700 render(code, renderOptions) {12701 const { format, pluginDriver, snippets } = renderOptions;12702 const { scope: { context: { module } }, meta: { name }, metaProperty, parent, preliminaryChunkId, referenceId, start, end } = this;12703 const { id: moduleId } = module;12704 if (name !== IMPORT)12705 return;12706 const chunkId = preliminaryChunkId;12707 if (referenceId) {12708 const fileName = pluginDriver.getFileName(referenceId);12709 const relativePath = parseAst_js.normalize(path$2.relative(path$2.dirname(chunkId), fileName));12710 const replacement = pluginDriver.hookFirstSync('resolveFileUrl', [12711 { chunkId, fileName, format, moduleId, referenceId, relativePath }12712 ]) || relativeUrlMechanisms[format](relativePath);12713 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true });12714 return;12715 }12716 let replacement = pluginDriver.hookFirstSync('resolveImportMeta', [12717 metaProperty,12718 { chunkId, format, moduleId }12719 ]);12720 if (!replacement) {12721 replacement = importMetaMechanisms[format]?.(metaProperty, { chunkId, snippets });12722 renderOptions.accessedDocumentCurrentScript ||=12723 formatsMaybeAccessDocumentCurrentScript.includes(format) && replacement !== 'undefined';12724 }12725 if (typeof replacement === 'string') {12726 if (parent instanceof MemberExpression) {12727 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true });12728 }12729 else {12730 code.overwrite(start, end, replacement, { contentOnly: true });12731 }12732 }12733 }12734 setResolution(format, accessedGlobalsByScope, preliminaryChunkId) {12735 this.preliminaryChunkId = preliminaryChunkId;12736 const accessedGlobals = (this.metaProperty?.startsWith(FILE_PREFIX) ? accessedFileUrlGlobals : accessedMetaUrlGlobals)[format];12737 if (accessedGlobals.length > 0) {12738 this.scope.addAccessedGlobals(accessedGlobals, accessedGlobalsByScope);12739 }12740 }12741 }12742 const formatsMaybeAccessDocumentCurrentScript = ['cjs', 'iife', 'umd'];12743 const accessedMetaUrlGlobals = {12744 amd: ['document', 'module', 'URL'],12745 cjs: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT],12746 es: [],12747 iife: ['document', 'URL', DOCUMENT_CURRENT_SCRIPT],12748 system: ['module'],12749 umd: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT]12750 };12751 const accessedFileUrlGlobals = {12752 amd: ['document', 'require', 'URL'],12753 cjs: ['document', 'require', 'URL'],12754 es: [],12755 iife: ['document', 'URL'],12756 system: ['module', 'URL'],12757 umd: ['document', 'require', 'URL']12758 };12759 const getResolveUrl = (path, URL = 'URL') => `new ${URL}(${path}).href`;12760 const getRelativeUrlFromDocument = (relativePath, umd = false) => getResolveUrl(`'${escapeId(relativePath)}', ${umd ? `typeof document === 'undefined' ? location.href : ` : ''}document.currentScript && document.currentScript.src || document.baseURI`);12761 const getGenericImportMetaMechanism = (getUrl) => (property, { chunkId }) => {12762 const urlMechanism = getUrl(chunkId);12763 return property === null12764 ? `({ url: ${urlMechanism} })`12765 : property === 'url'12766 ? urlMechanism12767 : 'undefined';12768 };12769 const getFileUrlFromFullPath = (path) => `require('u' + 'rl').pathToFileURL(${path}).href`;12770 const getFileUrlFromRelativePath = (path) => getFileUrlFromFullPath(`__dirname + '/${escapeId(path)}'`);12771 const getUrlFromDocument = (chunkId, umd = false) => `${umd ? `typeof document === 'undefined' ? location.href : ` : ''}(${DOCUMENT_CURRENT_SCRIPT} && ${DOCUMENT_CURRENT_SCRIPT}.src || new URL('${escapeId(chunkId)}', document.baseURI).href)`;12772 const relativeUrlMechanisms = {12773 amd: relativePath => {12774 if (relativePath[0] !== '.')12775 relativePath = './' + relativePath;12776 return getResolveUrl(`require.toUrl('${escapeId(relativePath)}'), document.baseURI`);12777 },12778 cjs: relativePath => `(typeof document === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath)})`,12779 es: relativePath => getResolveUrl(`'${escapeId(relativePath)}', import.meta.url`),12780 iife: relativePath => getRelativeUrlFromDocument(relativePath),12781 system: relativePath => getResolveUrl(`'${escapeId(relativePath)}', module.meta.url`),12782 umd: relativePath => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath, true)})`12783 };12784 const importMetaMechanisms = {12785 amd: getGenericImportMetaMechanism(() => getResolveUrl(`module.uri, document.baseURI`)),12786 cjs: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId)})`),12787 iife: getGenericImportMetaMechanism(chunkId => getUrlFromDocument(chunkId)),12788 system: (property, { snippets: { getPropertyAccess } }) => property === null ? `module.meta` : `module.meta${getPropertyAccess(property)}`,12789 umd: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId, true)})`)12790 };12791 12792 14687 class NewExpression extends NodeBase { 12793 14688 hasEffects(context) { … … 13224 15119 render(code, options, nodeRenderOptions) { 13225 15120 if (this.consequent.length > 0) { 13226 this.test && this.test.render(code, options); 15121 if (this.test) { 15122 this.test.render(code, options); 15123 } 13227 15124 const testEnd = this.test 13228 15125 ? this.test.end … … 13436 15333 code.indentExclusionRanges.push([this.start, this.end]); 13437 15334 super.render(code, options); 13438 }13439 }13440 13441 class UndefinedVariable extends Variable {13442 constructor() {13443 super('undefined');13444 }13445 getLiteralValueAtPath() {13446 return undefined;13447 }13448 }13449 13450 class ExportDefaultVariable extends LocalVariable {13451 constructor(name, exportDefaultDeclaration, context) {13452 super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');13453 this.hasId = false;13454 this.originalId = null;13455 this.originalVariable = null;13456 const declaration = exportDefaultDeclaration.declaration;13457 if ((declaration instanceof FunctionDeclaration || declaration instanceof ClassDeclaration) &&13458 declaration.id) {13459 this.hasId = true;13460 this.originalId = declaration.id;13461 }13462 else if (declaration instanceof Identifier) {13463 this.originalId = declaration;13464 }13465 }13466 addReference(identifier) {13467 if (!this.hasId) {13468 this.name = identifier.name;13469 }13470 }13471 addUsedPlace(usedPlace) {13472 const original = this.getOriginalVariable();13473 if (original === this) {13474 super.addUsedPlace(usedPlace);13475 }13476 else {13477 original.addUsedPlace(usedPlace);13478 }13479 }13480 forbidName(name) {13481 const original = this.getOriginalVariable();13482 if (original === this) {13483 super.forbidName(name);13484 }13485 else {13486 original.forbidName(name);13487 }13488 }13489 getAssignedVariableName() {13490 return (this.originalId && this.originalId.name) || null;13491 }13492 getBaseVariableName() {13493 const original = this.getOriginalVariable();13494 return original === this ? super.getBaseVariableName() : original.getBaseVariableName();13495 }13496 getDirectOriginalVariable() {13497 return this.originalId &&13498 (this.hasId ||13499 !(this.originalId.isPossibleTDZ() ||13500 this.originalId.variable.isReassigned ||13501 this.originalId.variable instanceof UndefinedVariable ||13502 // this avoids a circular dependency13503 'syntheticNamespace' in this.originalId.variable))13504 ? this.originalId.variable13505 : null;13506 }13507 getName(getPropertyAccess) {13508 const original = this.getOriginalVariable();13509 return original === this13510 ? super.getName(getPropertyAccess)13511 : original.getName(getPropertyAccess);13512 }13513 getOriginalVariable() {13514 if (this.originalVariable)13515 return this.originalVariable;13516 // eslint-disable-next-line @typescript-eslint/no-this-alias13517 let original = this;13518 let currentVariable;13519 const checkedVariables = new Set();13520 do {13521 checkedVariables.add(original);13522 currentVariable = original;13523 original = currentVariable.getDirectOriginalVariable();13524 } while (original instanceof ExportDefaultVariable && !checkedVariables.has(original));13525 return (this.originalVariable = original || currentVariable);13526 15335 } 13527 15336 } … … 14017 15826 'ImportNamespaceSpecifier', 14018 15827 'ImportSpecifier', 15828 'JSXAttribute', 15829 'JSXClosingElement', 15830 'JSXClosingFragment', 15831 'JSXElement', 15832 'JSXEmptyExpression', 15833 'JSXExpressionContainer', 15834 'JSXFragment', 15835 'JSXIdentifier', 15836 'JSXMemberExpression', 15837 'JSXNamespacedName', 15838 'JSXOpeningElement', 15839 'JSXOpeningFragment', 15840 'JSXSpreadAttribute', 15841 'JSXSpreadChild', 15842 'JSXText', 14019 15843 'LabeledStatement', 14020 15844 'Literal', … … 14099 15923 ImportNamespaceSpecifier, 14100 15924 ImportSpecifier, 15925 JSXAttribute, 15926 JSXClosingElement, 15927 JSXClosingFragment, 15928 JSXElement, 15929 JSXEmptyExpression, 15930 JSXExpressionContainer, 15931 JSXFragment, 15932 JSXIdentifier, 15933 JSXMemberExpression, 15934 JSXNamespacedName, 15935 JSXOpeningElement, 15936 JSXOpeningFragment, 15937 JSXSpreadAttribute, 15938 JSXSpreadChild, 15939 JSXText, 14101 15940 LabeledStatement, 14102 15941 Literal, … … 14218 16057 const { scope } = node; 14219 16058 const bodyPosition = buffer[position]; 14220 const body = (node.body = []);14221 16059 if (bodyPosition) { 14222 16060 const length = buffer[bodyPosition]; 16061 const body = (node.body = new Array(length)); 14223 16062 for (let index = 0; index < length; index++) { 14224 16063 const nodePosition = buffer[bodyPosition + 1 + index]; 14225 body.push(convertNode(node, (buffer[nodePosition + 3] & 1) === 0 ? scope.instanceScope : scope, nodePosition, buffer)); 14226 } 16064 body[index] = convertNode(node, (buffer[nodePosition + 3] & 1) === 0 ? scope.instanceScope : scope, nodePosition, buffer); 16065 } 16066 } 16067 else { 16068 node.body = []; 14227 16069 } 14228 16070 }, … … 14404 16246 node.imported = 14405 16247 importedPosition === 0 ? node.local : convertNode(node, scope, importedPosition, buffer); 16248 }, 16249 function jsxAttribute(node, position, buffer) { 16250 const { scope } = node; 16251 node.name = convertNode(node, scope, buffer[position], buffer); 16252 const valuePosition = buffer[position + 1]; 16253 node.value = valuePosition === 0 ? null : convertNode(node, scope, valuePosition, buffer); 16254 }, 16255 function jsxClosingElement(node, position, buffer) { 16256 const { scope } = node; 16257 node.name = convertNode(node, scope, buffer[position], buffer); 16258 }, 16259 function jsxClosingFragment() { }, 16260 function jsxElement(node, position, buffer) { 16261 const { scope } = node; 16262 node.openingElement = convertNode(node, scope, buffer[position], buffer); 16263 node.children = convertNodeList(node, scope, buffer[position + 1], buffer); 16264 const closingElementPosition = buffer[position + 2]; 16265 node.closingElement = 16266 closingElementPosition === 0 16267 ? null 16268 : convertNode(node, scope, closingElementPosition, buffer); 16269 }, 16270 function jsxEmptyExpression() { }, 16271 function jsxExpressionContainer(node, position, buffer) { 16272 const { scope } = node; 16273 node.expression = convertNode(node, scope, buffer[position], buffer); 16274 }, 16275 function jsxFragment(node, position, buffer) { 16276 const { scope } = node; 16277 node.openingFragment = convertNode(node, scope, buffer[position], buffer); 16278 node.children = convertNodeList(node, scope, buffer[position + 1], buffer); 16279 node.closingFragment = convertNode(node, scope, buffer[position + 2], buffer); 16280 }, 16281 function jsxIdentifier(node, position, buffer) { 16282 node.name = buffer.convertString(buffer[position]); 16283 }, 16284 function jsxMemberExpression(node, position, buffer) { 16285 const { scope } = node; 16286 node.object = convertNode(node, scope, buffer[position], buffer); 16287 node.property = convertNode(node, scope, buffer[position + 1], buffer); 16288 }, 16289 function jsxNamespacedName(node, position, buffer) { 16290 const { scope } = node; 16291 node.namespace = convertNode(node, scope, buffer[position], buffer); 16292 node.name = convertNode(node, scope, buffer[position + 1], buffer); 16293 }, 16294 function jsxOpeningElement(node, position, buffer) { 16295 const { scope } = node; 16296 const flags = buffer[position]; 16297 node.selfClosing = (flags & 1) === 1; 16298 node.name = convertNode(node, scope, buffer[position + 1], buffer); 16299 node.attributes = convertNodeList(node, scope, buffer[position + 2], buffer); 16300 }, 16301 function jsxOpeningFragment(node) { 16302 node.attributes = []; 16303 node.selfClosing = false; 16304 }, 16305 function jsxSpreadAttribute(node, position, buffer) { 16306 const { scope } = node; 16307 node.argument = convertNode(node, scope, buffer[position], buffer); 16308 }, 16309 function jsxSpreadChild(node, position, buffer) { 16310 const { scope } = node; 16311 node.expression = convertNode(node, scope, buffer[position], buffer); 16312 }, 16313 function jsxText(node, position, buffer) { 16314 node.value = buffer.convertString(buffer[position]); 16315 node.raw = buffer.convertString(buffer[position + 1]); 14406 16316 }, 14407 16317 function labeledStatement(node, position, buffer) { … … 14635 16545 return parseAst_js.EMPTY_ARRAY; 14636 16546 const length = buffer[position++]; 14637 const list = [];16547 const list = new Array(length); 14638 16548 for (let index = 0; index < length; index++) { 14639 16549 const nodePosition = buffer[position++]; 14640 list .push(nodePosition ? convertNode(parent, parentScope, nodePosition, buffer) : null);16550 list[index] = nodePosition ? convertNode(parent, parentScope, nodePosition, buffer) : null; 14641 16551 } 14642 16552 return list; … … 14694 16604 ImportNamespaceSpecifier, 14695 16605 ImportSpecifier, 16606 JSXAttribute, 16607 JSXClosingElement, 16608 JSXClosingFragment, 16609 JSXElement, 16610 JSXEmptyExpression, 16611 JSXExpressionContainer, 16612 JSXFragment, 16613 JSXIdentifier, 16614 JSXMemberExpression, 16615 JSXNamespacedName, 16616 JSXOpeningElement, 16617 JSXOpeningFragment, 16618 JSXSpreadAttribute, 16619 JSXSpreadChild, 16620 JSXText, 14696 16621 LabeledStatement, 14697 16622 Literal, … … 14732 16657 }; 14733 16658 14734 const MISSING_EXPORT_SHIM_VARIABLE = '_missingExportShim';14735 14736 16659 class ExportShimVariable extends Variable { 14737 16660 constructor(module) { … … 14742 16665 super.include(); 14743 16666 this.module.needsExportShim = true; 14744 }14745 }14746 14747 class NamespaceVariable extends Variable {14748 constructor(context) {14749 super(context.getModuleName());14750 this.memberVariables = null;14751 this.mergedNamespaces = [];14752 this.referencedEarly = false;14753 this.references = [];14754 this.context = context;14755 this.module = context.module;14756 }14757 addReference(identifier) {14758 this.references.push(identifier);14759 this.name = identifier.name;14760 }14761 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {14762 if (path.length > 1 || (path.length === 1 && interaction.type === INTERACTION_CALLED)) {14763 const key = path[0];14764 if (typeof key === 'string') {14765 this.getMemberVariables()[key]?.deoptimizeArgumentsOnInteractionAtPath(interaction, path.slice(1), recursionTracker);14766 }14767 else {14768 deoptimizeInteraction(interaction);14769 }14770 }14771 }14772 deoptimizePath(path) {14773 if (path.length > 1) {14774 const key = path[0];14775 if (typeof key === 'string') {14776 this.getMemberVariables()[key]?.deoptimizePath(path.slice(1));14777 }14778 }14779 }14780 getLiteralValueAtPath(path) {14781 if (path[0] === SymbolToStringTag) {14782 return 'Module';14783 }14784 return UnknownValue;14785 }14786 getMemberVariables() {14787 if (this.memberVariables) {14788 return this.memberVariables;14789 }14790 const memberVariables = Object.create(null);14791 const sortedExports = [...this.context.getExports(), ...this.context.getReexports()].sort();14792 for (const name of sortedExports) {14793 if (name[0] !== '*' && name !== this.module.info.syntheticNamedExports) {14794 const exportedVariable = this.context.traceExport(name);14795 if (exportedVariable) {14796 memberVariables[name] = exportedVariable;14797 }14798 }14799 }14800 return (this.memberVariables = memberVariables);14801 }14802 hasEffectsOnInteractionAtPath(path, interaction, context) {14803 const { type } = interaction;14804 if (path.length === 0) {14805 // This can only be a call anyway14806 return true;14807 }14808 if (path.length === 1 && type !== INTERACTION_CALLED) {14809 return type === INTERACTION_ASSIGNED;14810 }14811 const key = path[0];14812 if (typeof key !== 'string') {14813 return true;14814 }14815 const memberVariable = this.getMemberVariables()[key];14816 return (!memberVariable ||14817 memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));14818 }14819 include() {14820 super.include();14821 this.context.includeAllExports();14822 }14823 prepare(accessedGlobalsByScope) {14824 if (this.mergedNamespaces.length > 0) {14825 this.module.scope.addAccessedGlobals([MERGE_NAMESPACES_VARIABLE], accessedGlobalsByScope);14826 }14827 }14828 renderBlock(options) {14829 const { exportNamesByVariable, format, freeze, indent: t, symbols, snippets: { _, cnst, getObject, getPropertyAccess, n, s } } = options;14830 const memberVariables = this.getMemberVariables();14831 const members = Object.entries(memberVariables)14832 .filter(([_, variable]) => variable.included)14833 .map(([name, variable]) => {14834 if (this.referencedEarly || variable.isReassigned || variable === this) {14835 return [14836 null,14837 `get ${stringifyObjectKeyIfNeeded(name)}${_}()${_}{${_}return ${variable.getName(getPropertyAccess)}${s}${_}}`14838 ];14839 }14840 return [name, variable.getName(getPropertyAccess)];14841 });14842 members.unshift([null, `__proto__:${_}null`]);14843 let output = getObject(members, { lineBreakIndent: { base: '', t } });14844 if (this.mergedNamespaces.length > 0) {14845 const assignmentArguments = this.mergedNamespaces.map(variable => variable.getName(getPropertyAccess));14846 output = `/*#__PURE__*/${MERGE_NAMESPACES_VARIABLE}(${output},${_}[${assignmentArguments.join(`,${_}`)}])`;14847 }14848 else {14849 // The helper to merge namespaces will also take care of freezing and toStringTag14850 if (symbols) {14851 output = `/*#__PURE__*/Object.defineProperty(${output},${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)})`;14852 }14853 if (freeze) {14854 output = `/*#__PURE__*/Object.freeze(${output})`;14855 }14856 }14857 const name = this.getName(getPropertyAccess);14858 output = `${cnst} ${name}${_}=${_}${output};`;14859 if (format === 'system' && exportNamesByVariable.has(this)) {14860 output += `${n}${getSystemExportStatement([this], options)};`;14861 }14862 return output;14863 }14864 renderFirst() {14865 return this.referencedEarly;14866 }14867 setMergedNamespaces(mergedNamespaces) {14868 this.mergedNamespaces = mergedNamespaces;14869 const moduleExecIndex = this.context.getModuleExecIndex();14870 for (const identifier of this.references) {14871 const { context } = identifier.scope;14872 if (context.getModuleExecIndex() <= moduleExecIndex) {14873 this.referencedEarly = true;14874 break;14875 }14876 }14877 }14878 }14879 NamespaceVariable.prototype.isNamespace = true;14880 14881 class SyntheticNamedExportVariable extends Variable {14882 constructor(context, name, syntheticNamespace) {14883 super(name);14884 this.baseVariable = null;14885 this.context = context;14886 this.module = context.module;14887 this.syntheticNamespace = syntheticNamespace;14888 }14889 getBaseVariable() {14890 if (this.baseVariable)14891 return this.baseVariable;14892 let baseVariable = this.syntheticNamespace;14893 while (baseVariable instanceof ExportDefaultVariable ||14894 baseVariable instanceof SyntheticNamedExportVariable) {14895 if (baseVariable instanceof ExportDefaultVariable) {14896 const original = baseVariable.getOriginalVariable();14897 if (original === baseVariable)14898 break;14899 baseVariable = original;14900 }14901 if (baseVariable instanceof SyntheticNamedExportVariable) {14902 baseVariable = baseVariable.syntheticNamespace;14903 }14904 }14905 return (this.baseVariable = baseVariable);14906 }14907 getBaseVariableName() {14908 return this.syntheticNamespace.getBaseVariableName();14909 }14910 getName(getPropertyAccess) {14911 return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;14912 }14913 include() {14914 super.include();14915 this.context.includeVariableInModule(this.syntheticNamespace);14916 }14917 setRenderNames(baseName, name) {14918 super.setRenderNames(baseName, name);14919 16667 } 14920 16668 } … … 15185 16933 } 15186 16934 15187 function markModuleAndImpureDependenciesAsExecuted(baseModule) {15188 baseModule.isExecuted = true;15189 const modules = [baseModule];15190 const visitedModules = new Set();15191 for (const module of modules) {15192 for (const dependency of [...module.dependencies, ...module.implicitlyLoadedBefore]) {15193 if (!(dependency instanceof ExternalModule) &&15194 !dependency.isExecuted &&15195 (dependency.info.moduleSideEffects || module.implicitlyLoadedBefore.has(dependency)) &&15196 !visitedModules.has(dependency.id)) {15197 dependency.isExecuted = true;15198 visitedModules.add(dependency.id);15199 modules.push(dependency);15200 }15201 }15202 }15203 }15204 15205 16935 const MISSING_EXPORT_SHIM_DESCRIPTION = { 15206 16936 identifier: null, … … 15264 16994 this.dynamicImports = []; 15265 16995 this.execIndex = Infinity; 16996 this.hasTreeShakingPassStarted = false; 15266 16997 this.implicitlyLoadedAfter = new Set(); 15267 16998 this.implicitlyLoadedBefore = new Set(); … … 15340 17071 id, 15341 17072 get implicitlyLoadedAfterOneOf() { 15342 // eslint-disable-next-line unicorn/prefer-spread15343 17073 return Array.from(implicitlyLoadedAfter, getId).sort(); 15344 17074 }, 15345 17075 get implicitlyLoadedBefore() { 15346 // eslint-disable-next-line unicorn/prefer-spread15347 17076 return Array.from(implicitlyLoadedBefore, getId).sort(); 15348 17077 }, 15349 17078 get importedIdResolutions() { 15350 // eslint-disable-next-line unicorn/prefer-spread15351 17079 return Array.from(sourcesWithAttributes.keys(), source => module.resolvedIds[source]).filter(Boolean); 15352 17080 }, … … 15354 17082 // We cannot use this.dependencies because this is needed before 15355 17083 // dependencies are populated 15356 // eslint-disable-next-line unicorn/prefer-spread15357 17084 return Array.from(sourcesWithAttributes.keys(), source => module.resolvedIds[source]?.id).filter(Boolean); 15358 17085 }, … … 15374 17101 } 15375 17102 basename() { 15376 const base = path $2.basename(this.id);15377 const extension = path $2.extname(this.id);17103 const base = path.basename(this.id); 17104 const extension = path.extname(this.id); 15378 17105 return makeLegal(extension ? base.slice(0, -extension.length) : base); 15379 17106 } … … 15397 17124 } 15398 17125 error(properties, pos) { 15399 pos !== undefined && this.addLocationToLogProps(properties, pos); 17126 if (pos !== undefined) { 17127 this.addLocationToLogProps(properties, pos); 17128 } 15400 17129 return parseAst_js.error(properties); 15401 17130 } … … 15750 17479 addImport: this.addImport.bind(this), 15751 17480 addImportMeta: this.addImportMeta.bind(this), 17481 addImportSource: this.addImportSource.bind(this), 15752 17482 code, // Only needed for debugging 15753 17483 deoptimizationTracker: this.graph.deoptimizationTracker, … … 15755 17485 fileName, // Needed for warnings 15756 17486 getExports: this.getExports.bind(this), 17487 getImportedJsxFactoryVariable: this.getImportedJsxFactoryVariable.bind(this), 15757 17488 getModuleExecIndex: () => this.execIndex, 15758 17489 getModuleName: this.basename.bind(this), … … 15784 17515 // Measuring asynchronous code does not provide reasonable results 15785 17516 timeEnd('generate ast', 3); 15786 const astBuffer = await native_js.parseAsync(code, false );17517 const astBuffer = await native_js.parseAsync(code, false, this.options.jsx !== false); 15787 17518 timeStart('generate ast', 3); 15788 17519 this.ast = convertProgram(astBuffer, programParent, this.scope); … … 15819 17550 code: this.info.code, 15820 17551 customTransformCache: this.customTransformCache, 15821 // eslint-disable-next-line unicorn/prefer-spread15822 17552 dependencies: Array.from(this.dependencies, getId), 15823 17553 id: this.id, … … 15976 17706 start: specifier.start 15977 17707 }); 17708 } 17709 } 17710 addImportSource(importSource) { 17711 if (importSource && !this.sourcesWithAttributes.has(importSource)) { 17712 this.sourcesWithAttributes.set(importSource, parseAst_js.EMPTY_OBJECT); 15978 17713 } 15979 17714 } … … 16041 17776 } 16042 17777 } 17778 getImportedJsxFactoryVariable(baseName, nodeStart, importSource) { 17779 const { id } = this.resolvedIds[importSource]; 17780 const module = this.graph.modulesById.get(id); 17781 const [variable] = module.getVariableForExportName(baseName); 17782 if (!variable) { 17783 return this.error(parseAst_js.logMissingJsxExport(baseName, id, this.id), nodeStart); 17784 } 17785 return variable; 17786 } 16043 17787 getVariableFromNamespaceReexports(name, importerForSideEffects, searchedNamesAndModules) { 16044 17788 let foundSyntheticDeclaration = null; … … 16161 17905 tryParse() { 16162 17906 try { 16163 return parseAst_js.parseAst(this.info.code );17907 return parseAst_js.parseAst(this.info.code, { jsx: this.options.jsx !== false }); 16164 17908 } 16165 17909 catch (error_) { … … 16186 17930 } 16187 17931 const copyNameToModulesMap = (searchedNamesAndModules) => searchedNamesAndModules && 16188 // eslint-disable-next-line unicorn/prefer-spread16189 17932 new Map(Array.from(searchedNamesAndModules, ([name, modules]) => [name, new Set(modules)])); 16190 16191 function removeJsExtension(name) {16192 return name.endsWith('.js') ? name.slice(0, -3) : name;16193 }16194 16195 function getCompleteAmdId(options, chunkId) {16196 if (options.autoId) {16197 return `${options.basePath ? options.basePath + '/' : ''}${removeJsExtension(chunkId)}`;16198 }16199 return options.id ?? '';16200 }16201 16202 function getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, mechanism = 'return ') {16203 const { _, getDirectReturnFunction, getFunctionIntro, getPropertyAccess, n, s } = snippets;16204 if (!namedExportsMode) {16205 return `${n}${n}${mechanism}${getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess)};`;16206 }16207 let exportBlock = '';16208 if (namedExportsMode) {16209 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) {16210 if (!reexports) {16211 continue;16212 }16213 for (const specifier of reexports) {16214 if (specifier.reexported !== '*') {16215 const importName = getReexportedImportName(name, specifier.imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess);16216 if (exportBlock)16217 exportBlock += n;16218 if (specifier.imported !== '*' && specifier.needsLiveBinding) {16219 const [left, right] = getDirectReturnFunction([], {16220 functionReturn: true,16221 lineBreakIndent: null,16222 name: null16223 });16224 exportBlock +=16225 `Object.defineProperty(exports,${_}${JSON.stringify(specifier.reexported)},${_}{${n}` +16226 `${t}enumerable:${_}true,${n}` +16227 `${t}get:${_}${left}${importName}${right}${n}});`;16228 }16229 else if (specifier.reexported === '__proto__') {16230 exportBlock +=16231 `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` +16232 `${t}enumerable:${_}true,${n}` +16233 `${t}value:${_}${importName}${n}});`;16234 }16235 else {16236 exportBlock += `exports${getPropertyAccess(specifier.reexported)}${_}=${_}${importName};`;16237 }16238 }16239 }16240 }16241 }16242 for (const { exported, local } of exports) {16243 const lhs = `exports${getPropertyAccess(exported)}`;16244 const rhs = local;16245 if (lhs !== rhs) {16246 if (exportBlock)16247 exportBlock += n;16248 exportBlock +=16249 exported === '__proto__'16250 ? `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` +16251 `${t}enumerable:${_}true,${n}` +16252 `${t}value:${_}${rhs}${n}});`16253 : `${lhs}${_}=${_}${rhs};`;16254 }16255 }16256 if (namedExportsMode) {16257 for (const { name, reexports } of dependencies) {16258 if (!reexports) {16259 continue;16260 }16261 for (const specifier of reexports) {16262 if (specifier.reexported === '*') {16263 if (exportBlock)16264 exportBlock += n;16265 if (!specifier.needsLiveBinding && reexportProtoFromExternal) {16266 const protoString = "'__proto__'";16267 exportBlock +=16268 `Object.prototype.hasOwnProperty.call(${name},${_}${protoString})${_}&&${n}` +16269 `${t}!Object.prototype.hasOwnProperty.call(exports,${_}${protoString})${_}&&${n}` +16270 `${t}Object.defineProperty(exports,${_}${protoString},${_}{${n}` +16271 `${t}${t}enumerable:${_}true,${n}` +16272 `${t}${t}value:${_}${name}[${protoString}]${n}` +16273 `${t}});${n}${n}`;16274 }16275 const copyPropertyIfNecessary = `{${n}${t}if${_}(k${_}!==${_}'default'${_}&&${_}!Object.prototype.hasOwnProperty.call(exports,${_}k))${_}${getDefineProperty(name, specifier.needsLiveBinding, t, snippets)}${s}${n}}`;16276 exportBlock += `Object.keys(${name}).forEach(${getFunctionIntro(['k'], {16277 isAsync: false,16278 name: null16279 })}${copyPropertyIfNecessary});`;16280 }16281 }16282 }16283 }16284 if (exportBlock) {16285 return `${n}${n}${exportBlock}`;16286 }16287 return '';16288 }16289 function getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess) {16290 if (exports.length > 0) {16291 return exports[0].local;16292 }16293 else {16294 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) {16295 if (reexports) {16296 return getReexportedImportName(name, reexports[0].imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess);16297 }16298 }16299 }16300 }16301 function getReexportedImportName(moduleVariableName, imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, moduleId, externalLiveBindings, getPropertyAccess) {16302 if (imported === 'default') {16303 if (!isChunk) {16304 const moduleInterop = interop(moduleId);16305 const variableName = defaultInteropHelpersByInteropType[moduleInterop]16306 ? defaultVariableName16307 : moduleVariableName;16308 return isDefaultAProperty(moduleInterop, externalLiveBindings)16309 ? `${variableName}${getPropertyAccess('default')}`16310 : variableName;16311 }16312 return depNamedExportsMode16313 ? `${moduleVariableName}${getPropertyAccess('default')}`16314 : moduleVariableName;16315 }16316 if (imported === '*') {16317 return (isChunk ? !depNamedExportsMode : namespaceInteropHelpersByInteropType[interop(moduleId)])16318 ? namespaceVariableName16319 : moduleVariableName;16320 }16321 return `${moduleVariableName}${getPropertyAccess(imported)}`;16322 }16323 function getEsModuleValue(getObject) {16324 return getObject([['value', 'true']], {16325 lineBreakIndent: null16326 });16327 }16328 function getNamespaceMarkers(hasNamedExports, addEsModule, addNamespaceToStringTag, { _, getObject }) {16329 if (hasNamedExports) {16330 if (addEsModule) {16331 if (addNamespaceToStringTag) {16332 return `Object.defineProperties(exports,${_}${getObject([16333 ['__esModule', getEsModuleValue(getObject)],16334 [null, `[Symbol.toStringTag]:${_}${getToStringTagValue(getObject)}`]16335 ], {16336 lineBreakIndent: null16337 })});`;16338 }16339 return `Object.defineProperty(exports,${_}'__esModule',${_}${getEsModuleValue(getObject)});`;16340 }16341 if (addNamespaceToStringTag) {16342 return `Object.defineProperty(exports,${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)});`;16343 }16344 }16345 return '';16346 }16347 const getDefineProperty = (name, needsLiveBinding, t, { _, getDirectReturnFunction, n }) => {16348 if (needsLiveBinding) {16349 const [left, right] = getDirectReturnFunction([], {16350 functionReturn: true,16351 lineBreakIndent: null,16352 name: null16353 });16354 return (`Object.defineProperty(exports,${_}k,${_}{${n}` +16355 `${t}${t}enumerable:${_}true,${n}` +16356 `${t}${t}get:${_}${left}${name}[k]${right}${n}${t}})`);16357 }16358 return `exports[k]${_}=${_}${name}[k]`;16359 };16360 16361 function getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, indent, snippets) {16362 const { _, cnst, n } = snippets;16363 const neededInteropHelpers = new Set();16364 const interopStatements = [];16365 const addInteropStatement = (helperVariableName, helper, dependencyVariableName) => {16366 neededInteropHelpers.add(helper);16367 interopStatements.push(`${cnst} ${helperVariableName}${_}=${_}/*#__PURE__*/${helper}(${dependencyVariableName});`);16368 };16369 for (const { defaultVariableName, imports, importPath, isChunk, name, namedExportsMode, namespaceVariableName, reexports } of dependencies) {16370 if (isChunk) {16371 for (const { imported, reexported } of [16372 ...(imports || []),16373 ...(reexports || [])16374 ]) {16375 if (imported === '*' && reexported !== '*') {16376 if (!namedExportsMode) {16377 addInteropStatement(namespaceVariableName, INTEROP_NAMESPACE_DEFAULT_ONLY_VARIABLE, name);16378 }16379 break;16380 }16381 }16382 }16383 else {16384 const moduleInterop = interop(importPath);16385 let hasDefault = false;16386 let hasNamespace = false;16387 for (const { imported, reexported } of [16388 ...(imports || []),16389 ...(reexports || [])16390 ]) {16391 let helper;16392 let variableName;16393 if (imported === 'default') {16394 if (!hasDefault) {16395 hasDefault = true;16396 if (defaultVariableName !== namespaceVariableName) {16397 variableName = defaultVariableName;16398 helper = defaultInteropHelpersByInteropType[moduleInterop];16399 }16400 }16401 }16402 else if (imported === '*' && reexported !== '*' && !hasNamespace) {16403 hasNamespace = true;16404 helper = namespaceInteropHelpersByInteropType[moduleInterop];16405 variableName = namespaceVariableName;16406 }16407 if (helper) {16408 addInteropStatement(variableName, helper, name);16409 }16410 }16411 }16412 }16413 return `${getHelpersBlock(neededInteropHelpers, accessedGlobals, indent, snippets, externalLiveBindings, freeze, symbols)}${interopStatements.length > 0 ? `${interopStatements.join(n)}${n}${n}` : ''}`;16414 }16415 16416 function addJsExtension(name) {16417 return name.endsWith('.js') ? name : name + '.js';16418 }16419 16420 // AMD resolution will only respect the AMD baseUrl if the .js extension is omitted.16421 // The assumption is that this makes sense for all relative ids:16422 // https://requirejs.org/docs/api.html#jsfiles16423 function updateExtensionForRelativeAmdId(id, forceJsExtensionForImports) {16424 if (id[0] !== '.') {16425 return id;16426 }16427 return forceJsExtensionForImports ? addJsExtension(id) : removeJsExtension(id);16428 }16429 16430 const builtinModules = [16431 "assert",16432 "assert/strict",16433 "async_hooks",16434 "buffer",16435 "child_process",16436 "cluster",16437 "console",16438 "constants",16439 "crypto",16440 "dgram",16441 "diagnostics_channel",16442 "dns",16443 "dns/promises",16444 "domain",16445 "events",16446 "fs",16447 "fs/promises",16448 "http",16449 "http2",16450 "https",16451 "inspector",16452 "inspector/promises",16453 "module",16454 "net",16455 "os",16456 "path",16457 "path/posix",16458 "path/win32",16459 "perf_hooks",16460 "process",16461 "punycode",16462 "querystring",16463 "readline",16464 "readline/promises",16465 "repl",16466 "stream",16467 "stream/consumers",16468 "stream/promises",16469 "stream/web",16470 "string_decoder",16471 "timers",16472 "timers/promises",16473 "tls",16474 "trace_events",16475 "tty",16476 "url",16477 "util",16478 "util/types",16479 "v8",16480 "vm",16481 "wasi",16482 "worker_threads",16483 "zlib"16484 ];16485 16486 const nodeBuiltins = new Set(builtinModules);16487 function warnOnBuiltins(log, dependencies) {16488 const externalBuiltins = dependencies16489 .map(({ importPath }) => importPath)16490 .filter(importPath => nodeBuiltins.has(importPath) || importPath.startsWith('node:'));16491 if (externalBuiltins.length === 0)16492 return;16493 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingNodeBuiltins(externalBuiltins));16494 }16495 16496 function amd(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, id, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, log, outro, snippets }, { amd, esModule, externalLiveBindings, freeze, generatedCode: { symbols }, interop, reexportProtoFromExternal, strict }) {16497 warnOnBuiltins(log, dependencies);16498 const deps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`);16499 const parameters = dependencies.map(m => m.name);16500 const { n, getNonArrowFunctionIntro, _ } = snippets;16501 if (namedExportsMode && hasExports) {16502 parameters.unshift(`exports`);16503 deps.unshift(`'exports'`);16504 }16505 if (accessedGlobals.has('require')) {16506 parameters.unshift('require');16507 deps.unshift(`'require'`);16508 }16509 if (accessedGlobals.has('module')) {16510 parameters.unshift('module');16511 deps.unshift(`'module'`);16512 }16513 const completeAmdId = getCompleteAmdId(amd, id);16514 const defineParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) +16515 (deps.length > 0 ? `[${deps.join(`,${_}`)}],${_}` : ``);16516 const useStrict = strict ? `${_}'use strict';` : '';16517 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`);16518 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);16519 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets);16520 if (namespaceMarkers) {16521 namespaceMarkers = n + n + namespaceMarkers;16522 }16523 magicString16524 .append(`${exportBlock}${namespaceMarkers}${outro}`)16525 .indent(t)16526 // factory function should be wrapped by parentheses to avoid lazy parsing,16527 // cf. https://v8.dev/blog/preparser#pife16528 .prepend(`${amd.define}(${defineParameters}(${getNonArrowFunctionIntro(parameters, {16529 isAsync: false,16530 name: null16531 })}{${useStrict}${n}${n}`)16532 .append(`${n}${n}}));`);16533 }16534 16535 function cjs(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, indent: t, intro, isEntryFacade, isModuleFacade, namedExportsMode, outro, snippets }, { compact, esModule, externalLiveBindings, freeze, interop, generatedCode: { symbols }, reexportProtoFromExternal, strict }) {16536 const { _, n } = snippets;16537 const useStrict = strict ? `'use strict';${n}${n}` : '';16538 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets);16539 if (namespaceMarkers) {16540 namespaceMarkers += n + n;16541 }16542 const importBlock = getImportBlock$1(dependencies, snippets, compact);16543 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets);16544 magicString.prepend(`${useStrict}${intro}${namespaceMarkers}${importBlock}${interopBlock}`);16545 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, `module.exports${_}=${_}`);16546 magicString.append(`${exportBlock}${outro}`);16547 }16548 function getImportBlock$1(dependencies, { _, cnst, n }, compact) {16549 let importBlock = '';16550 let definingVariable = false;16551 for (const { importPath, name, reexports, imports } of dependencies) {16552 if (!reexports && !imports) {16553 if (importBlock) {16554 importBlock += compact && !definingVariable ? ',' : `;${n}`;16555 }16556 definingVariable = false;16557 importBlock += `require('${importPath}')`;16558 }16559 else {16560 importBlock += compact && definingVariable ? ',' : `${importBlock ? `;${n}` : ''}${cnst} `;16561 definingVariable = true;16562 importBlock += `${name}${_}=${_}require('${importPath}')`;16563 }16564 }16565 if (importBlock) {16566 return `${importBlock};${n}${n}`;16567 }16568 return '';16569 }16570 16571 function es(magicString, { accessedGlobals, indent: t, intro, outro, dependencies, exports, snippets }, { externalLiveBindings, freeze, generatedCode: { symbols }, importAttributesKey }) {16572 const { n } = snippets;16573 const importBlock = getImportBlock(dependencies, importAttributesKey, snippets);16574 if (importBlock.length > 0)16575 intro += importBlock.join(n) + n + n;16576 intro += getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols);16577 if (intro)16578 magicString.prepend(intro);16579 const exportBlock = getExportBlock(exports, snippets);16580 if (exportBlock.length > 0)16581 magicString.append(n + n + exportBlock.join(n).trim());16582 if (outro)16583 magicString.append(outro);16584 magicString.trim();16585 }16586 function getImportBlock(dependencies, importAttributesKey, { _ }) {16587 const importBlock = [];16588 for (const { importPath, reexports, imports, name, attributes } of dependencies) {16589 const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : '';16590 const pathWithAssertion = `'${importPath}'${assertion};`;16591 if (!reexports && !imports) {16592 importBlock.push(`import${_}${pathWithAssertion}`);16593 continue;16594 }16595 if (imports) {16596 let defaultImport = null;16597 let starImport = null;16598 const importedNames = [];16599 for (const specifier of imports) {16600 if (specifier.imported === 'default') {16601 defaultImport = specifier;16602 }16603 else if (specifier.imported === '*') {16604 starImport = specifier;16605 }16606 else {16607 importedNames.push(specifier);16608 }16609 }16610 if (starImport) {16611 importBlock.push(`import${_}*${_}as ${starImport.local} from${_}${pathWithAssertion}`);16612 }16613 if (defaultImport && importedNames.length === 0) {16614 importBlock.push(`import ${defaultImport.local} from${_}${pathWithAssertion}`);16615 }16616 else if (importedNames.length > 0) {16617 importBlock.push(`import ${defaultImport ? `${defaultImport.local},${_}` : ''}{${_}${importedNames16618 .map(specifier => specifier.imported === specifier.local16619 ? specifier.imported16620 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${specifier.local}`)16621 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`);16622 }16623 }16624 if (reexports) {16625 let starExport = null;16626 const namespaceReexports = [];16627 const namedReexports = [];16628 for (const specifier of reexports) {16629 if (specifier.reexported === '*') {16630 starExport = specifier;16631 }16632 else if (specifier.imported === '*') {16633 namespaceReexports.push(specifier);16634 }16635 else {16636 namedReexports.push(specifier);16637 }16638 }16639 if (starExport) {16640 importBlock.push(`export${_}*${_}from${_}${pathWithAssertion}`);16641 }16642 if (namespaceReexports.length > 0) {16643 if (!imports ||16644 !imports.some(specifier => specifier.imported === '*' && specifier.local === name)) {16645 importBlock.push(`import${_}*${_}as ${name} from${_}${pathWithAssertion}`);16646 }16647 for (const specifier of namespaceReexports) {16648 importBlock.push(`export${_}{${_}${name === specifier.reexported16649 ? name16650 : `${name} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`} };`);16651 }16652 }16653 if (namedReexports.length > 0) {16654 importBlock.push(`export${_}{${_}${namedReexports16655 .map(specifier => specifier.imported === specifier.reexported16656 ? stringifyIdentifierIfNeeded(specifier.imported)16657 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`)16658 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`);16659 }16660 }16661 }16662 return importBlock;16663 }16664 function getExportBlock(exports, { _, cnst }) {16665 const exportBlock = [];16666 const exportDeclaration = [];16667 for (const specifier of exports) {16668 if (specifier.expression) {16669 exportBlock.push(`${cnst} ${specifier.local}${_}=${_}${specifier.expression};`);16670 }16671 exportDeclaration.push(specifier.exported === specifier.local16672 ? specifier.local16673 : `${specifier.local} as ${stringifyIdentifierIfNeeded(specifier.exported)}`);16674 }16675 if (exportDeclaration.length > 0) {16676 exportBlock.push(`export${_}{${_}${exportDeclaration.join(`,${_}`)}${_}};`);16677 }16678 return exportBlock;16679 }16680 16681 const keypath = (keypath, getPropertyAccess) => keypath.split('.').map(getPropertyAccess).join('');16682 16683 function setupNamespace(name, root, globals, { _, getPropertyAccess, s }, compact) {16684 const parts = name.split('.');16685 parts[0] = (typeof globals === 'function' ? globals(parts[0]) : globals[parts[0]]) || parts[0];16686 parts.pop();16687 let propertyPath = root;16688 return (parts16689 .map(part => {16690 propertyPath += getPropertyAccess(part);16691 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}${s}`;16692 })16693 .join(compact ? ',' : '\n') + (compact && parts.length > 0 ? ';' : '\n'));16694 }16695 function assignToDeepVariable(deepName, root, globals, assignment, { _, getPropertyAccess }) {16696 const parts = deepName.split('.');16697 parts[0] = (typeof globals === 'function' ? globals(parts[0]) : globals[parts[0]]) || parts[0];16698 const last = parts.pop();16699 let propertyPath = root;16700 let deepAssignment = [16701 ...parts.map(part => {16702 propertyPath += getPropertyAccess(part);16703 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}`;16704 }),16705 `${propertyPath}${getPropertyAccess(last)}`16706 ].join(`,${_}`) + `${_}=${_}${assignment}`;16707 if (parts.length > 0) {16708 deepAssignment = `(${deepAssignment})`;16709 }16710 return deepAssignment;16711 }16712 16713 function trimEmptyImports(dependencies) {16714 let index = dependencies.length;16715 while (index--) {16716 const { imports, reexports } = dependencies[index];16717 if (imports || reexports) {16718 return dependencies.slice(0, index + 1);16719 }16720 }16721 return [];16722 }16723 16724 function iife(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, indent: t, intro, namedExportsMode, log, outro, snippets }, { compact, esModule, extend, freeze, externalLiveBindings, reexportProtoFromExternal, globals, interop, name, generatedCode: { symbols }, strict }) {16725 const { _, getNonArrowFunctionIntro, getPropertyAccess, n } = snippets;16726 const isNamespaced = name && name.includes('.');16727 const useVariableAssignment = !extend && !isNamespaced;16728 if (name && useVariableAssignment && !isLegal(name)) {16729 return parseAst_js.error(parseAst_js.logIllegalIdentifierAsName(name));16730 }16731 warnOnBuiltins(log, dependencies);16732 const external = trimEmptyImports(dependencies);16733 const deps = external.map(dep => dep.globalName || 'null');16734 const parameters = external.map(m => m.name);16735 if (hasExports && !name) {16736 log(parseAst_js.LOGLEVEL_WARN, parseAst_js.logMissingNameOptionForIifeExport());16737 }16738 if (namedExportsMode && hasExports) {16739 if (extend) {16740 deps.unshift(`this${keypath(name, getPropertyAccess)}${_}=${_}this${keypath(name, getPropertyAccess)}${_}||${_}{}`);16741 parameters.unshift('exports');16742 }16743 else {16744 deps.unshift('{}');16745 parameters.unshift('exports');16746 }16747 }16748 const useStrict = strict ? `${t}'use strict';${n}` : '';16749 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets);16750 magicString.prepend(`${intro}${interopBlock}`);16751 let wrapperIntro = `(${getNonArrowFunctionIntro(parameters, {16752 isAsync: false,16753 name: null16754 })}{${n}${useStrict}${n}`;16755 if (hasExports) {16756 if (name && !(extend && namedExportsMode)) {16757 wrapperIntro =16758 (useVariableAssignment ? `var ${name}` : `this${keypath(name, getPropertyAccess)}`) +16759 `${_}=${_}${wrapperIntro}`;16760 }16761 if (isNamespaced) {16762 wrapperIntro = setupNamespace(name, 'this', globals, snippets, compact) + wrapperIntro;16763 }16764 }16765 let wrapperOutro = `${n}${n}})(${deps.join(`,${_}`)});`;16766 if (hasExports && !extend && namedExportsMode) {16767 wrapperOutro = `${n}${n}${t}return exports;${wrapperOutro}`;16768 }16769 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);16770 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets);16771 if (namespaceMarkers) {16772 namespaceMarkers = n + n + namespaceMarkers;16773 }16774 magicString16775 .append(`${exportBlock}${namespaceMarkers}${outro}`)16776 .indent(t)16777 .prepend(wrapperIntro)16778 .append(wrapperOutro);16779 }16780 16781 function system(magicString, { accessedGlobals, dependencies, exports, hasExports, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) {16782 const { _, getFunctionIntro, getNonArrowFunctionIntro, n, s } = snippets;16783 const { importBindings, setters, starExcludes } = analyzeDependencies(dependencies, exports, t, snippets);16784 const registeredName = name ? `'${name}',${_}` : '';16785 const wrapperParameters = accessedGlobals.has('module')16786 ? ['exports', 'module']16787 : hasExports16788 ? ['exports']16789 : [];16790 // factory function should be wrapped by parentheses to avoid lazy parsing,16791 // cf. https://v8.dev/blog/preparser#pife16792 let wrapperStart = `System.register(${registeredName}[` +16793 dependencies.map(({ importPath }) => `'${importPath}'`).join(`,${_}`) +16794 `],${_}(${getNonArrowFunctionIntro(wrapperParameters, {16795 isAsync: false,16796 name: null16797 })}{${n}${t}${strict ? "'use strict';" : ''}` +16798 getStarExcludesBlock(starExcludes, t, snippets) +16799 getImportBindingsBlock(importBindings, t, snippets) +16800 `${n}${t}return${_}{${setters.length > 016801 ? `${n}${t}${t}setters:${_}[${setters16802 .map(setter => setter16803 ? `${getFunctionIntro(['module'], {16804 isAsync: false,16805 name: null16806 })}{${n}${t}${t}${t}${setter}${n}${t}${t}}`16807 : systemNullSetters16808 ? `null`16809 : `${getFunctionIntro([], { isAsync: false, name: null })}{}`)16810 .join(`,${_}`)}],`16811 : ''}${n}`;16812 wrapperStart += `${t}${t}execute:${_}(${getNonArrowFunctionIntro([], {16813 isAsync: usesTopLevelAwait,16814 name: null16815 })}{${n}${n}`;16816 const wrapperEnd = `${t}${t}})${n}${t}}${s}${n}}));`;16817 magicString16818 .prepend(intro +16819 getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols) +16820 getHoistedExportsBlock(exports, t, snippets))16821 .append(`${outro}${n}${n}` +16822 getSyntheticExportsBlock(exports, t, snippets) +16823 getMissingExportsBlock(exports, t, snippets))16824 .indent(`${t}${t}${t}`)16825 .append(wrapperEnd)16826 .prepend(wrapperStart);16827 }16828 function analyzeDependencies(dependencies, exports, t, { _, cnst, getObject, getPropertyAccess, n }) {16829 const importBindings = [];16830 const setters = [];16831 let starExcludes = null;16832 for (const { imports, reexports } of dependencies) {16833 const setter = [];16834 if (imports) {16835 for (const specifier of imports) {16836 importBindings.push(specifier.local);16837 if (specifier.imported === '*') {16838 setter.push(`${specifier.local}${_}=${_}module;`);16839 }16840 else {16841 setter.push(`${specifier.local}${_}=${_}module${getPropertyAccess(specifier.imported)};`);16842 }16843 }16844 }16845 if (reexports) {16846 const reexportedNames = [];16847 let hasStarReexport = false;16848 for (const { imported, reexported } of reexports) {16849 if (reexported === '*') {16850 hasStarReexport = true;16851 }16852 else {16853 reexportedNames.push([16854 reexported,16855 imported === '*' ? 'module' : `module${getPropertyAccess(imported)}`16856 ]);16857 }16858 }16859 if (reexportedNames.length > 1 || hasStarReexport) {16860 if (hasStarReexport) {16861 if (!starExcludes) {16862 starExcludes = getStarExcludes({ dependencies, exports });16863 }16864 reexportedNames.unshift([null, `__proto__:${_}null`]);16865 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null });16866 setter.push(`${cnst} setter${_}=${_}${exportMapping};`, `for${_}(${cnst} name in module)${_}{`, `${t}if${_}(!_starExcludes[name])${_}setter[name]${_}=${_}module[name];`, '}', 'exports(setter);');16867 }16868 else {16869 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null });16870 setter.push(`exports(${exportMapping});`);16871 }16872 }16873 else {16874 const [key, value] = reexportedNames[0];16875 setter.push(`exports(${JSON.stringify(key)},${_}${value});`);16876 }16877 }16878 setters.push(setter.join(`${n}${t}${t}${t}`));16879 }16880 return { importBindings, setters, starExcludes };16881 }16882 const getStarExcludes = ({ dependencies, exports }) => {16883 const starExcludes = new Set(exports.map(expt => expt.exported));16884 starExcludes.add('default');16885 for (const { reexports } of dependencies) {16886 if (reexports) {16887 for (const reexport of reexports) {16888 if (reexport.reexported !== '*')16889 starExcludes.add(reexport.reexported);16890 }16891 }16892 }16893 return starExcludes;16894 };16895 const getStarExcludesBlock = (starExcludes, t, { _, cnst, getObject, n }) => {16896 if (starExcludes) {16897 const fields = [...starExcludes].map(property => [16898 property,16899 '1'16900 ]);16901 fields.unshift([null, `__proto__:${_}null`]);16902 return `${n}${t}${cnst} _starExcludes${_}=${_}${getObject(fields, {16903 lineBreakIndent: { base: t, t }16904 })};`;16905 }16906 return '';16907 };16908 const getImportBindingsBlock = (importBindings, t, { _, n }) => (importBindings.length > 0 ? `${n}${t}var ${importBindings.join(`,${_}`)};` : '');16909 const getHoistedExportsBlock = (exports, t, snippets) => getExportsBlock(exports.filter(expt => expt.hoisted).map(expt => ({ name: expt.exported, value: expt.local })), t, snippets);16910 function getExportsBlock(exports, t, { _, n }) {16911 if (exports.length === 0) {16912 return '';16913 }16914 if (exports.length === 1) {16915 return `exports(${JSON.stringify(exports[0].name)},${_}${exports[0].value});${n}${n}`;16916 }16917 return (`exports({${n}` +16918 exports16919 .map(({ name, value }) => `${t}${stringifyObjectKeyIfNeeded(name)}:${_}${value}`)16920 .join(`,${n}`) +16921 `${n}});${n}${n}`);16922 }16923 const getSyntheticExportsBlock = (exports, t, snippets) => getExportsBlock(exports16924 .filter(expt => expt.expression)16925 .map(expt => ({ name: expt.exported, value: expt.local })), t, snippets);16926 const getMissingExportsBlock = (exports, t, snippets) => getExportsBlock(exports16927 .filter(expt => expt.local === MISSING_EXPORT_SHIM_VARIABLE)16928 .map(expt => ({ name: expt.exported, value: MISSING_EXPORT_SHIM_VARIABLE })), t, snippets);16929 16930 function globalProperty(name, globalVariable, getPropertyAccess) {16931 if (!name)16932 return 'null';16933 return `${globalVariable}${keypath(name, getPropertyAccess)}`;16934 }16935 function safeAccess(name, globalVariable, { _, getPropertyAccess }) {16936 let propertyPath = globalVariable;16937 return name16938 .split('.')16939 .map(part => (propertyPath += getPropertyAccess(part)))16940 .join(`${_}&&${_}`);16941 }16942 function umd(magicString, { accessedGlobals, dependencies, exports, hasDefaultExport, hasExports, id, indent: t, intro, namedExportsMode, log, outro, snippets }, { amd, compact, esModule, extend, externalLiveBindings, freeze, interop, name, generatedCode: { symbols }, globals, noConflict, reexportProtoFromExternal, strict }) {16943 const { _, cnst, getFunctionIntro, getNonArrowFunctionIntro, getPropertyAccess, n, s } = snippets;16944 const factoryVariable = compact ? 'f' : 'factory';16945 const globalVariable = compact ? 'g' : 'global';16946 if (hasExports && !name) {16947 return parseAst_js.error(parseAst_js.logMissingNameOptionForUmdExport());16948 }16949 warnOnBuiltins(log, dependencies);16950 const amdDeps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`);16951 const cjsDeps = dependencies.map(m => `require('${m.importPath}')`);16952 const trimmedImports = trimEmptyImports(dependencies);16953 const globalDeps = trimmedImports.map(module => globalProperty(module.globalName, globalVariable, getPropertyAccess));16954 const factoryParameters = trimmedImports.map(m => m.name);16955 if (namedExportsMode && (hasExports || noConflict)) {16956 amdDeps.unshift(`'exports'`);16957 cjsDeps.unshift(`exports`);16958 globalDeps.unshift(assignToDeepVariable(name, globalVariable, globals, `${extend ? `${globalProperty(name, globalVariable, getPropertyAccess)}${_}||${_}` : ''}{}`, snippets));16959 factoryParameters.unshift('exports');16960 }16961 const completeAmdId = getCompleteAmdId(amd, id);16962 const amdParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) +16963 (amdDeps.length > 0 ? `[${amdDeps.join(`,${_}`)}],${_}` : ``);16964 const define = amd.define;16965 const cjsExport = !namedExportsMode && hasExports ? `module.exports${_}=${_}` : ``;16966 const useStrict = strict ? `${_}'use strict';${n}` : ``;16967 let iifeExport;16968 if (noConflict) {16969 const noConflictExportsVariable = compact ? 'e' : 'exports';16970 let factory;16971 if (!namedExportsMode && hasExports) {16972 factory = `${cnst} ${noConflictExportsVariable}${_}=${_}${assignToDeepVariable(name, globalVariable, globals, `${factoryVariable}(${globalDeps.join(`,${_}`)})`, snippets)};`;16973 }16974 else {16975 const module = globalDeps.shift();16976 factory =16977 `${cnst} ${noConflictExportsVariable}${_}=${_}${module};${n}` +16978 `${t}${t}${factoryVariable}(${[noConflictExportsVariable, ...globalDeps].join(`,${_}`)});`;16979 }16980 iifeExport =16981 `(${getFunctionIntro([], { isAsync: false, name: null })}{${n}` +16982 `${t}${t}${cnst} current${_}=${_}${safeAccess(name, globalVariable, snippets)};${n}` +16983 `${t}${t}${factory}${n}` +16984 `${t}${t}${noConflictExportsVariable}.noConflict${_}=${_}${getFunctionIntro([], {16985 isAsync: false,16986 name: null16987 })}{${_}` +16988 `${globalProperty(name, globalVariable, getPropertyAccess)}${_}=${_}current;${_}return ${noConflictExportsVariable}${s}${_}};${n}` +16989 `${t}})()`;16990 }16991 else {16992 iifeExport = `${factoryVariable}(${globalDeps.join(`,${_}`)})`;16993 if (!namedExportsMode && hasExports) {16994 iifeExport = assignToDeepVariable(name, globalVariable, globals, iifeExport, snippets);16995 }16996 }16997 const iifeNeedsGlobal = hasExports || (noConflict && namedExportsMode) || globalDeps.length > 0;16998 const wrapperParameters = [factoryVariable];16999 if (iifeNeedsGlobal) {17000 wrapperParameters.unshift(globalVariable);17001 }17002 const globalArgument = iifeNeedsGlobal ? `this,${_}` : '';17003 const iifeStart = iifeNeedsGlobal17004 ? `(${globalVariable}${_}=${_}typeof globalThis${_}!==${_}'undefined'${_}?${_}globalThis${_}:${_}${globalVariable}${_}||${_}self,${_}`17005 : '';17006 const iifeEnd = iifeNeedsGlobal ? ')' : '';17007 const cjsIntro = iifeNeedsGlobal17008 ? `${t}typeof exports${_}===${_}'object'${_}&&${_}typeof module${_}!==${_}'undefined'${_}?` +17009 `${_}${cjsExport}${factoryVariable}(${cjsDeps.join(`,${_}`)})${_}:${n}`17010 : '';17011 const wrapperIntro = `(${getNonArrowFunctionIntro(wrapperParameters, { isAsync: false, name: null })}{${n}` +17012 cjsIntro +17013 `${t}typeof ${define}${_}===${_}'function'${_}&&${_}${define}.amd${_}?${_}${define}(${amdParameters}${factoryVariable})${_}:${n}` +17014 `${t}${iifeStart}${iifeExport}${iifeEnd};${n}` +17015 // factory function should be wrapped by parentheses to avoid lazy parsing,17016 // cf. https://v8.dev/blog/preparser#pife17017 `})(${globalArgument}(${getNonArrowFunctionIntro(factoryParameters, {17018 isAsync: false,17019 name: null17020 })}{${useStrict}${n}`;17021 const wrapperOutro = n + n + '}));';17022 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`);17023 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);17024 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets);17025 if (namespaceMarkers) {17026 namespaceMarkers = n + n + namespaceMarkers;17027 }17028 magicString17029 .append(`${exportBlock}${namespaceMarkers}${outro}`)17030 .trim()17031 .indent(t)17032 .append(wrapperOutro)17033 .prepend(wrapperIntro);17034 }17035 17036 const finalisers = { amd, cjs, es, iife, system, umd };17037 17933 17038 17934 const concatSeparator = (out, next) => (next ? `${out}\n${next}` : out); … … 17502 18398 } 17503 18399 for (const module of entryModules) { 17504 // eslint-disable-next-line unicorn/prefer-spread17505 18400 const requiredFacades = Array.from(new Set(module.chunkNames.filter(({ isUserDefined }) => isUserDefined).map(({ name }) => name)), 17506 18401 // mapping must run after Set 'name' dedupe … … 17511 18406 requiredFacades.push({}); 17512 18407 } 17513 // eslint-disable-next-line unicorn/prefer-spread17514 18408 requiredFacades.push(...Array.from(module.chunkFileNames, fileName => ({ fileName }))); 17515 18409 if (requiredFacades.length === 0) { … … 17578 18472 const { chunkFileNames, entryFileNames, file, format, preserveModules } = this.outputOptions; 17579 18473 if (file) { 17580 fileName = path $2.basename(file);18474 fileName = path.basename(file); 17581 18475 } 17582 18476 else if (this.fileName === null) { … … 17636 18530 dynamicImports: this.getDynamicDependencies().map(resolveFileName), 17637 18531 fileName: this.getFileName(), 17638 // eslint-disable-next-line unicorn/prefer-spread17639 18532 implicitlyLoadedBefore: Array.from(this.implicitlyLoadedBefore, resolveFileName), 17640 18533 importedBindings: getImportedBindingsPerDependency(this.getRenderedDependencies(), resolveFileName), 17641 // eslint-disable-next-line unicorn/prefer-spread17642 18534 imports: Array.from(this.dependencies, resolveFileName), 17643 18535 modules: this.renderedModules, … … 17684 18576 } 17685 18577 if (format === 'es') { 17686 renderedDependency.reexports = reexports.filter( 17687 // eslint-disable-next-line unicorn/prefer-array-some 17688 ({ reexported }) => !renderedExports.find(({ exported }) => exported === reexported)); 18578 renderedDependency.reexports = reexports.filter(({ reexported }) => !renderedExports.find(({ exported }) => exported === reexported)); 17689 18579 } 17690 18580 } … … 17720 18610 if (format === 'es' || format === 'cjs') { 17721 18611 const shebang = facadeModule !== null && facadeModule.info.isEntry && facadeModule.shebang; 17722 shebang && magicString.prepend(`#!${shebang}\n`); 18612 if (shebang) { 18613 magicString.prepend(`#!${shebang}\n`); 18614 } 17723 18615 } 17724 18616 if (footer) … … 18031 18923 const { preserveModulesRoot, sanitizeFileName } = this.outputOptions; 18032 18924 const sanitizedId = sanitizeFileName(parseAst_js.normalize(module.id.split(QUERY_HASH_REGEX, 1)[0])); 18033 const extensionName = path $2.extname(sanitizedId);18925 const extensionName = path.extname(sanitizedId); 18034 18926 const idWithoutExtension = NON_ASSET_EXTENSIONS.has(extensionName) 18035 18927 ? sanitizedId.slice(0, -extensionName.length) 18036 18928 : sanitizedId; 18037 18929 if (parseAst_js.isAbsolute(idWithoutExtension)) { 18038 return preserveModulesRoot && path$2.resolve(idWithoutExtension).startsWith(preserveModulesRoot) 18039 ? idWithoutExtension.slice(preserveModulesRoot.length).replace(/^[/\\]/, '') 18040 : parseAst_js.relative(this.inputBase, idWithoutExtension); 18930 if (preserveModulesRoot && path.resolve(idWithoutExtension).startsWith(preserveModulesRoot)) { 18931 return idWithoutExtension.slice(preserveModulesRoot.length).replace(/^[/\\]/, ''); 18932 } 18933 else { 18934 // handle edge case in Windows 18935 if (this.inputBase === '/' && !idWithoutExtension.startsWith('/')) { 18936 return parseAst_js.relative(this.inputBase, idWithoutExtension.replace(/^[a-zA-Z]:[/\\]/, '/')); 18937 } 18938 return parseAst_js.relative(this.inputBase, idWithoutExtension); 18939 } 18041 18940 } 18042 18941 else { 18043 return `_virtual/${path$2.basename(idWithoutExtension)}`;18942 return (this.outputOptions.virtualDirname.replace(/\/$/, '') + '/' + path.basename(idWithoutExtension)); 18044 18943 } 18045 18944 } … … 18178 19077 if (!renderOptions.accessedDocumentCurrentScript && 18179 19078 formatsMaybeAccessDocumentCurrentScript.includes(format)) { 18180 // eslint-disable-next-line unicorn/consistent-destructuring18181 19079 this.accessedGlobalsByScope.get(module.scope)?.delete(DOCUMENT_CURRENT_SCRIPT); 18182 19080 } … … 18220 19118 if (hoistedSource) 18221 19119 magicString.prepend(hoistedSource + n + n); 18222 // eslint-disable-next-line unicorn/consistent-destructuring18223 19120 if (this.needsExportsShim) { 18224 19121 magicString.prepend(`${n}${cnst} ${MISSING_EXPORT_SHIM_VARIABLE}${_}=${_}void 0;${n}${n}`); … … 18528 19425 } 18529 19426 function getChunkDefinitionsFromManualChunks(manualChunkAliasByEntry) { 18530 const chunkDefinitions = [];18531 19427 const modulesInManualChunks = new Set(manualChunkAliasByEntry.keys()); 18532 19428 const manualChunkModulesByAlias = Object.create(null); … … 18534 19430 addStaticDependenciesToManualChunk(entry, (manualChunkModulesByAlias[alias] ||= []), modulesInManualChunks); 18535 19431 } 18536 for (const [alias, modules] of Object.entries(manualChunkModulesByAlias)) { 18537 chunkDefinitions.push({ alias, modules }); 19432 const manualChunks = Object.entries(manualChunkModulesByAlias); 19433 const chunkDefinitions = new Array(manualChunks.length); 19434 let index = 0; 19435 for (const [alias, modules] of manualChunks) { 19436 chunkDefinitions[index++] = { alias, modules }; 18538 19437 } 18539 19438 return { chunkDefinitions, modulesInManualChunks }; … … 18554 19453 const dynamicEntryModules = new Set(); 18555 19454 const dependentEntriesByModule = new Map(); 18556 const dynamicImportModulesByEntry = [];18557 19455 const allEntriesSet = new Set(entries); 19456 const dynamicImportModulesByEntry = new Array(allEntriesSet.size); 18558 19457 let entryIndex = 0; 18559 19458 for (const currentEntry of allEntriesSet) { 18560 19459 const dynamicImportsForCurrentEntry = new Set(); 18561 dynamicImportModulesByEntry .push(dynamicImportsForCurrentEntry);19460 dynamicImportModulesByEntry[entryIndex] = dynamicImportsForCurrentEntry; 18562 19461 const modulesToHandle = new Set([currentEntry]); 18563 19462 for (const module of modulesToHandle) { … … 18604 19503 } 18605 19504 } 18606 const dynamicImportsByEntry = []; 19505 const dynamicImportsByEntry = new Array(dynamicImportModulesByEntry.length); 19506 let index = 0; 18607 19507 for (const dynamicImportModules of dynamicImportModulesByEntry) { 18608 19508 const dynamicImports = new Set(); … … 18610 19510 dynamicImports.add(entryIndexByModule.get(dynamicEntry)); 18611 19511 } 18612 dynamicImportsByEntry .push(dynamicImports);19512 dynamicImportsByEntry[index++] = dynamicImports; 18613 19513 } 18614 19514 return { dynamicEntries, dynamicImportsByEntry }; … … 18715 19615 const chunksBySignature = Object.create(null); 18716 19616 const chunkByModule = new Map(); 18717 const sizeByAtom = [];19617 const sizeByAtom = new Array(chunkAtoms.length); 18718 19618 let sideEffectAtoms = 0n; 18719 19619 let atomMask = 1n; 19620 let index = 0; 18720 19621 for (const { dependentEntries, modules } of chunkAtoms) { 18721 19622 let chunkSignature = 0n; … … 18755 19656 sideEffectAtoms |= atomMask; 18756 19657 } 18757 sizeByAtom .push(atomSize);19658 sizeByAtom[index++] = atomSize; 18758 19659 chunk.containedAtoms |= atomMask; 18759 19660 chunk.modules.push(...modules); … … 18880 19781 return chunks; // the actual modules 18881 19782 } 18882 minChunkSize > 1 &&19783 if (minChunkSize > 1) { 18883 19784 log('info', parseAst_js.logOptimizeChunkStatus(chunks.length, chunkPartition.small.size, 'Initially')); 19785 } 18884 19786 mergeChunks(chunkPartition, minChunkSize, sideEffectAtoms, sizeByAtom); 18885 minChunkSize > 1 &&19787 if (minChunkSize > 1) { 18886 19788 log('info', parseAst_js.logOptimizeChunkStatus(chunkPartition.small.size + chunkPartition.big.size, chunkPartition.small.size, 'After merging chunks')); 19789 } 18887 19790 timeEnd('optimize chunks', 3); 18888 19791 return [...chunkPartition.small, ...chunkPartition.big]; … … 19024 19927 return '/'; 19025 19928 if (files.length === 1) 19026 return path $2.dirname(files[0]);19929 return path.dirname(files[0]); 19027 19930 const commonSegments = files.slice(1).reduce((commonSegments, file) => { 19028 19931 const pathSegments = file.split(/\/+|\\+/); … … 19282 20185 const sources = originalSourcemap.sources; 19283 20186 const sourcesContent = originalSourcemap.sourcesContent || []; 19284 const directory = path $2.dirname(id) || '.';20187 const directory = path.dirname(id) || '.'; 19285 20188 const sourceRoot = originalSourcemap.sourceRoot || '.'; 19286 const baseSources = sources.map((source, index) => new Source(path $2.resolve(directory, sourceRoot, source), sourcesContent[index]));20189 const baseSources = sources.map((source, index) => new Source(path.resolve(directory, sourceRoot, source), sourcesContent[index])); 19287 20190 source = new Link(originalSourcemap, baseSources); 19288 20191 } … … 19301 20204 let { sources, sourcesContent, names, mappings } = source.traceMappings(); 19302 20205 if (file) { 19303 const directory = path $2.dirname(file);19304 sources = sources.map((source) => path $2.relative(directory, source));19305 file = path $2.basename(file);20206 const directory = path.dirname(file); 20207 sources = sources.map((source) => path.relative(directory, source)); 20208 file = path.basename(file); 19306 20209 } 19307 20210 sourcesContent = (excludeContent ? null : sourcesContent); … … 19333 20236 const getHash = hasherByType[outputOptions.hashCharacters]; 19334 20237 const chunkGraph = getChunkGraph(chunks); 19335 const { initialHashesByPlaceholder, nonHashedChunksWithPlaceholders, renderedChunksByPlaceholder, hashDependenciesByPlaceholder } = await transformChunksAndGenerateContentHashes(renderedChunks, chunkGraph, outputOptions, pluginDriver, getHash, log);19336 const hashesByPlaceholder = generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, bundle, getHash);20238 const { hashDependenciesByPlaceholder, initialHashesByPlaceholder, nonHashedChunksWithPlaceholders, placeholders, renderedChunksByPlaceholder } = await transformChunksAndGenerateContentHashes(renderedChunks, chunkGraph, outputOptions, pluginDriver, getHash, log); 20239 const hashesByPlaceholder = generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, placeholders, bundle, getHash); 19337 20240 addChunksToBundle(renderedChunksByPlaceholder, hashesByPlaceholder, bundle, nonHashedChunksWithPlaceholders, pluginDriver, outputOptions); 19338 20241 timeEnd('transform chunks', 2); … … 19377 20280 let resultingFile; 19378 20281 if (file) 19379 resultingFile = path $2.resolve(sourcemapFile || file);20282 resultingFile = path.resolve(sourcemapFile || file); 19380 20283 else if (dir) 19381 resultingFile = path $2.resolve(dir, fileName);20284 resultingFile = path.resolve(dir, fileName); 19382 20285 else 19383 resultingFile = path $2.resolve(fileName);20286 resultingFile = path.resolve(fileName); 19384 20287 const decodedMap = magicString.generateDecodedMap({}); 19385 20288 map = collapseSourcemaps(resultingFile, decodedMap, usedModules, sourcemapChain, sourcemapExcludeSources, log); … … 19464 20367 initialHashesByPlaceholder, 19465 20368 nonHashedChunksWithPlaceholders, 20369 placeholders, 19466 20370 renderedChunksByPlaceholder 19467 20371 }; 19468 20372 } 19469 function generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, bundle, getHash) {20373 function generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, placeholders, bundle, getHash) { 19470 20374 const hashesByPlaceholder = new Map(initialHashesByPlaceholder); 19471 for (const [placeholder, { fileName }] of renderedChunksByPlaceholder) { 20375 for (const placeholder of placeholders) { 20376 const { fileName } = renderedChunksByPlaceholder.get(placeholder); 19472 20377 let contentToHash = ''; 19473 20378 const hashDependencyPlaceholders = new Set([placeholder]); … … 19501 20406 let finalSourcemapFileName = null; 19502 20407 if (map) { 20408 if (options.sourcemapDebugIds) { 20409 updatedCode += calculateDebugIdAndGetComment(updatedCode, map); 20410 } 19503 20411 finalSourcemapFileName = sourcemapFileName 19504 20412 ? replacePlaceholders(sourcemapFileName, hashesByPlaceholder) … … 19513 20421 let finalSourcemapFileName = null; 19514 20422 if (map) { 20423 if (options.sourcemapDebugIds) { 20424 updatedCode += calculateDebugIdAndGetComment(updatedCode, map); 20425 } 19515 20426 finalSourcemapFileName = sourcemapFileName 19516 20427 ? replacePlaceholders(sourcemapFileName, hashesByPlaceholder) … … 19527 20438 } 19528 20439 else { 19529 const sourcemapFileName = path $2.basename(fileName);20440 const sourcemapFileName = path.basename(fileName); 19530 20441 url = sourcemapBaseUrl 19531 20442 ? new URL(sourcemapFileName, sourcemapBaseUrl).toString() … … 19539 20450 } 19540 20451 return sourcemap === 'hidden' ? '' : `//# ${SOURCEMAPPING_URL}=${url}\n`; 20452 } 20453 function calculateDebugIdAndGetComment(code, map) { 20454 const hash = hasherByType.hex(code); 20455 const debugId = [ 20456 hash.slice(0, 8), 20457 hash.slice(8, 12), 20458 '4' + hash.slice(12, 15), 20459 ((parseInt(hash.slice(15, 16), 16) & 3) | 8).toString(16) + hash.slice(17, 20), 20460 hash.slice(20, 32) 20461 ].join('-'); 20462 map.debugId = debugId; 20463 return '//# debugId=' + debugId + '\n'; 19541 20464 } 19542 20465 … … 19603 20526 } 19604 20527 assignManualChunks(getManualChunk) { 19605 // eslint-disable-next-line unicorn/prefer-module19606 20528 const manualChunkAliasesWithEntry = []; 19607 20529 const manualChunksApi = { … … 19629 20551 if ('code' in file) { 19630 20552 try { 19631 parseAst_js.parseAst(file.code );20553 parseAst_js.parseAst(file.code, { jsx: this.inputOptions.jsx !== false }); 19632 20554 } 19633 20555 catch (error_) { … … 19648 20570 const inputBase = commondir(getAbsoluteEntryModulePaths(includedModules, preserveModules)); 19649 20571 const externalChunkByModule = getExternalChunkByModule(this.graph.modulesById, this.outputOptions, inputBase); 19650 const chunks = []; 19651 const chunkByModule = new Map(); 19652 for (const { alias, modules } of inlineDynamicImports 20572 const executableModule = inlineDynamicImports 19653 20573 ? [{ alias: null, modules: includedModules }] 19654 20574 : preserveModules 19655 20575 ? includedModules.map(module => ({ alias: null, modules: [module] })) 19656 : getChunkAssignments(this.graph.entryModules, manualChunkAliasByEntry, experimentalMinChunkSize, this.inputOptions.onLog)) { 20576 : getChunkAssignments(this.graph.entryModules, manualChunkAliasByEntry, experimentalMinChunkSize, this.inputOptions.onLog); 20577 const chunks = new Array(executableModule.length); 20578 const chunkByModule = new Map(); 20579 let index = 0; 20580 for (const { alias, modules } of executableModule) { 19657 20581 sortByExecutionOrder(modules); 19658 20582 const chunk = new Chunk(modules, this.inputOptions, this.outputOptions, this.unsetOptions, this.pluginDriver, this.graph.modulesById, chunkByModule, externalChunkByModule, this.facadeChunkByModule, this.includedNamespaces, alias, getHashPlaceholder, bundle, inputBase, snippets); 19659 chunks .push(chunk);20583 chunks[index++] = chunk; 19660 20584 } 19661 20585 for (const chunk of chunks) { … … 19759 20683 } 19760 20684 20685 class GlobalScope extends Scope { 20686 constructor() { 20687 super(); 20688 this.parent = null; 20689 this.variables.set('undefined', new UndefinedVariable()); 20690 } 20691 findVariable(name) { 20692 let variable = this.variables.get(name); 20693 if (!variable) { 20694 variable = new GlobalVariable(name); 20695 this.variables.set(name, variable); 20696 } 20697 return variable; 20698 } 20699 } 20700 19761 20701 function resolveIdViaPlugins(source, importer, pluginDriver, moduleLoaderResolveId, skip, customOptions, isEntry, attributes) { 19762 20702 let skipped = null; … … 19806 20746 // resolve call and require no special handing on our part. 19807 20747 // See https://nodejs.org/api/path.html#path_path_resolve_paths 19808 return addJsExtensionIfNecessary(importer ? path $2.resolve(path$2.dirname(importer), source) : path$2.resolve(source), preserveSymlinks);20748 return addJsExtensionIfNecessary(importer ? path.resolve(path.dirname(importer), source) : path.resolve(source), preserveSymlinks); 19809 20749 } 19810 20750 async function addJsExtensionIfNecessary(file, preserveSymlinks) { … … 19820 20760 if ((preserveSymlinks && stats.isSymbolicLink()) || stats.isFile()) { 19821 20761 // check case 19822 const name = path $2.basename(file);19823 const files = await promises.readdir(path $2.dirname(file));20762 const name = path.basename(file); 20763 const files = await promises.readdir(path.dirname(file)); 19824 20764 if (files.includes(name)) 19825 20765 return file; … … 20264 21204 } 20265 21205 getResolveStaticDependencyPromises(module) { 20266 // eslint-disable-next-line unicorn/prefer-spread20267 21206 return Array.from(module.sourcesWithAttributes, async ([source, attributes]) => [ 20268 21207 source, … … 20377 21316 return parseAst_js.isRelative(source) 20378 21317 ? importer 20379 ? path $2.resolve(importer, '..', source)20380 : path $2.resolve(source)21318 ? path.resolve(importer, '..', source) 21319 : path.resolve(source) 20381 21320 : source; 20382 21321 } … … 20401 21340 const [resolveStaticDependencyPromises, resolveDynamicImportPromises] = await loadPromise; 20402 21341 return Promise.all([...resolveStaticDependencyPromises, ...resolveDynamicImportPromises]); 20403 }20404 20405 class GlobalScope extends Scope {20406 constructor() {20407 super();20408 this.parent = null;20409 this.variables.set('undefined', new UndefinedVariable());20410 }20411 findVariable(name) {20412 let variable = this.variables.get(name);20413 if (!variable) {20414 variable = new GlobalVariable(name);20415 this.variables.set(name, variable);20416 }20417 return variable;20418 }20419 21342 } 20420 21343 … … 20575 21498 for (const module of this.modules) { 20576 21499 if (module.isExecuted) { 21500 module.hasTreeShakingPassStarted = true; 20577 21501 if (module.info.moduleSideEffects === 'no-treeshake') { 20578 21502 module.includeAllInBundle(); … … 20704 21628 external: getIdMatcher(config.external), 20705 21629 input: getInput(config), 21630 jsx: getJsx(config), 20706 21631 logLevel, 20707 21632 makeAbsoluteExternalsRelative: config.makeAbsoluteExternalsRelative ?? 'ifRelativeSource', … … 20749 21674 return configInput == null ? [] : typeof configInput === 'string' ? [configInput] : configInput; 20750 21675 }; 21676 const getJsx = (config) => { 21677 const configJsx = config.jsx; 21678 if (!configJsx) 21679 return false; 21680 const configWithPreset = getOptionWithPreset(configJsx, jsxPresets, 'jsx', parseAst_js.URL_JSX, 'false, '); 21681 const { factory, importSource, mode } = configWithPreset; 21682 switch (mode) { 21683 case 'automatic': { 21684 return { 21685 factory: factory || 'React.createElement', 21686 importSource: importSource || 'react', 21687 jsxImportSource: configWithPreset.jsxImportSource || 'react/jsx-runtime', 21688 mode: 'automatic' 21689 }; 21690 } 21691 case 'preserve': { 21692 if (importSource && !(factory || configWithPreset.fragment)) { 21693 parseAst_js.error(parseAst_js.logInvalidOption('jsx', parseAst_js.URL_JSX, 'when preserving JSX and specifying an importSource, you also need to specify a factory or fragment')); 21694 } 21695 return { 21696 factory: factory || null, 21697 fragment: configWithPreset.fragment || null, 21698 importSource: importSource || null, 21699 mode: 'preserve' 21700 }; 21701 } 21702 // case 'classic': 21703 default: { 21704 if (mode && mode !== 'classic') { 21705 parseAst_js.error(parseAst_js.logInvalidOption('jsx.mode', parseAst_js.URL_JSX, 'mode must be "automatic", "classic" or "preserve"', mode)); 21706 } 21707 return { 21708 factory: factory || 'React.createElement', 21709 fragment: configWithPreset.fragment || 'React.Fragment', 21710 importSource: importSource || null, 21711 mode: 'classic' 21712 }; 21713 } 21714 } 21715 }; 20751 21716 const getMaxParallelFileOps = (config) => { 20752 21717 const maxParallelFileOps = config.maxParallelFileOps; … … 20766 21731 const contextByModuleId = Object.create(null); 20767 21732 for (const [key, moduleContext] of Object.entries(configModuleContext)) { 20768 contextByModuleId[path $2.resolve(key)] = moduleContext;21733 contextByModuleId[path.resolve(key)] = moduleContext; 20769 21734 } 20770 21735 return id => contextByModuleId[id] ?? context; … … 20879 21844 sourcemap: config.sourcemap || false, 20880 21845 sourcemapBaseUrl: getSourcemapBaseUrl(config), 21846 sourcemapDebugIds: config.sourcemapDebugIds || false, 20881 21847 sourcemapExcludeSources: config.sourcemapExcludeSources || false, 20882 21848 sourcemapFile: config.sourcemapFile, … … 20890 21856 strict: config.strict ?? true, 20891 21857 systemNullSetters: config.systemNullSetters ?? true, 20892 validate: config.validate || false 21858 validate: config.validate || false, 21859 virtualDirname: config.virtualDirname || '_virtual' 20893 21860 }; 20894 21861 warnUnknownOptions(config, Object.keys(outputOptions), 'output options', inputOptions.onLog); … … 20958 21925 return undefined; 20959 21926 } 20960 return path $2.resolve(preserveModulesRoot);21927 return path.resolve(preserveModulesRoot); 20961 21928 }; 20962 21929 const getAmd = (config) => { … … 20995 21962 return () => configAddon || ''; 20996 21963 }; 20997 // eslint-disable-next-line unicorn/prevent-abbreviations20998 21964 const getDir = (config, file) => { 20999 21965 const { dir } = config; … … 21065 22031 const validateInterop = (interop) => { 21066 22032 if (!ALLOWED_INTEROP_TYPES.has(interop)) { 21067 return parseAst_js.error(parseAst_js.logInvalidOption('output.interop', parseAst_js.URL_OUTPUT_INTEROP, 21068 // eslint-disable-next-line unicorn/prefer-spread 21069 `use one of ${Array.from(ALLOWED_INTEROP_TYPES, value => JSON.stringify(value)).join(', ')}`, interop)); 22033 return parseAst_js.error(parseAst_js.logInvalidOption('output.interop', parseAst_js.URL_OUTPUT_INTEROP, `use one of ${Array.from(ALLOWED_INTEROP_TYPES, value => JSON.stringify(value)).join(', ')}`, interop)); 21070 22034 } 21071 22035 return interop; … … 21101 22065 }; 21102 22066 22067 // @ts-expect-error TS2540: the polyfill of `asyncDispose`. 22068 Symbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); 21103 22069 function rollup(rawInputOptions) { 21104 22070 return rollupInternal(rawInputOptions, null); … … 21144 22110 }, 21145 22111 closed: false, 22112 async [Symbol.asyncDispose]() { 22113 await this.close(); 22114 }, 21146 22115 async generate(rawOutputOptions) { 21147 22116 if (result.closed) … … 21258 22227 } 21259 22228 async function writeOutputFile(outputFile, outputOptions) { 21260 const fileName = path $2.resolve(outputOptions.dir || path$2.dirname(outputOptions.file), outputFile.fileName);22229 const fileName = path.resolve(outputOptions.dir || path.dirname(outputOptions.file), outputFile.fileName); 21261 22230 // 'recursive: true' does not throw if the folder structure, or parts of it, already exist 21262 await promises.mkdir(path $2.dirname(fileName), { recursive: true });22231 await promises.mkdir(path.dirname(fileName), { recursive: true }); 21263 22232 return promises.writeFile(fileName, outputFile.type === 'asset' ? outputFile.source : outputFile.code); 21264 22233 } … … 21282 22251 exports.ensureArray = ensureArray$1; 21283 22252 exports.getAugmentedNamespace = getAugmentedNamespace; 22253 exports.getDefaultExportFromCjs = getDefaultExportFromCjs; 21284 22254 exports.getNewArray = getNewArray; 21285 22255 exports.getOrCreate = getOrCreate; … … 21290 22260 exports.mergeOptions = mergeOptions; 21291 22261 exports.normalizePluginOption = normalizePluginOption; 21292 exports.picomatch = picomatch;21293 22262 exports.rollup = rollup; 21294 22263 exports.rollupInternal = rollupInternal; -
imaps-frontend/node_modules/rollup/dist/shared/watch-cli.js
rd565449 r0c6b92a 1 1 /* 2 2 @license 3 Rollup.js v4.2 0.04 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d53 Rollup.js v4.27.4 4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 5 5 6 6 https://github.com/rollup/rollup … … 12 12 Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 13 13 14 const index = require('./index.js'); 14 15 const promises = require('node:fs/promises'); 15 16 const process$2 = require('node:process'); 16 const index = require('./index.js');17 17 const cli = require('../bin/rollup'); 18 18 const rollup = require('./rollup.js'); … … 21 21 const node_child_process = require('node:child_process'); 22 22 const rollup_js = require('../rollup.js'); 23 require('path'); 23 24 require('fs'); 24 25 require('util'); 25 26 require('stream'); 26 require('path');27 27 require('os'); 28 28 require('./fsevents-importer.js'); … … 540 540 }); 541 541 } 542 asyncfunction close(code) {542 function close(code) { 543 543 process$2.removeListener('uncaughtException', closeWithError); 544 544 // removing a non-existent listener is a no-op 545 545 process$2.stdin.removeListener('end', close); 546 if (watcher)547 await watcher.close();548 546 if (configWatcher) 549 547 configWatcher.close(); 550 if (code) 551 process$2.exit(code); 548 Promise.resolve(watcher?.close()).finally(() => { 549 process$2.exit(typeof code === 'number' ? code : 0); 550 }); 551 // Tell signal-exit that we are handling this gracefully 552 return true; 552 553 } 553 554 // return a promise that never resolves to keep the process running -
imaps-frontend/node_modules/rollup/dist/shared/watch.js
rd565449 r0c6b92a 1 1 /* 2 2 @license 3 Rollup.js v4.2 0.04 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d53 Rollup.js v4.27.4 4 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 5 5 6 6 https://github.com/rollup/rollup … … 12 12 Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 13 13 14 const rollup = require('./rollup.js'); 14 15 const path = require('node:path'); 15 16 const process = require('node:process'); 16 const rollup = require('./rollup.js');17 const index = require('./index.js'); 17 18 const node_os = require('node:os'); 18 const index = require('./index.js');19 19 require('./parseAst.js'); 20 20 require('../native.js'); … … 64 64 const task = this.task; 65 65 const isLinux = node_os.platform() === 'linux'; 66 const isFreeBSD = node_os.platform() === 'freebsd'; 66 67 const isTransformDependency = transformWatcherId !== null; 67 68 const handleChange = (id, event) => { 68 69 const changedId = transformWatcherId || id; 69 if (isLinux ) {70 if (isLinux || isFreeBSD) { 70 71 // unwatching and watching fixes an issue with chokidar where on certain systems, 71 72 // a file that was unlinked and immediately recreated would create a change event
Note:
See TracChangeset
for help on using the changeset viewer.