Changeset 0c6b92a for imaps-frontend/node_modules/rollup/dist
- Timestamp:
- 12/12/24 17:06:06 (5 weeks ago)
- Branches:
- main
- Parents:
- d565449
- Location:
- imaps-frontend/node_modules/rollup/dist
- Files:
-
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
imaps-frontend/node_modules/rollup/dist/bin/rollup
rd565449 r0c6b92a 2 2 /* 3 3 @license 4 Rollup.js v4.2 0.05 Sat, 03 Aug 2024 04:48:21 GMT - commit df12edfea6e9c1a71bda1a01bed1ab787b7514d54 Rollup.js v4.27.4 5 Sat, 23 Nov 2024 06:59:50 GMT - commit e805b546405a4e6cfccd3fe73e9f4df770023824 6 6 7 7 https://github.com/rollup/rollup … … 29 29 require('../getLogFilter.js'); 30 30 31 const help = "rollup version __VERSION__\n=====================================\n\nUsage: rollup [options] <entry file>\n\nBasic options:\n\n-c, --config <filename> Use this config file (if argument is used but value\n is unspecified, defaults to rollup.config.js)\n-d, --dir <dirname> Directory for chunks (if absent, prints to stdout)\n-e, --external <ids> Comma-separate list of module IDs to exclude\n-f, --format <format> Type of output (amd, cjs, es, iife, umd, system)\n-g, --globals <pairs> Comma-separate list of `moduleID:Global` pairs\n-h, --help Show this help message\n-i, --input <filename> Input (alternative to <entry file>)\n-m, --sourcemap Generate sourcemap (`-m inline` for inline map)\n-n, --name <name> Name for UMD export\n-o, --file <output> Single output file (if absent, prints to stdout)\n-p, --plugin <plugin> Use the plugin specified (may be repeated)\n-v, --version Show version number\n-w, --watch Watch files in bundle and rebuild on changes\n--amd.autoId Generate the AMD ID based off the chunk name\n--amd.basePath <prefix> Path to prepend to auto generated AMD ID\n--amd.define <name> Function to use in place of `define`\n--amd.forceJsExtensionForImports Use `.js` extension in AMD imports\n--amd.id <id> ID for AMD module (default is anonymous)\n--assetFileNames <pattern> Name pattern for emitted assets\n--banner <text> Code to insert at top of bundle (outside wrapper)\n--chunkFileNames <pattern> Name pattern for emitted secondary chunks\n--compact Minify wrapper code\n--context <variable> Specify top-level `this` value\n--no-dynamicImportInCjs Write external dynamic CommonJS imports as require\n--entryFileNames <pattern> Name pattern for emitted entry chunks\n--environment <values> Settings passed to config file (see example)\n--no-esModule Do not add __esModule property\n--exports <mode> Specify export mode (auto, default, named, none)\n--extend Extend global variable defined by --name\n--no-externalImportAttributes Omit import attributes in \"es\" output\n--no-externalLiveBindings Do not generate code to support live bindings\n--failAfterWarnings Exit with an error if the build produced warnings\n--filterLogs <filter> Filter log messages\n--footer <text> Code to insert at end of bundle (outside wrapper)\n--forceExit Force exit the process when done\n--no-freeze Do not freeze namespace objects\n--generatedCode <preset> Which code features to use (es5/es2015)\n--generatedCode.arrowFunctions Use arrow functions in generated code\n--generatedCode.constBindings Use \"const\" in generated code\n--generatedCode.objectShorthand Use shorthand properties in generated code\n--no-generatedCode.reservedNamesAsProps Always quote reserved names as props\n--generatedCode.symbols Use symbols in generated code\n--hashCharacters <name> Use the specified character set for file hashes\n--no-hoistTransitiveImports Do not hoist transitive imports into entry chunks\n--importAttributesKey <name> Use the specified keyword for import attributes\n--no-indent Don't indent result\n--inlineDynamicImports Create single bundle when using dynamic imports\n--no-interop Do not include interop block\n--intro <text> Code to insert at top of bundle (inside wrapper)\n--logLevel <level> Which kind of logs to display\n--no-makeAbsoluteExternalsRelative Prevent normalization of external imports\n--maxParallelFileOps <value> How many files to read in parallel\n--minifyInternalExports Force or disable minification of internal exports\n--noConflict Generate a noConflict method for UMD globals\n--outro <text> Code to insert at end of bundle (inside wrapper)\n--perf Display performance timings\n--no-preserveEntrySignatures Avoid facade chunks for entry points\n--preserveModules Preserve module structure\n--preserveModulesRoot Put preserved modules under this path at root level\n--preserveSymlinks Do not follow symlinks when resolving files\n--no-reexportProtoFromExternal Ignore `__proto__` in star re-exports\n--no-sanitizeFileName Do not replace invalid characters in file names\n--shimMissingExports Create shim variables for missing exports\n--silent Don't print warnings\n--sourcemapBaseUrl <url> Emit absolute sourcemap URLs with given base\n--sourcemap ExcludeSources Do not include source code in source maps\n--sourcemapFile <file> Specify bundle position for source maps\n--sourcemapFileNames <pattern> Name pattern for emitted sourcemaps\n--stdin=ext Specify file extension used for stdin input\n--no-stdin Do not read \"-\" from stdin\n--no-strict Don't emit `\"use strict\";` in the generated modules\n--strictDeprecations Throw errors for deprecated features\n--no-systemNullSetters Do not replace empty SystemJS setters with `null`\n--no-treeshake Disable tree-shaking optimisations\n--no-treeshake.annotations Ignore pure call annotations\n--treeshake.correctVarValueBeforeDeclaration Deoptimize variables until declared\n--treeshake.manualPureFunctions <names> Manually declare functions as pure\n--no-treeshake.moduleSideEffects Assume modules have no side effects\n--no-treeshake.propertyReadSideEffects Ignore property access side effects\n--no-treeshake.tryCatchDeoptimization Do not turn off try-catch-tree-shaking\n--no-treeshake.unknownGlobalSideEffects Assume unknown globals do not throw\n--validate Validate output\n--waitForBundleInput Wait for bundle input files\n--watch.buildDelay <number> Throttle watch rebuilds\n--no-watch.clearScreen Do not clear the screen when rebuilding\n--watch.exclude <files> Exclude files from being watched\n--watch.include <files> Limit watching to specified files\n--watch.onBundleEnd <cmd> Shell command to run on `\"BUNDLE_END\"` event\n--watch.onBundleStart <cmd> Shell command to run on `\"BUNDLE_START\"` event\n--watch.onEnd <cmd> Shell command to run on `\"END\"` event\n--watch.onError <cmd> Shell command to run on `\"ERROR\"` event\n--watch.onStart <cmd> Shell command to run on `\"START\"` event\n--watch.skipWrite Do not write files to disk when watching\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --file=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://rollupjs.org\n";31 const help = "rollup version __VERSION__\n=====================================\n\nUsage: rollup [options] <entry file>\n\nBasic options:\n\n-c, --config <filename> Use this config file (if argument is used but value\n is unspecified, defaults to rollup.config.js)\n-d, --dir <dirname> Directory for chunks (if absent, prints to stdout)\n-e, --external <ids> Comma-separate list of module IDs to exclude\n-f, --format <format> Type of output (amd, cjs, es, iife, umd, system)\n-g, --globals <pairs> Comma-separate list of `moduleID:Global` pairs\n-h, --help Show this help message\n-i, --input <filename> Input (alternative to <entry file>)\n-m, --sourcemap Generate sourcemap (`-m inline` for inline map)\n-n, --name <name> Name for UMD export\n-o, --file <output> Single output file (if absent, prints to stdout)\n-p, --plugin <plugin> Use the plugin specified (may be repeated)\n-v, --version Show version number\n-w, --watch Watch files in bundle and rebuild on changes\n--amd.autoId Generate the AMD ID based off the chunk name\n--amd.basePath <prefix> Path to prepend to auto generated AMD ID\n--amd.define <name> Function to use in place of `define`\n--amd.forceJsExtensionForImports Use `.js` extension in AMD imports\n--amd.id <id> ID for AMD module (default is anonymous)\n--assetFileNames <pattern> Name pattern for emitted assets\n--banner <text> Code to insert at top of bundle (outside wrapper)\n--chunkFileNames <pattern> Name pattern for emitted secondary chunks\n--compact Minify wrapper code\n--context <variable> Specify top-level `this` value\n--no-dynamicImportInCjs Write external dynamic CommonJS imports as require\n--entryFileNames <pattern> Name pattern for emitted entry chunks\n--environment <values> Settings passed to config file (see example)\n--no-esModule Do not add __esModule property\n--exports <mode> Specify export mode (auto, default, named, none)\n--extend Extend global variable defined by --name\n--no-externalImportAttributes Omit import attributes in \"es\" output\n--no-externalLiveBindings Do not generate code to support live bindings\n--failAfterWarnings Exit with an error if the build produced warnings\n--filterLogs <filter> Filter log messages\n--footer <text> Code to insert at end of bundle (outside wrapper)\n--forceExit Force exit the process when done\n--no-freeze Do not freeze namespace objects\n--generatedCode <preset> Which code features to use (es5/es2015)\n--generatedCode.arrowFunctions Use arrow functions in generated code\n--generatedCode.constBindings Use \"const\" in generated code\n--generatedCode.objectShorthand Use shorthand properties in generated code\n--no-generatedCode.reservedNamesAsProps Always quote reserved names as props\n--generatedCode.symbols Use symbols in generated code\n--hashCharacters <name> Use the specified character set for file hashes\n--no-hoistTransitiveImports Do not hoist transitive imports into entry chunks\n--importAttributesKey <name> Use the specified keyword for import attributes\n--no-indent Don't indent result\n--inlineDynamicImports Create single bundle when using dynamic imports\n--no-interop Do not include interop block\n--intro <text> Code to insert at top of bundle (inside wrapper)\n--logLevel <level> Which kind of logs to display\n--no-makeAbsoluteExternalsRelative Prevent normalization of external imports\n--maxParallelFileOps <value> How many files to read in parallel\n--minifyInternalExports Force or disable minification of internal exports\n--noConflict Generate a noConflict method for UMD globals\n--outro <text> Code to insert at end of bundle (inside wrapper)\n--perf Display performance timings\n--no-preserveEntrySignatures Avoid facade chunks for entry points\n--preserveModules Preserve module structure\n--preserveModulesRoot Put preserved modules under this path at root level\n--preserveSymlinks Do not follow symlinks when resolving files\n--no-reexportProtoFromExternal Ignore `__proto__` in star re-exports\n--no-sanitizeFileName Do not replace invalid characters in file names\n--shimMissingExports Create shim variables for missing exports\n--silent Don't print warnings\n--sourcemapBaseUrl <url> Emit absolute sourcemap URLs with given base\n--sourcemapDebugIds Emit unique debug ids in source and sourcemaps\n--sourcemapExcludeSources Do not include source code in source maps\n--sourcemapFile <file> Specify bundle position for source maps\n--sourcemapFileNames <pattern> Name pattern for emitted sourcemaps\n--stdin=ext Specify file extension used for stdin input\n--no-stdin Do not read \"-\" from stdin\n--no-strict Don't emit `\"use strict\";` in the generated modules\n--strictDeprecations Throw errors for deprecated features\n--no-systemNullSetters Do not replace empty SystemJS setters with `null`\n--no-treeshake Disable tree-shaking optimisations\n--no-treeshake.annotations Ignore pure call annotations\n--treeshake.correctVarValueBeforeDeclaration Deoptimize variables until declared\n--treeshake.manualPureFunctions <names> Manually declare functions as pure\n--no-treeshake.moduleSideEffects Assume modules have no side effects\n--no-treeshake.propertyReadSideEffects Ignore property access side effects\n--no-treeshake.tryCatchDeoptimization Do not turn off try-catch-tree-shaking\n--no-treeshake.unknownGlobalSideEffects Assume unknown globals do not throw\n--validate Validate output\n--waitForBundleInput Wait for bundle input files\n--watch.buildDelay <number> Throttle watch rebuilds\n--no-watch.clearScreen Do not clear the screen when rebuilding\n--watch.exclude <files> Exclude files from being watched\n--watch.include <files> Limit watching to specified files\n--watch.onBundleEnd <cmd> Shell command to run on `\"BUNDLE_END\"` event\n--watch.onBundleStart <cmd> Shell command to run on `\"BUNDLE_START\"` event\n--watch.onEnd <cmd> Shell command to run on `\"END\"` event\n--watch.onError <cmd> Shell command to run on `\"ERROR\"` event\n--watch.onStart <cmd> Shell command to run on `\"START\"` event\n--watch.skipWrite Do not write files to disk when watching\n\nExamples:\n\n# use settings in config file\nrollup -c\n\n# in config file, process.env.INCLUDE_DEPS === 'true'\n# and process.env.BUILD === 'production'\nrollup -c --environment INCLUDE_DEPS,BUILD:production\n\n# create CommonJS bundle.js from src/main.js\nrollup --format=cjs --file=bundle.js -- src/main.js\n\n# create self-executing IIFE using `window.jQuery`\n# and `window._` as external globals\nrollup -f iife --globals jquery:jQuery,lodash:_ \\\n -i src/app.js -o build/app.js -m build/app.js.map\n\nNotes:\n\n* When piping to stdout, only inline sourcemaps are permitted\n\nFor more information visit https://rollupjs.org\n"; 32 32 33 33 /** … … 1248 1248 yargsParser.looksLikeNumber = looksLikeNumber; 1249 1249 1250 /****************************************************************************** 1251 Copyright (c) Microsoft Corporation. 1252 1253 Permission to use, copy, modify, and/or distribute this software for any 1254 purpose with or without fee is hereby granted. 1255 1256 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH 1257 REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 1258 AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 1259 INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 1260 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 1261 OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 1262 PERFORMANCE OF THIS SOFTWARE. 1263 ***************************************************************************** */ 1264 /* global Reflect, Promise, SuppressedError, Symbol, Iterator */ 1265 1266 1267 function __addDisposableResource(env, value, async) { 1268 if (value !== null && value !== void 0) { 1269 if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected."); 1270 var dispose, inner; 1271 if (async) { 1272 if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined."); 1273 dispose = value[Symbol.asyncDispose]; 1274 } 1275 if (dispose === void 0) { 1276 if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined."); 1277 dispose = value[Symbol.dispose]; 1278 if (async) inner = dispose; 1279 } 1280 if (typeof dispose !== "function") throw new TypeError("Object not disposable."); 1281 if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } }; 1282 env.stack.push({ value: value, dispose: dispose, async: async }); 1283 } 1284 else if (async) { 1285 env.stack.push({ async: true }); 1286 } 1287 return value; 1288 1289 } 1290 1291 var _SuppressedError = typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { 1292 var e = new Error(message); 1293 return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; 1294 }; 1295 1296 function __disposeResources(env) { 1297 function fail(e) { 1298 env.error = env.hasError ? new _SuppressedError(e, env.error, "An error was suppressed during disposal.") : e; 1299 env.hasError = true; 1300 } 1301 var r, s = 0; 1302 function next() { 1303 while (r = env.stack.pop()) { 1304 try { 1305 if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next); 1306 if (r.dispose) { 1307 var result = r.dispose.call(r.value); 1308 if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); }); 1309 } 1310 else s |= 1; 1311 } 1312 catch (e) { 1313 fail(e); 1314 } 1315 } 1316 if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve(); 1317 if (env.hasError) throw env.error; 1318 } 1319 return next(); 1320 } 1321 1250 1322 const toZeroIfInfinity = value => Number.isFinite(value) ? value : 0; 1251 1323 … … 1355 1427 const days = BigInt(parsed.days); 1356 1428 1357 add(days / 365n, 'year', 'y'); 1358 add(days % 365n, 'day', 'd'); 1359 add(Number(parsed.hours), 'hour', 'h'); 1429 if (options.hideYearAndDays) { 1430 add((BigInt(days) * 24n) + BigInt(parsed.hours), 'hour', 'h'); 1431 } else { 1432 if (options.hideYear) { 1433 add(days, 'day', 'd'); 1434 } else { 1435 add(days / 365n, 'year', 'y'); 1436 add(days % 365n, 'day', 'd'); 1437 } 1438 1439 add(Number(parsed.hours), 'hour', 'h'); 1440 } 1441 1360 1442 add(Number(parsed.minutes), 'minute', 'm'); 1361 1443 1362 if ( 1363 options.separateMilliseconds 1364 || options.formatSubMilliseconds 1365 || (!options.colonNotation && milliseconds < 1000) 1366 ) { 1367 const seconds = Number(parsed.seconds); 1368 const milliseconds = Number(parsed.milliseconds); 1369 const microseconds = Number(parsed.microseconds); 1370 const nanoseconds = Number(parsed.nanoseconds); 1371 1372 add(seconds, 'second', 's'); 1373 1374 if (options.formatSubMilliseconds) { 1375 add(milliseconds, 'millisecond', 'ms'); 1376 add(microseconds, 'microsecond', 'µs'); 1377 add(nanoseconds, 'nanosecond', 'ns'); 1444 if (!options.hideSeconds) { 1445 if ( 1446 options.separateMilliseconds 1447 || options.formatSubMilliseconds 1448 || (!options.colonNotation && milliseconds < 1000) 1449 ) { 1450 const seconds = Number(parsed.seconds); 1451 const milliseconds = Number(parsed.milliseconds); 1452 const microseconds = Number(parsed.microseconds); 1453 const nanoseconds = Number(parsed.nanoseconds); 1454 1455 add(seconds, 'second', 's'); 1456 1457 if (options.formatSubMilliseconds) { 1458 add(milliseconds, 'millisecond', 'ms'); 1459 add(microseconds, 'microsecond', 'µs'); 1460 add(nanoseconds, 'nanosecond', 'ns'); 1461 } else { 1462 const millisecondsAndBelow 1463 = milliseconds 1464 + (microseconds / 1000) 1465 + (nanoseconds / 1e6); 1466 1467 const millisecondsDecimalDigits 1468 = typeof options.millisecondsDecimalDigits === 'number' 1469 ? options.millisecondsDecimalDigits 1470 : 0; 1471 1472 const roundedMilliseconds = millisecondsAndBelow >= 1 1473 ? Math.round(millisecondsAndBelow) 1474 : Math.ceil(millisecondsAndBelow); 1475 1476 const millisecondsString = millisecondsDecimalDigits 1477 ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) 1478 : roundedMilliseconds; 1479 1480 add( 1481 Number.parseFloat(millisecondsString), 1482 'millisecond', 1483 'ms', 1484 millisecondsString, 1485 ); 1486 } 1378 1487 } else { 1379 const millisecondsAndBelow 1380 = milliseconds 1381 + (microseconds / 1000) 1382 + (nanoseconds / 1e6); 1383 1384 const millisecondsDecimalDigits 1385 = typeof options.millisecondsDecimalDigits === 'number' 1386 ? options.millisecondsDecimalDigits 1387 : 0; 1388 1389 const roundedMilliseconds = millisecondsAndBelow >= 1 1390 ? Math.round(millisecondsAndBelow) 1391 : Math.ceil(millisecondsAndBelow); 1392 1393 const millisecondsString = millisecondsDecimalDigits 1394 ? millisecondsAndBelow.toFixed(millisecondsDecimalDigits) 1395 : roundedMilliseconds; 1396 1397 add( 1398 Number.parseFloat(millisecondsString), 1399 'millisecond', 1400 'ms', 1401 millisecondsString, 1402 ); 1488 const seconds = ( 1489 (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds) 1490 / 1000 1491 ) % 60; 1492 const secondsDecimalDigits 1493 = typeof options.secondsDecimalDigits === 'number' 1494 ? options.secondsDecimalDigits 1495 : 1; 1496 const secondsFixed = floorDecimals(seconds, secondsDecimalDigits); 1497 const secondsString = options.keepDecimalsOnWholeSeconds 1498 ? secondsFixed 1499 : secondsFixed.replace(/\.0+$/, ''); 1500 add(Number.parseFloat(secondsString), 'second', 's', secondsString); 1403 1501 } 1404 } else {1405 const seconds = (1406 (isBigInt ? Number(milliseconds % ONE_DAY_IN_MILLISECONDS) : milliseconds)1407 / 10001408 ) % 60;1409 const secondsDecimalDigits1410 = typeof options.secondsDecimalDigits === 'number'1411 ? options.secondsDecimalDigits1412 : 1;1413 const secondsFixed = floorDecimals(seconds, secondsDecimalDigits);1414 const secondsString = options.keepDecimalsOnWholeSeconds1415 ? secondsFixed1416 : secondsFixed.replace(/\.0+$/, '');1417 add(Number.parseFloat(secondsString), 'second', 's', secondsString);1418 1502 } 1419 1503 … … 1562 1646 1563 1647 async function build(inputOptions, warnings, silent = false) { 1564 const outputOptions = inputOptions.output; 1565 const useStdout = !outputOptions[0].file && !outputOptions[0].dir; 1566 const start = Date.now(); 1567 const files = useStdout ? ['stdout'] : outputOptions.map(t => parseAst_js.relativeId(t.file || t.dir)); 1568 if (!silent) { 1569 let inputFiles; 1570 if (typeof inputOptions.input === 'string') { 1571 inputFiles = inputOptions.input; 1572 } 1573 else if (Array.isArray(inputOptions.input)) { 1574 inputFiles = inputOptions.input.join(', '); 1575 } 1576 else if (typeof inputOptions.input === 'object' && inputOptions.input !== null) { 1577 inputFiles = Object.values(inputOptions.input).join(', '); 1578 } 1579 rollup.stderr(rollup.cyan$1(`\n${rollup.bold(inputFiles)} → ${rollup.bold(files.join(', '))}...`)); 1580 } 1581 const bundle = await rollup.rollup(inputOptions); 1582 if (useStdout) { 1583 const output = outputOptions[0]; 1584 if (output.sourcemap && output.sourcemap !== 'inline') { 1585 rollup.handleError(parseAst_js.logOnlyInlineSourcemapsForStdout()); 1586 } 1587 const { output: outputs } = await bundle.generate(output); 1588 for (const file of outputs) { 1589 if (outputs.length > 1) 1590 process$1.stdout.write(`\n${rollup.cyan$1(rollup.bold(`//→ ${file.fileName}:`))}\n`); 1591 process$1.stdout.write(file.type === 'asset' ? file.source : file.code); 1592 } 1648 const env_1 = { stack: [], error: void 0, hasError: false }; 1649 try { 1650 const outputOptions = inputOptions.output; 1651 const useStdout = !outputOptions[0].file && !outputOptions[0].dir; 1652 const start = Date.now(); 1653 const files = useStdout ? ['stdout'] : outputOptions.map(t => parseAst_js.relativeId(t.file || t.dir)); 1654 if (!silent) { 1655 let inputFiles; 1656 if (typeof inputOptions.input === 'string') { 1657 inputFiles = inputOptions.input; 1658 } 1659 else if (Array.isArray(inputOptions.input)) { 1660 inputFiles = inputOptions.input.join(', '); 1661 } 1662 else if (typeof inputOptions.input === 'object' && inputOptions.input !== null) { 1663 inputFiles = Object.values(inputOptions.input).join(', '); 1664 } 1665 rollup.stderr(rollup.cyan$1(`\n${rollup.bold(inputFiles)} → ${rollup.bold(files.join(', '))}...`)); 1666 } 1667 const bundle = __addDisposableResource(env_1, await rollup.rollup(inputOptions), true); 1668 if (useStdout) { 1669 const output = outputOptions[0]; 1670 if (output.sourcemap && output.sourcemap !== 'inline') { 1671 rollup.handleError(parseAst_js.logOnlyInlineSourcemapsForStdout()); 1672 } 1673 const { output: outputs } = await bundle.generate(output); 1674 for (const file of outputs) { 1675 if (outputs.length > 1) 1676 process$1.stdout.write(`\n${rollup.cyan$1(rollup.bold(`//→ ${file.fileName}:`))}\n`); 1677 process$1.stdout.write(file.type === 'asset' ? file.source : file.code); 1678 } 1679 if (!silent) { 1680 warnings.flush(); 1681 } 1682 return; 1683 } 1684 await Promise.all(outputOptions.map(bundle.write)); 1593 1685 if (!silent) { 1594 1686 warnings.flush(); 1595 } 1596 return; 1597 } 1598 await Promise.all(outputOptions.map(bundle.write)); 1599 await bundle.close(); 1600 if (!silent) { 1601 warnings.flush(); 1602 rollup.stderr(rollup.green(`created ${rollup.bold(files.join(', '))} in ${rollup.bold(prettyMilliseconds(Date.now() - start))}`)); 1603 if (bundle && bundle.getTimings) { 1604 printTimings(bundle.getTimings()); 1605 } 1687 rollup.stderr(rollup.green(`created ${rollup.bold(files.join(', '))} in ${rollup.bold(prettyMilliseconds(Date.now() - start))}`)); 1688 if (bundle && bundle.getTimings) { 1689 printTimings(bundle.getTimings()); 1690 } 1691 } 1692 } 1693 catch (e_1) { 1694 env_1.error = e_1; 1695 env_1.hasError = true; 1696 } 1697 finally { 1698 const result_1 = __disposeResources(env_1); 1699 if (result_1) 1700 await result_1; 1606 1701 } 1607 1702 } … … 1615 1710 const packageName = commandConfig.slice(5); 1616 1711 try { 1617 // eslint-disable-next-line unicorn/prefer-module1618 1712 return require.resolve(`rollup-config-${packageName}`, { paths: [process$1.cwd()] }); 1619 1713 } 1620 1714 catch { 1621 1715 try { 1622 // eslint-disable-next-line unicorn/prefer-module1623 1716 return require.resolve(packageName, { paths: [process$1.cwd()] }); 1624 1717 } … … 1746 1839 else { 1747 1840 try { 1748 // eslint-disable-next-line unicorn/prefer-module1841 // eslint-disable-next-line @typescript-eslint/no-require-imports 1749 1842 require('source-map-support').install(); 1750 1843 } … … 1754 1847 const promise = runRollup(command); 1755 1848 if (command.forceExit) { 1756 // eslint-disable-next-line unicorn/no-process-exit1757 1849 promise.then(() => process$1.exit()); 1758 1850 } -
imaps-frontend/node_modules/rollup/dist/es/getLogFilter.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/es/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 -
imaps-frontend/node_modules/rollup/dist/es/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 -
imaps-frontend/node_modules/rollup/dist/es/shared/node-entry.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 … … 8 8 Released under the MIT License. 9 9 */ 10 import { normalize, getImportPath, ExportDefaultDeclaration as ExportDefaultDeclaration$1, CallExpression as CallExpression$1, EMPTY_ARRAY, LOGLEVEL_WARN, logUnusedExternalImports, ANNOTATION_KEY, INVALID_ANNOTATION_KEY, Program as Program$1, BLANK, logIllegalImportReassignment, logRedeclarationError, CatchClause as CatchClause$1, logDuplicateArgumentNameError, logModuleLevelDirective, ReturnStatement as ReturnStatement$1, VariableDeclarator as VariableDeclarator$1, Property as Property$1, logConstVariableReassignError, ExpressionStatement as ExpressionStatement$1, ArrowFunctionExpression as ArrowFunctionExpression$1, logMissingExport, EMPTY_SET, logCannotCallNamespace, logEval, StaticBlock as StaticBlock$1, BlockStatement as BlockStatement$1, getRollupError, logParseError, logModuleParseError, error, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, Identifier as Identifier$1, logThisIsUndefined, getAstBuffer, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, EMPTY_OBJECT, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logSyntheticNamedExportsNeedNamespaceExport, logMissingEntryExport, logInvalidFormatForTopLevelAwait, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, logCircularReexport, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, logMissingNodeBuiltins, logIllegalIdentifierAsName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, logAddonNotGenerated, logIncompatibleExportOptionValue, logMixedExport, logFailedValidation, isPathFragment, logCyclicCrossChunkReexport, getAliasName, logUnexpectedNamedImport, isAbsolute as isAbsolute$1, relative as relative$1, logUnexpectedNamespaceReexport, logEmptyChunk, logMissingGlobalName, logOptimizeChunkStatus, logSourcemapBroken, logConflictingSourcemapSources, logChunkInvalid, logInvalidOption, URL_OUTPUT_FORMAT, URL_OUTPUT_DIR, URL_OUTPUT_SOURCEMAPFILE, URL_OUTPUT_AMD_ID, logCannotAssignModuleToChunk, logAnonymousPluginCache, logDuplicatePluginName, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, logUnknownOption, printQuotedStringList, logInvalidSetAssetSourceCall, logPluginError, logNoTransformMapOrAstWithoutCode, relativeId, logBadLoader, logExternalModulesCannotBeTransformedToModules, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logInvalidRollupPhaseForChunkEmission, logFileNameConflict, logAssetNotFinalisedForFileName, logChunkNotGeneratedForFileName, logInvalidLogPosition, logInputHookInOutputPlugin, logInvalidFunctionPluginHook, logInvalidAddonPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_TREESHAKE_MODULESIDEEFFECTS, URL_TREESHAKE, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_AMD_BASEPATH, logInvalidExportOptionValue, warnDeprecation, URL_OUTPUT_INTEROP, URL_OUTPUT_MANUALCHUNKS, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, logAlreadyClosed, logMissingFileOrDirOption, logCannotEmitFromOptionsHook, URL_WATCH } from './parseAst.js';10 import { ExportDefaultDeclaration as ExportDefaultDeclaration$1, CallExpression as CallExpression$1, EMPTY_ARRAY, LOGLEVEL_WARN, logUnusedExternalImports, ANNOTATION_KEY, INVALID_ANNOTATION_KEY, ObjectExpression as ObjectExpression$1, Property as Property$1, Program as Program$1, logIllegalImportReassignment, BLANK, logRedeclarationError, StaticBlock as StaticBlock$1, CatchClause as CatchClause$1, logDuplicateArgumentNameError, logModuleLevelDirective, ReturnStatement as ReturnStatement$1, VariableDeclarator as VariableDeclarator$1, ExpressionStatement as ExpressionStatement$1, logMissingExport, normalize, getImportPath, logMissingNodeBuiltins, logReservedNamespace, error, logIllegalIdentifierAsName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, logConstVariableReassignError, ArrowFunctionExpression as ArrowFunctionExpression$1, EMPTY_SET, logCannotCallNamespace, logEval, BlockStatement as BlockStatement$1, getRollupError, logParseError, logModuleParseError, LOGLEVEL_INFO, logFirstSideEffect, locate, logInvalidAnnotation, Identifier as Identifier$1, logThisIsUndefined, getAstBuffer, convertAnnotations, FIXED_STRINGS, convertNode as convertNode$1, EMPTY_OBJECT, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logSyntheticNamedExportsNeedNamespaceExport, logMissingEntryExport, logDuplicateExportError, logInvalidSourcemapForError, augmentCodeLocation, logInconsistentImportAttributes, logMissingJsxExport, logNamespaceConflict, logAmbiguousExternalNamespaces, logShimmedExport, parseAst, logCircularReexport, logInvalidFormatForTopLevelAwait, TemplateLiteral as TemplateLiteral$1, Literal as Literal$1, logAddonNotGenerated, logIncompatibleExportOptionValue, logMixedExport, logFailedValidation, isPathFragment, logCyclicCrossChunkReexport, getAliasName, logUnexpectedNamedImport, isAbsolute as isAbsolute$1, relative as relative$1, logUnexpectedNamespaceReexport, logEmptyChunk, logMissingGlobalName, logOptimizeChunkStatus, logSourcemapBroken, logConflictingSourcemapSources, logChunkInvalid, logInvalidOption, URL_OUTPUT_FORMAT, URL_OUTPUT_DIR, URL_OUTPUT_SOURCEMAPFILE, URL_OUTPUT_AMD_ID, logCannotAssignModuleToChunk, logAnonymousPluginCache, logDuplicatePluginName, logUnknownOption, printQuotedStringList, LOGLEVEL_ERROR, logLevelPriority, LOGLEVEL_DEBUG, logInvalidSetAssetSourceCall, logPluginError, logNoTransformMapOrAstWithoutCode, relativeId, logBadLoader, logExternalModulesCannotBeTransformedToModules, logInternalIdCannotBeExternal, isRelative, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logExternalSyntheticExports, logUnresolvedEntry, logUnresolvedImplicitDependant, logExternalModulesCannotBeIncludedInManualChunks, logEntryCannotBeExternal, logImplicitDependantCannotBeExternal, logNoAssetSourceSet, logFileReferenceIdNotFoundForFilename, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logInvalidRollupPhaseForChunkEmission, warnDeprecation, URL_GENERATEBUNDLE, logFileNameConflict, logAssetNotFinalisedForFileName, logChunkNotGeneratedForFileName, logInvalidLogPosition, logInputHookInOutputPlugin, logInvalidFunctionPluginHook, logInvalidAddonPluginHook, logImplicitDependantIsNotIncluded, logCircularDependency, augmentLogMessage, URL_JSX, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, logInvalidExportOptionValue, URL_OUTPUT_INTEROP, isValidUrl, addTrailingSlashIfMissed, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_PRESERVEENTRYSIGNATURES, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_MANUALCHUNKS, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, logAlreadyClosed, logMissingFileOrDirOption, logCannotEmitFromOptionsHook, URL_WATCH } from './parseAst.js'; 11 11 import { relative, dirname, basename, extname, resolve as resolve$1 } from 'node:path'; 12 import require$$0, { win32, posix, isAbsolute, resolve } from 'path';12 import { posix, win32, isAbsolute, resolve } from 'path'; 13 13 import { parseAsync, xxhashBase64Url, xxhashBase36, xxhashBase16 } from '../../native.js'; 14 14 import process$1, { env as env$1 } from 'node:process'; … … 17 17 import * as tty from 'tty'; 18 18 19 var version = "4.2 0.0";19 var version = "4.27.4"; 20 20 21 21 const comma = ','.charCodeAt(0); … … 422 422 this.x_google_ignoreList = properties.x_google_ignoreList; 423 423 } 424 if (typeof properties.debugId !== 'undefined') { 425 this.debugId = properties.debugId; 426 } 424 427 } 425 428 … … 480 483 const toString = Object.prototype.toString; 481 484 482 function isObject $1(thing) {485 function isObject(thing) { 483 486 return toString.call(thing) === '[object Object]'; 484 487 } … … 566 569 567 570 while (originalCharIndex < chunk.end) { 568 if (this.hires || first || sourcemapLocations.has(originalCharIndex)) {569 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];570 571 if (this.hires === 'boundary') {572 // in hires "boundary", group segments per word boundary than per char573 if (wordRegex.test(original[originalCharIndex])) {574 // for first char in the boundary found, start the boundary by pushing a segment575 if (!charInHiresBoundary) {576 this.rawSegments.push(segment);577 charInHiresBoundary = true;578 }579 } else {580 // for non-word char, end the boundary by pushing a segment581 this.rawSegments.push(segment);582 charInHiresBoundary = false;583 }584 } else {585 this.rawSegments.push(segment);586 }587 }588 589 571 if (original[originalCharIndex] === '\n') { 590 572 loc.line += 1; … … 595 577 first = true; 596 578 } else { 579 if (this.hires || first || sourcemapLocations.has(originalCharIndex)) { 580 const segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column]; 581 582 if (this.hires === 'boundary') { 583 // in hires "boundary", group segments per word boundary than per char 584 if (wordRegex.test(original[originalCharIndex])) { 585 // for first char in the boundary found, start the boundary by pushing a segment 586 if (!charInHiresBoundary) { 587 this.rawSegments.push(segment); 588 charInHiresBoundary = true; 589 } 590 } else { 591 // for non-word char, end the boundary by pushing a segment 592 this.rawSegments.push(segment); 593 charInHiresBoundary = false; 594 } 595 } else { 596 this.rawSegments.push(segment); 597 } 598 } 599 597 600 loc.column += 1; 598 601 this.generatedCodeColumn += 1; … … 801 804 const pattern = /^[^\r\n]/gm; 802 805 803 if (isObject $1(indentStr)) {806 if (isObject(indentStr)) { 804 807 options = indentStr; 805 808 indentStr = undefined; … … 1478 1481 } 1479 1482 1480 if (!isObject $1(source) || !source.content) {1483 if (!isObject(source) || !source.content) { 1481 1484 throw new Error( 1482 1485 'bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`', … … 1749 1752 }; 1750 1753 1751 const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/; 1752 const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g; 1753 const backSlashRegEx = /\\/g; 1754 function escapeId(id) { 1755 if (!needsEscapeRegEx.test(id)) 1756 return id; 1757 return id.replace(backSlashRegEx, '\\\\').replace(quoteNewlineRegEx, '\\$1'); 1758 } 1759 1760 class ExternalChunk { 1761 constructor(module, options, inputBase) { 1762 this.options = options; 1763 this.inputBase = inputBase; 1764 this.defaultVariableName = ''; 1765 this.namespaceVariableName = ''; 1766 this.variableName = ''; 1767 this.fileName = null; 1768 this.importAttributes = null; 1769 this.id = module.id; 1770 this.moduleInfo = module.info; 1771 this.renormalizeRenderPath = module.renormalizeRenderPath; 1772 this.suggestedVariableName = module.suggestedVariableName; 1773 } 1774 getFileName() { 1775 if (this.fileName) { 1776 return this.fileName; 1777 } 1778 const { paths } = this.options; 1779 return (this.fileName = 1780 (typeof paths === 'function' ? paths(this.id) : paths[this.id]) || 1781 (this.renormalizeRenderPath ? normalize(relative(this.inputBase, this.id)) : this.id)); 1782 } 1783 getImportAttributes(snippets) { 1784 return (this.importAttributes ||= formatAttributes(this.options.format === 'es' && 1785 this.options.externalImportAttributes && 1786 this.moduleInfo.attributes, snippets)); 1787 } 1788 getImportPath(importer) { 1789 return escapeId(this.renormalizeRenderPath 1790 ? getImportPath(importer, this.getFileName(), this.options.format === 'amd', false) 1791 : this.getFileName()); 1792 } 1793 } 1794 function formatAttributes(attributes, { getObject }) { 1795 if (!attributes) { 1796 return null; 1797 } 1798 const assertionEntries = Object.entries(attributes).map(([key, value]) => [key, `'${value}'`]); 1799 if (assertionEntries.length > 0) { 1800 return getObject(assertionEntries, { lineBreakIndent: null }); 1801 } 1802 return null; 1803 } 1754 function treeshakeNode(node, code, start, end) { 1755 code.remove(start, end); 1756 node.removeAnnotations(code); 1757 } 1758 1759 const NO_SEMICOLON = { isNoStatement: true }; 1760 // This assumes there are only white-space and comments between start and the string we are looking for 1761 function findFirstOccurrenceOutsideComment(code, searchString, start = 0) { 1762 let searchPos, charCodeAfterSlash; 1763 searchPos = code.indexOf(searchString, start); 1764 while (true) { 1765 start = code.indexOf('/', start); 1766 if (start === -1 || start >= searchPos) 1767 return searchPos; 1768 charCodeAfterSlash = code.charCodeAt(++start); 1769 ++start; 1770 // With our assumption, '/' always starts a comment. Determine comment type: 1771 start = 1772 charCodeAfterSlash === 47 /*"/"*/ 1773 ? code.indexOf('\n', start) + 1 1774 : code.indexOf('*/', start) + 2; 1775 if (start > searchPos) { 1776 searchPos = code.indexOf(searchString, start); 1777 } 1778 } 1779 } 1780 const NON_WHITESPACE = /\S/g; 1781 function findNonWhiteSpace(code, index) { 1782 NON_WHITESPACE.lastIndex = index; 1783 const result = NON_WHITESPACE.exec(code); 1784 return result.index; 1785 } 1786 const WHITESPACE = /\s/; 1787 function findLastWhiteSpaceReverse(code, start, end) { 1788 while (true) { 1789 if (start >= end) { 1790 return end; 1791 } 1792 if (WHITESPACE.test(code[end - 1])) { 1793 end--; 1794 } 1795 else { 1796 return end; 1797 } 1798 } 1799 } 1800 // This assumes "code" only contains white-space and comments 1801 // Returns position of line-comment if applicable 1802 function findFirstLineBreakOutsideComment(code) { 1803 let lineBreakPos, charCodeAfterSlash, start = 0; 1804 lineBreakPos = code.indexOf('\n', start); 1805 while (true) { 1806 start = code.indexOf('/', start); 1807 if (start === -1 || start > lineBreakPos) 1808 return [lineBreakPos, lineBreakPos + 1]; 1809 // With our assumption, '/' always starts a comment. Determine comment type: 1810 charCodeAfterSlash = code.charCodeAt(start + 1); 1811 if (charCodeAfterSlash === 47 /*"/"*/) 1812 return [start, lineBreakPos + 1]; 1813 start = code.indexOf('*/', start + 2) + 2; 1814 if (start > lineBreakPos) { 1815 lineBreakPos = code.indexOf('\n', start); 1816 } 1817 } 1818 } 1819 function renderStatementList(statements, code, start, end, options) { 1820 let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart; 1821 let nextNode = statements[0]; 1822 let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries; 1823 if (nextNodeNeedsBoundaries) { 1824 nextNodeStart = 1825 start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1]; 1826 } 1827 for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) { 1828 currentNode = nextNode; 1829 currentNodeStart = nextNodeStart; 1830 currentNodeNeedsBoundaries = nextNodeNeedsBoundaries; 1831 nextNode = statements[nextIndex]; 1832 nextNodeNeedsBoundaries = 1833 nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries; 1834 if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) { 1835 nextNodeStart = 1836 currentNode.end + 1837 findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1]; 1838 if (currentNode.included) { 1839 if (currentNodeNeedsBoundaries) { 1840 currentNode.render(code, options, { 1841 end: nextNodeStart, 1842 start: currentNodeStart 1843 }); 1844 } 1845 else { 1846 currentNode.render(code, options); 1847 } 1848 } 1849 else { 1850 treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart); 1851 } 1852 } 1853 else { 1854 currentNode.render(code, options); 1855 } 1856 } 1857 } 1858 // This assumes that the first character is not part of the first node 1859 function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) { 1860 const splitUpNodes = []; 1861 let node, nextNodeStart, contentEnd, char; 1862 let separator = start - 1; 1863 for (const nextNode of nodes) { 1864 if (node !== undefined) { 1865 separator = 1866 node.end + 1867 findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ','); 1868 } 1869 nextNodeStart = contentEnd = 1870 separator + 1871 1 + 1872 findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1]; 1873 while (((char = code.original.charCodeAt(nextNodeStart)), 1874 char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/) 1875 nextNodeStart++; 1876 if (node !== undefined) { 1877 splitUpNodes.push({ 1878 contentEnd, 1879 end: nextNodeStart, 1880 node, 1881 separator, 1882 start 1883 }); 1884 } 1885 node = nextNode; 1886 start = nextNodeStart; 1887 } 1888 splitUpNodes.push({ 1889 contentEnd: end, 1890 end, 1891 node: node, 1892 separator: null, 1893 start 1894 }); 1895 return splitUpNodes; 1896 } 1897 // This assumes there are only white-space and comments between start and end 1898 function removeLineBreaks(code, start, end) { 1899 while (true) { 1900 const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end)); 1901 if (removeStart === -1) { 1902 break; 1903 } 1904 code.remove(start + removeStart, (start += removeEnd)); 1905 } 1906 } 1907 1908 function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') { 1909 if (exportedVariables.length === 1 && 1910 exportNamesByVariable.get(exportedVariables[0]).length === 1) { 1911 const variable = exportedVariables[0]; 1912 return `exports(${JSON.stringify(exportNamesByVariable.get(variable)[0])},${_}${variable.getName(getPropertyAccess)}${modifier})`; 1913 } 1914 else { 1915 const fields = []; 1916 for (const variable of exportedVariables) { 1917 for (const exportName of exportNamesByVariable.get(variable)) { 1918 fields.push([exportName, variable.getName(getPropertyAccess) + modifier]); 1919 } 1920 } 1921 return `exports(${getObject(fields, { lineBreakIndent: null })})`; 1922 } 1923 } 1924 // This is only invoked if there is exactly one export name 1925 function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) { 1926 code.prependRight(expressionStart, `exports(${JSON.stringify(exportNamesByVariable.get(exportedVariable)[0])},${_}`); 1927 code.appendLeft(expressionEnd, ')'); 1928 } 1929 function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) { 1930 const { _, getDirectReturnIifeLeft } = options.snippets; 1931 code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens })); 1932 code.appendLeft(expressionEnd, ')'); 1933 } 1934 function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) { 1935 const { _, getPropertyAccess } = options.snippets; 1936 code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`); 1937 if (needsParens) { 1938 code.prependRight(expressionStart, '('); 1939 code.appendLeft(expressionEnd, ')'); 1940 } 1941 } 1942 function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) { 1943 const { _ } = options.snippets; 1944 code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`); 1945 if (needsParens) { 1946 code.prependRight(expressionStart, '('); 1947 code.appendLeft(expressionEnd, ')'); 1948 } 1949 } 1950 1951 /** @import { Node } from 'estree' */ 1952 1953 /** 1954 * @param {Node} node 1955 * @param {Node} parent 1956 * @returns {boolean} 1957 */ 1958 function is_reference(node, parent) { 1959 if (node.type === 'MemberExpression') { 1960 return !node.computed && is_reference(node.object, node); 1961 } 1962 1963 if (node.type !== 'Identifier') return false; 1964 1965 switch (parent?.type) { 1966 // disregard `bar` in `foo.bar` 1967 case 'MemberExpression': 1968 return parent.computed || node === parent.object; 1969 1970 // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}` 1971 case 'MethodDefinition': 1972 return parent.computed; 1973 1974 // disregard the `meta` in `import.meta` 1975 case 'MetaProperty': 1976 return parent.meta === node; 1977 1978 // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}` 1979 case 'PropertyDefinition': 1980 return parent.computed || node === parent.value; 1981 1982 // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }` 1983 case 'Property': 1984 return parent.computed || node === parent.value; 1985 1986 // disregard the `bar` in `export { foo as bar }` or 1987 // the foo in `import { foo as bar }` 1988 case 'ExportSpecifier': 1989 case 'ImportSpecifier': 1990 return node === parent.local; 1991 1992 // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}` 1993 case 'LabeledStatement': 1994 case 'BreakStatement': 1995 case 'ContinueStatement': 1996 return false; 1997 1998 default: 1999 return true; 2000 } 2001 } 2002 2003 const PureFunctionKey = Symbol('PureFunction'); 2004 const getPureFunctions = ({ treeshake }) => { 2005 const pureFunctions = Object.create(null); 2006 for (const functionName of treeshake ? treeshake.manualPureFunctions : []) { 2007 let currentFunctions = pureFunctions; 2008 for (const pathSegment of functionName.split('.')) { 2009 currentFunctions = currentFunctions[pathSegment] ||= Object.create(null); 2010 } 2011 currentFunctions[PureFunctionKey] = true; 2012 } 2013 return pureFunctions; 2014 }; 1804 2015 1805 2016 function getOrCreate(map, key, init) { … … 1977 2188 this.alwaysRendered = false; 1978 2189 this.forbiddenNames = null; 2190 this.globalName = null; 1979 2191 this.initReached = false; 1980 2192 this.isId = false; … … 2022 2234 } 2023 2235 getName(getPropertyAccess, useOriginalName) { 2236 if (this.globalName) { 2237 return this.globalName; 2238 } 2024 2239 if (useOriginalName?.(this)) { 2025 2240 return this.name; … … 2035 2250 } 2036 2251 /** 2037 * Marks this variable as being part of the bundle, which is usually the case when one of2038 * its identifiers becomes part of the bundle. Returns true if it has not been included2039 * previously.2040 * Once a variable is included, it shouldtake care all its declarations are included.2252 * Marks this variable as being part of the bundle, which is usually the case 2253 * when one of its identifiers becomes part of the bundle. Returns true if it 2254 * has not been included previously. Once a variable is included, it should 2255 * take care all its declarations are included. 2041 2256 */ 2042 2257 include() { … … 2262 2477 } 2263 2478 2264 function getDefaultExportFromCjs (x) { 2265 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 2266 } 2267 2268 function getAugmentedNamespace(n) { 2269 if (n.__esModule) return n; 2270 var f = n.default; 2271 if (typeof f == "function") { 2272 var a = function a () { 2273 if (this instanceof a) { 2274 return Reflect.construct(f, arguments, this.constructor); 2275 } 2276 return f.apply(this, arguments); 2277 }; 2278 a.prototype = f.prototype; 2279 } else a = {}; 2280 Object.defineProperty(a, '__esModule', {value: true}); 2281 Object.keys(n).forEach(function (k) { 2282 var d = Object.getOwnPropertyDescriptor(n, k); 2283 Object.defineProperty(a, k, d.get ? d : { 2284 enumerable: true, 2285 get: function () { 2286 return n[k]; 2287 } 2288 }); 2289 }); 2290 return a; 2291 } 2292 2293 var utils$3 = {}; 2294 2295 const path$1 = require$$0; 2296 const WIN_SLASH = '\\\\/'; 2297 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 2298 2299 /** 2300 * Posix glob regex 2301 */ 2302 2303 const DOT_LITERAL = '\\.'; 2304 const PLUS_LITERAL = '\\+'; 2305 const QMARK_LITERAL = '\\?'; 2306 const SLASH_LITERAL = '\\/'; 2307 const ONE_CHAR = '(?=.)'; 2308 const QMARK = '[^/]'; 2309 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 2310 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 2311 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 2312 const NO_DOT = `(?!${DOT_LITERAL})`; 2313 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 2314 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 2315 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 2316 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 2317 const STAR = `${QMARK}*?`; 2318 2319 const POSIX_CHARS = { 2320 DOT_LITERAL, 2321 PLUS_LITERAL, 2322 QMARK_LITERAL, 2323 SLASH_LITERAL, 2324 ONE_CHAR, 2325 QMARK, 2326 END_ANCHOR, 2327 DOTS_SLASH, 2328 NO_DOT, 2329 NO_DOTS, 2330 NO_DOT_SLASH, 2331 NO_DOTS_SLASH, 2332 QMARK_NO_DOT, 2333 STAR, 2334 START_ANCHOR 2479 function markModuleAndImpureDependenciesAsExecuted(baseModule) { 2480 baseModule.isExecuted = true; 2481 const modules = [baseModule]; 2482 const visitedModules = new Set(); 2483 for (const module of modules) { 2484 for (const dependency of [...module.dependencies, ...module.implicitlyLoadedBefore]) { 2485 if (!(dependency instanceof ExternalModule) && 2486 !dependency.isExecuted && 2487 (dependency.info.moduleSideEffects || module.implicitlyLoadedBefore.has(dependency)) && 2488 !visitedModules.has(dependency.id)) { 2489 dependency.isExecuted = true; 2490 visitedModules.add(dependency.id); 2491 modules.push(dependency); 2492 } 2493 } 2494 } 2495 } 2496 2497 const doNothing = () => { }; 2498 2499 // This file is generated by scripts/generate-child-node-keys.js. 2500 // Do not edit this file directly. 2501 const childNodeKeys = { 2502 ArrayExpression: ['elements'], 2503 ArrayPattern: ['elements'], 2504 ArrowFunctionExpression: ['params', 'body'], 2505 AssignmentExpression: ['left', 'right'], 2506 AssignmentPattern: ['left', 'right'], 2507 AwaitExpression: ['argument'], 2508 BinaryExpression: ['left', 'right'], 2509 BlockStatement: ['body'], 2510 BreakStatement: ['label'], 2511 CallExpression: ['callee', 'arguments'], 2512 CatchClause: ['param', 'body'], 2513 ChainExpression: ['expression'], 2514 ClassBody: ['body'], 2515 ClassDeclaration: ['decorators', 'id', 'superClass', 'body'], 2516 ClassExpression: ['decorators', 'id', 'superClass', 'body'], 2517 ConditionalExpression: ['test', 'consequent', 'alternate'], 2518 ContinueStatement: ['label'], 2519 DebuggerStatement: [], 2520 Decorator: ['expression'], 2521 DoWhileStatement: ['body', 'test'], 2522 EmptyStatement: [], 2523 ExportAllDeclaration: ['exported', 'source', 'attributes'], 2524 ExportDefaultDeclaration: ['declaration'], 2525 ExportNamedDeclaration: ['specifiers', 'source', 'attributes', 'declaration'], 2526 ExportSpecifier: ['local', 'exported'], 2527 ExpressionStatement: ['expression'], 2528 ForInStatement: ['left', 'right', 'body'], 2529 ForOfStatement: ['left', 'right', 'body'], 2530 ForStatement: ['init', 'test', 'update', 'body'], 2531 FunctionDeclaration: ['id', 'params', 'body'], 2532 FunctionExpression: ['id', 'params', 'body'], 2533 Identifier: [], 2534 IfStatement: ['test', 'consequent', 'alternate'], 2535 ImportAttribute: ['key', 'value'], 2536 ImportDeclaration: ['specifiers', 'source', 'attributes'], 2537 ImportDefaultSpecifier: ['local'], 2538 ImportExpression: ['source', 'options'], 2539 ImportNamespaceSpecifier: ['local'], 2540 ImportSpecifier: ['imported', 'local'], 2541 JSXAttribute: ['name', 'value'], 2542 JSXClosingElement: ['name'], 2543 JSXClosingFragment: [], 2544 JSXElement: ['openingElement', 'children', 'closingElement'], 2545 JSXEmptyExpression: [], 2546 JSXExpressionContainer: ['expression'], 2547 JSXFragment: ['openingFragment', 'children', 'closingFragment'], 2548 JSXIdentifier: [], 2549 JSXMemberExpression: ['object', 'property'], 2550 JSXNamespacedName: ['namespace', 'name'], 2551 JSXOpeningElement: ['name', 'attributes'], 2552 JSXOpeningFragment: [], 2553 JSXSpreadAttribute: ['argument'], 2554 JSXSpreadChild: ['expression'], 2555 JSXText: [], 2556 LabeledStatement: ['label', 'body'], 2557 Literal: [], 2558 LogicalExpression: ['left', 'right'], 2559 MemberExpression: ['object', 'property'], 2560 MetaProperty: ['meta', 'property'], 2561 MethodDefinition: ['decorators', 'key', 'value'], 2562 NewExpression: ['callee', 'arguments'], 2563 ObjectExpression: ['properties'], 2564 ObjectPattern: ['properties'], 2565 PanicError: [], 2566 ParseError: [], 2567 PrivateIdentifier: [], 2568 Program: ['body'], 2569 Property: ['key', 'value'], 2570 PropertyDefinition: ['decorators', 'key', 'value'], 2571 RestElement: ['argument'], 2572 ReturnStatement: ['argument'], 2573 SequenceExpression: ['expressions'], 2574 SpreadElement: ['argument'], 2575 StaticBlock: ['body'], 2576 Super: [], 2577 SwitchCase: ['test', 'consequent'], 2578 SwitchStatement: ['discriminant', 'cases'], 2579 TaggedTemplateExpression: ['tag', 'quasi'], 2580 TemplateElement: [], 2581 TemplateLiteral: ['quasis', 'expressions'], 2582 ThisExpression: [], 2583 ThrowStatement: ['argument'], 2584 TryStatement: ['block', 'handler', 'finalizer'], 2585 UnaryExpression: ['argument'], 2586 UpdateExpression: ['argument'], 2587 VariableDeclaration: ['declarations'], 2588 VariableDeclarator: ['id', 'init'], 2589 WhileStatement: ['test', 'body'], 2590 YieldExpression: ['argument'] 2335 2591 }; 2336 2337 /**2338 * Windows glob regex2339 */2340 2341 const WINDOWS_CHARS = {2342 ...POSIX_CHARS,2343 2344 SLASH_LITERAL: `[${WIN_SLASH}]`,2345 QMARK: WIN_NO_SLASH,2346 STAR: `${WIN_NO_SLASH}*?`,2347 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`,2348 NO_DOT: `(?!${DOT_LITERAL})`,2349 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,2350 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`,2351 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`,2352 QMARK_NO_DOT: `[^.${WIN_SLASH}]`,2353 START_ANCHOR: `(?:^|[${WIN_SLASH}])`,2354 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`2355 };2356 2357 /**2358 * POSIX Bracket Regex2359 */2360 2361 const POSIX_REGEX_SOURCE$1 = {2362 alnum: 'a-zA-Z0-9',2363 alpha: 'a-zA-Z',2364 ascii: '\\x00-\\x7F',2365 blank: ' \\t',2366 cntrl: '\\x00-\\x1F\\x7F',2367 digit: '0-9',2368 graph: '\\x21-\\x7E',2369 lower: 'a-z',2370 print: '\\x20-\\x7E ',2371 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~',2372 space: ' \\t\\r\\n\\v\\f',2373 upper: 'A-Z',2374 word: 'A-Za-z0-9_',2375 xdigit: 'A-Fa-f0-9'2376 };2377 2378 var constants$2 = {2379 MAX_LENGTH: 1024 * 64,2380 POSIX_REGEX_SOURCE: POSIX_REGEX_SOURCE$1,2381 2382 // regular expressions2383 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g,2384 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/,2385 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/,2386 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g,2387 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g,2388 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g,2389 2390 // Replace globs with equivalent patterns to reduce parsing time.2391 REPLACEMENTS: {2392 '***': '*',2393 '**/**': '**',2394 '**/**/**': '**'2395 },2396 2397 // Digits2398 CHAR_0: 48, /* 0 */2399 CHAR_9: 57, /* 9 */2400 2401 // Alphabet chars.2402 CHAR_UPPERCASE_A: 65, /* A */2403 CHAR_LOWERCASE_A: 97, /* a */2404 CHAR_UPPERCASE_Z: 90, /* Z */2405 CHAR_LOWERCASE_Z: 122, /* z */2406 2407 CHAR_LEFT_PARENTHESES: 40, /* ( */2408 CHAR_RIGHT_PARENTHESES: 41, /* ) */2409 2410 CHAR_ASTERISK: 42, /* * */2411 2412 // Non-alphabetic chars.2413 CHAR_AMPERSAND: 38, /* & */2414 CHAR_AT: 64, /* @ */2415 CHAR_BACKWARD_SLASH: 92, /* \ */2416 CHAR_CARRIAGE_RETURN: 13, /* \r */2417 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */2418 CHAR_COLON: 58, /* : */2419 CHAR_COMMA: 44, /* , */2420 CHAR_DOT: 46, /* . */2421 CHAR_DOUBLE_QUOTE: 34, /* " */2422 CHAR_EQUAL: 61, /* = */2423 CHAR_EXCLAMATION_MARK: 33, /* ! */2424 CHAR_FORM_FEED: 12, /* \f */2425 CHAR_FORWARD_SLASH: 47, /* / */2426 CHAR_GRAVE_ACCENT: 96, /* ` */2427 CHAR_HASH: 35, /* # */2428 CHAR_HYPHEN_MINUS: 45, /* - */2429 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */2430 CHAR_LEFT_CURLY_BRACE: 123, /* { */2431 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */2432 CHAR_LINE_FEED: 10, /* \n */2433 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */2434 CHAR_PERCENT: 37, /* % */2435 CHAR_PLUS: 43, /* + */2436 CHAR_QUESTION_MARK: 63, /* ? */2437 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */2438 CHAR_RIGHT_CURLY_BRACE: 125, /* } */2439 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */2440 CHAR_SEMICOLON: 59, /* ; */2441 CHAR_SINGLE_QUOTE: 39, /* ' */2442 CHAR_SPACE: 32, /* */2443 CHAR_TAB: 9, /* \t */2444 CHAR_UNDERSCORE: 95, /* _ */2445 CHAR_VERTICAL_LINE: 124, /* | */2446 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */2447 2448 SEP: path$1.sep,2449 2450 /**2451 * Create EXTGLOB_CHARS2452 */2453 2454 extglobChars(chars) {2455 return {2456 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` },2457 '?': { type: 'qmark', open: '(?:', close: ')?' },2458 '+': { type: 'plus', open: '(?:', close: ')+' },2459 '*': { type: 'star', open: '(?:', close: ')*' },2460 '@': { type: 'at', open: '(?:', close: ')' }2461 };2462 },2463 2464 /**2465 * Create GLOB_CHARS2466 */2467 2468 globChars(win32) {2469 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS;2470 }2471 };2472 2473 (function (exports) {2474 2475 const path = require$$0;2476 const win32 = process.platform === 'win32';2477 const {2478 REGEX_BACKSLASH,2479 REGEX_REMOVE_BACKSLASH,2480 REGEX_SPECIAL_CHARS,2481 REGEX_SPECIAL_CHARS_GLOBAL2482 } = constants$2;2483 2484 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val);2485 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str);2486 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str);2487 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1');2488 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/');2489 2490 exports.removeBackslashes = str => {2491 return str.replace(REGEX_REMOVE_BACKSLASH, match => {2492 return match === '\\' ? '' : match;2493 });2494 };2495 2496 exports.supportsLookbehinds = () => {2497 const segs = process.version.slice(1).split('.').map(Number);2498 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) {2499 return true;2500 }2501 return false;2502 };2503 2504 exports.isWindows = options => {2505 if (options && typeof options.windows === 'boolean') {2506 return options.windows;2507 }2508 return win32 === true || path.sep === '\\';2509 };2510 2511 exports.escapeLast = (input, char, lastIdx) => {2512 const idx = input.lastIndexOf(char, lastIdx);2513 if (idx === -1) return input;2514 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1);2515 return `${input.slice(0, idx)}\\${input.slice(idx)}`;2516 };2517 2518 exports.removePrefix = (input, state = {}) => {2519 let output = input;2520 if (output.startsWith('./')) {2521 output = output.slice(2);2522 state.prefix = './';2523 }2524 return output;2525 };2526 2527 exports.wrapOutput = (input, state = {}, options = {}) => {2528 const prepend = options.contains ? '' : '^';2529 const append = options.contains ? '' : '$';2530 2531 let output = `${prepend}(?:${input})${append}`;2532 if (state.negated === true) {2533 output = `(?:^(?!${output}).*$)`;2534 }2535 return output;2536 };2537 } (utils$3));2538 2539 const utils$2 = utils$3;2540 const {2541 CHAR_ASTERISK, /* * */2542 CHAR_AT, /* @ */2543 CHAR_BACKWARD_SLASH, /* \ */2544 CHAR_COMMA, /* , */2545 CHAR_DOT, /* . */2546 CHAR_EXCLAMATION_MARK, /* ! */2547 CHAR_FORWARD_SLASH, /* / */2548 CHAR_LEFT_CURLY_BRACE, /* { */2549 CHAR_LEFT_PARENTHESES, /* ( */2550 CHAR_LEFT_SQUARE_BRACKET, /* [ */2551 CHAR_PLUS, /* + */2552 CHAR_QUESTION_MARK, /* ? */2553 CHAR_RIGHT_CURLY_BRACE, /* } */2554 CHAR_RIGHT_PARENTHESES, /* ) */2555 CHAR_RIGHT_SQUARE_BRACKET /* ] */2556 } = constants$2;2557 2558 const isPathSeparator = code => {2559 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH;2560 };2561 2562 const depth = token => {2563 if (token.isPrefix !== true) {2564 token.depth = token.isGlobstar ? Infinity : 1;2565 }2566 };2567 2568 /**2569 * Quickly scans a glob pattern and returns an object with a handful of2570 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists),2571 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not2572 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`).2573 *2574 * ```js2575 * const pm = require('picomatch');2576 * console.log(pm.scan('foo/bar/*.js'));2577 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' }2578 * ```2579 * @param {String} `str`2580 * @param {Object} `options`2581 * @return {Object} Returns an object with tokens and regex source string.2582 * @api public2583 */2584 2585 const scan$1 = (input, options) => {2586 const opts = options || {};2587 2588 const length = input.length - 1;2589 const scanToEnd = opts.parts === true || opts.scanToEnd === true;2590 const slashes = [];2591 const tokens = [];2592 const parts = [];2593 2594 let str = input;2595 let index = -1;2596 let start = 0;2597 let lastIndex = 0;2598 let isBrace = false;2599 let isBracket = false;2600 let isGlob = false;2601 let isExtglob = false;2602 let isGlobstar = false;2603 let braceEscaped = false;2604 let backslashes = false;2605 let negated = false;2606 let negatedExtglob = false;2607 let finished = false;2608 let braces = 0;2609 let prev;2610 let code;2611 let token = { value: '', depth: 0, isGlob: false };2612 2613 const eos = () => index >= length;2614 const peek = () => str.charCodeAt(index + 1);2615 const advance = () => {2616 prev = code;2617 return str.charCodeAt(++index);2618 };2619 2620 while (index < length) {2621 code = advance();2622 let next;2623 2624 if (code === CHAR_BACKWARD_SLASH) {2625 backslashes = token.backslashes = true;2626 code = advance();2627 2628 if (code === CHAR_LEFT_CURLY_BRACE) {2629 braceEscaped = true;2630 }2631 continue;2632 }2633 2634 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) {2635 braces++;2636 2637 while (eos() !== true && (code = advance())) {2638 if (code === CHAR_BACKWARD_SLASH) {2639 backslashes = token.backslashes = true;2640 advance();2641 continue;2642 }2643 2644 if (code === CHAR_LEFT_CURLY_BRACE) {2645 braces++;2646 continue;2647 }2648 2649 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) {2650 isBrace = token.isBrace = true;2651 isGlob = token.isGlob = true;2652 finished = true;2653 2654 if (scanToEnd === true) {2655 continue;2656 }2657 2658 break;2659 }2660 2661 if (braceEscaped !== true && code === CHAR_COMMA) {2662 isBrace = token.isBrace = true;2663 isGlob = token.isGlob = true;2664 finished = true;2665 2666 if (scanToEnd === true) {2667 continue;2668 }2669 2670 break;2671 }2672 2673 if (code === CHAR_RIGHT_CURLY_BRACE) {2674 braces--;2675 2676 if (braces === 0) {2677 braceEscaped = false;2678 isBrace = token.isBrace = true;2679 finished = true;2680 break;2681 }2682 }2683 }2684 2685 if (scanToEnd === true) {2686 continue;2687 }2688 2689 break;2690 }2691 2692 if (code === CHAR_FORWARD_SLASH) {2693 slashes.push(index);2694 tokens.push(token);2695 token = { value: '', depth: 0, isGlob: false };2696 2697 if (finished === true) continue;2698 if (prev === CHAR_DOT && index === (start + 1)) {2699 start += 2;2700 continue;2701 }2702 2703 lastIndex = index + 1;2704 continue;2705 }2706 2707 if (opts.noext !== true) {2708 const isExtglobChar = code === CHAR_PLUS2709 || code === CHAR_AT2710 || code === CHAR_ASTERISK2711 || code === CHAR_QUESTION_MARK2712 || code === CHAR_EXCLAMATION_MARK;2713 2714 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) {2715 isGlob = token.isGlob = true;2716 isExtglob = token.isExtglob = true;2717 finished = true;2718 if (code === CHAR_EXCLAMATION_MARK && index === start) {2719 negatedExtglob = true;2720 }2721 2722 if (scanToEnd === true) {2723 while (eos() !== true && (code = advance())) {2724 if (code === CHAR_BACKWARD_SLASH) {2725 backslashes = token.backslashes = true;2726 code = advance();2727 continue;2728 }2729 2730 if (code === CHAR_RIGHT_PARENTHESES) {2731 isGlob = token.isGlob = true;2732 finished = true;2733 break;2734 }2735 }2736 continue;2737 }2738 break;2739 }2740 }2741 2742 if (code === CHAR_ASTERISK) {2743 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true;2744 isGlob = token.isGlob = true;2745 finished = true;2746 2747 if (scanToEnd === true) {2748 continue;2749 }2750 break;2751 }2752 2753 if (code === CHAR_QUESTION_MARK) {2754 isGlob = token.isGlob = true;2755 finished = true;2756 2757 if (scanToEnd === true) {2758 continue;2759 }2760 break;2761 }2762 2763 if (code === CHAR_LEFT_SQUARE_BRACKET) {2764 while (eos() !== true && (next = advance())) {2765 if (next === CHAR_BACKWARD_SLASH) {2766 backslashes = token.backslashes = true;2767 advance();2768 continue;2769 }2770 2771 if (next === CHAR_RIGHT_SQUARE_BRACKET) {2772 isBracket = token.isBracket = true;2773 isGlob = token.isGlob = true;2774 finished = true;2775 break;2776 }2777 }2778 2779 if (scanToEnd === true) {2780 continue;2781 }2782 2783 break;2784 }2785 2786 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) {2787 negated = token.negated = true;2788 start++;2789 continue;2790 }2791 2792 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) {2793 isGlob = token.isGlob = true;2794 2795 if (scanToEnd === true) {2796 while (eos() !== true && (code = advance())) {2797 if (code === CHAR_LEFT_PARENTHESES) {2798 backslashes = token.backslashes = true;2799 code = advance();2800 continue;2801 }2802 2803 if (code === CHAR_RIGHT_PARENTHESES) {2804 finished = true;2805 break;2806 }2807 }2808 continue;2809 }2810 break;2811 }2812 2813 if (isGlob === true) {2814 finished = true;2815 2816 if (scanToEnd === true) {2817 continue;2818 }2819 2820 break;2821 }2822 }2823 2824 if (opts.noext === true) {2825 isExtglob = false;2826 isGlob = false;2827 }2828 2829 let base = str;2830 let prefix = '';2831 let glob = '';2832 2833 if (start > 0) {2834 prefix = str.slice(0, start);2835 str = str.slice(start);2836 lastIndex -= start;2837 }2838 2839 if (base && isGlob === true && lastIndex > 0) {2840 base = str.slice(0, lastIndex);2841 glob = str.slice(lastIndex);2842 } else if (isGlob === true) {2843 base = '';2844 glob = str;2845 } else {2846 base = str;2847 }2848 2849 if (base && base !== '' && base !== '/' && base !== str) {2850 if (isPathSeparator(base.charCodeAt(base.length - 1))) {2851 base = base.slice(0, -1);2852 }2853 }2854 2855 if (opts.unescape === true) {2856 if (glob) glob = utils$2.removeBackslashes(glob);2857 2858 if (base && backslashes === true) {2859 base = utils$2.removeBackslashes(base);2860 }2861 }2862 2863 const state = {2864 prefix,2865 input,2866 start,2867 base,2868 glob,2869 isBrace,2870 isBracket,2871 isGlob,2872 isExtglob,2873 isGlobstar,2874 negated,2875 negatedExtglob2876 };2877 2878 if (opts.tokens === true) {2879 state.maxDepth = 0;2880 if (!isPathSeparator(code)) {2881 tokens.push(token);2882 }2883 state.tokens = tokens;2884 }2885 2886 if (opts.parts === true || opts.tokens === true) {2887 let prevIndex;2888 2889 for (let idx = 0; idx < slashes.length; idx++) {2890 const n = prevIndex ? prevIndex + 1 : start;2891 const i = slashes[idx];2892 const value = input.slice(n, i);2893 if (opts.tokens) {2894 if (idx === 0 && start !== 0) {2895 tokens[idx].isPrefix = true;2896 tokens[idx].value = prefix;2897 } else {2898 tokens[idx].value = value;2899 }2900 depth(tokens[idx]);2901 state.maxDepth += tokens[idx].depth;2902 }2903 if (idx !== 0 || value !== '') {2904 parts.push(value);2905 }2906 prevIndex = i;2907 }2908 2909 if (prevIndex && prevIndex + 1 < input.length) {2910 const value = input.slice(prevIndex + 1);2911 parts.push(value);2912 2913 if (opts.tokens) {2914 tokens[tokens.length - 1].value = value;2915 depth(tokens[tokens.length - 1]);2916 state.maxDepth += tokens[tokens.length - 1].depth;2917 }2918 }2919 2920 state.slashes = slashes;2921 state.parts = parts;2922 }2923 2924 return state;2925 };2926 2927 var scan_1 = scan$1;2928 2929 const constants$1 = constants$2;2930 const utils$1 = utils$3;2931 2932 /**2933 * Constants2934 */2935 2936 const {2937 MAX_LENGTH,2938 POSIX_REGEX_SOURCE,2939 REGEX_NON_SPECIAL_CHARS,2940 REGEX_SPECIAL_CHARS_BACKREF,2941 REPLACEMENTS2942 } = constants$1;2943 2944 /**2945 * Helpers2946 */2947 2948 const expandRange = (args, options) => {2949 if (typeof options.expandRange === 'function') {2950 return options.expandRange(...args, options);2951 }2952 2953 args.sort();2954 const value = `[${args.join('-')}]`;2955 2956 return value;2957 };2958 2959 /**2960 * Create the message for a syntax error2961 */2962 2963 const syntaxError = (type, char) => {2964 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`;2965 };2966 2967 /**2968 * Parse the given input string.2969 * @param {String} input2970 * @param {Object} options2971 * @return {Object}2972 */2973 2974 const parse$1 = (input, options) => {2975 if (typeof input !== 'string') {2976 throw new TypeError('Expected a string');2977 }2978 2979 input = REPLACEMENTS[input] || input;2980 2981 const opts = { ...options };2982 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;2983 2984 let len = input.length;2985 if (len > max) {2986 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);2987 }2988 2989 const bos = { type: 'bos', value: '', output: opts.prepend || '' };2990 const tokens = [bos];2991 2992 const capture = opts.capture ? '' : '?:';2993 const win32 = utils$1.isWindows(options);2994 2995 // create constants based on platform, for windows or posix2996 const PLATFORM_CHARS = constants$1.globChars(win32);2997 const EXTGLOB_CHARS = constants$1.extglobChars(PLATFORM_CHARS);2998 2999 const {3000 DOT_LITERAL,3001 PLUS_LITERAL,3002 SLASH_LITERAL,3003 ONE_CHAR,3004 DOTS_SLASH,3005 NO_DOT,3006 NO_DOT_SLASH,3007 NO_DOTS_SLASH,3008 QMARK,3009 QMARK_NO_DOT,3010 STAR,3011 START_ANCHOR3012 } = PLATFORM_CHARS;3013 3014 const globstar = opts => {3015 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;3016 };3017 3018 const nodot = opts.dot ? '' : NO_DOT;3019 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT;3020 let star = opts.bash === true ? globstar(opts) : STAR;3021 3022 if (opts.capture) {3023 star = `(${star})`;3024 }3025 3026 // minimatch options support3027 if (typeof opts.noext === 'boolean') {3028 opts.noextglob = opts.noext;3029 }3030 3031 const state = {3032 input,3033 index: -1,3034 start: 0,3035 dot: opts.dot === true,3036 consumed: '',3037 output: '',3038 prefix: '',3039 backtrack: false,3040 negated: false,3041 brackets: 0,3042 braces: 0,3043 parens: 0,3044 quotes: 0,3045 globstar: false,3046 tokens3047 };3048 3049 input = utils$1.removePrefix(input, state);3050 len = input.length;3051 3052 const extglobs = [];3053 const braces = [];3054 const stack = [];3055 let prev = bos;3056 let value;3057 3058 /**3059 * Tokenizing helpers3060 */3061 3062 const eos = () => state.index === len - 1;3063 const peek = state.peek = (n = 1) => input[state.index + n];3064 const advance = state.advance = () => input[++state.index] || '';3065 const remaining = () => input.slice(state.index + 1);3066 const consume = (value = '', num = 0) => {3067 state.consumed += value;3068 state.index += num;3069 };3070 3071 const append = token => {3072 state.output += token.output != null ? token.output : token.value;3073 consume(token.value);3074 };3075 3076 const negate = () => {3077 let count = 1;3078 3079 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) {3080 advance();3081 state.start++;3082 count++;3083 }3084 3085 if (count % 2 === 0) {3086 return false;3087 }3088 3089 state.negated = true;3090 state.start++;3091 return true;3092 };3093 3094 const increment = type => {3095 state[type]++;3096 stack.push(type);3097 };3098 3099 const decrement = type => {3100 state[type]--;3101 stack.pop();3102 };3103 3104 /**3105 * Push tokens onto the tokens array. This helper speeds up3106 * tokenizing by 1) helping us avoid backtracking as much as possible,3107 * and 2) helping us avoid creating extra tokens when consecutive3108 * characters are plain text. This improves performance and simplifies3109 * lookbehinds.3110 */3111 3112 const push = tok => {3113 if (prev.type === 'globstar') {3114 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace');3115 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren'));3116 3117 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) {3118 state.output = state.output.slice(0, -prev.output.length);3119 prev.type = 'star';3120 prev.value = '*';3121 prev.output = star;3122 state.output += prev.output;3123 }3124 }3125 3126 if (extglobs.length && tok.type !== 'paren') {3127 extglobs[extglobs.length - 1].inner += tok.value;3128 }3129 3130 if (tok.value || tok.output) append(tok);3131 if (prev && prev.type === 'text' && tok.type === 'text') {3132 prev.value += tok.value;3133 prev.output = (prev.output || '') + tok.value;3134 return;3135 }3136 3137 tok.prev = prev;3138 tokens.push(tok);3139 prev = tok;3140 };3141 3142 const extglobOpen = (type, value) => {3143 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' };3144 3145 token.prev = prev;3146 token.parens = state.parens;3147 token.output = state.output;3148 const output = (opts.capture ? '(' : '') + token.open;3149 3150 increment('parens');3151 push({ type, value, output: state.output ? '' : ONE_CHAR });3152 push({ type: 'paren', extglob: true, value: advance(), output });3153 extglobs.push(token);3154 };3155 3156 const extglobClose = token => {3157 let output = token.close + (opts.capture ? ')' : '');3158 let rest;3159 3160 if (token.type === 'negate') {3161 let extglobStar = star;3162 3163 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) {3164 extglobStar = globstar(opts);3165 }3166 3167 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) {3168 output = token.close = `)$))${extglobStar}`;3169 }3170 3171 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) {3172 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis.3173 // In this case, we need to parse the string and use it in the output of the original pattern.3174 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`.3175 //3176 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`.3177 const expression = parse$1(rest, { ...options, fastpaths: false }).output;3178 3179 output = token.close = `)${expression})${extglobStar})`;3180 }3181 3182 if (token.prev.type === 'bos') {3183 state.negatedExtglob = true;3184 }3185 }3186 3187 push({ type: 'paren', extglob: true, value, output });3188 decrement('parens');3189 };3190 3191 /**3192 * Fast paths3193 */3194 3195 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) {3196 let backslashes = false;3197 3198 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => {3199 if (first === '\\') {3200 backslashes = true;3201 return m;3202 }3203 3204 if (first === '?') {3205 if (esc) {3206 return esc + first + (rest ? QMARK.repeat(rest.length) : '');3207 }3208 if (index === 0) {3209 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : '');3210 }3211 return QMARK.repeat(chars.length);3212 }3213 3214 if (first === '.') {3215 return DOT_LITERAL.repeat(chars.length);3216 }3217 3218 if (first === '*') {3219 if (esc) {3220 return esc + first + (rest ? star : '');3221 }3222 return star;3223 }3224 return esc ? m : `\\${m}`;3225 });3226 3227 if (backslashes === true) {3228 if (opts.unescape === true) {3229 output = output.replace(/\\/g, '');3230 } else {3231 output = output.replace(/\\+/g, m => {3232 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : '');3233 });3234 }3235 }3236 3237 if (output === input && opts.contains === true) {3238 state.output = input;3239 return state;3240 }3241 3242 state.output = utils$1.wrapOutput(output, state, options);3243 return state;3244 }3245 3246 /**3247 * Tokenize input until we reach end-of-string3248 */3249 3250 while (!eos()) {3251 value = advance();3252 3253 if (value === '\u0000') {3254 continue;3255 }3256 3257 /**3258 * Escaped characters3259 */3260 3261 if (value === '\\') {3262 const next = peek();3263 3264 if (next === '/' && opts.bash !== true) {3265 continue;3266 }3267 3268 if (next === '.' || next === ';') {3269 continue;3270 }3271 3272 if (!next) {3273 value += '\\';3274 push({ type: 'text', value });3275 continue;3276 }3277 3278 // collapse slashes to reduce potential for exploits3279 const match = /^\\+/.exec(remaining());3280 let slashes = 0;3281 3282 if (match && match[0].length > 2) {3283 slashes = match[0].length;3284 state.index += slashes;3285 if (slashes % 2 !== 0) {3286 value += '\\';3287 }3288 }3289 3290 if (opts.unescape === true) {3291 value = advance();3292 } else {3293 value += advance();3294 }3295 3296 if (state.brackets === 0) {3297 push({ type: 'text', value });3298 continue;3299 }3300 }3301 3302 /**3303 * If we're inside a regex character class, continue3304 * until we reach the closing bracket.3305 */3306 3307 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) {3308 if (opts.posix !== false && value === ':') {3309 const inner = prev.value.slice(1);3310 if (inner.includes('[')) {3311 prev.posix = true;3312 3313 if (inner.includes(':')) {3314 const idx = prev.value.lastIndexOf('[');3315 const pre = prev.value.slice(0, idx);3316 const rest = prev.value.slice(idx + 2);3317 const posix = POSIX_REGEX_SOURCE[rest];3318 if (posix) {3319 prev.value = pre + posix;3320 state.backtrack = true;3321 advance();3322 3323 if (!bos.output && tokens.indexOf(prev) === 1) {3324 bos.output = ONE_CHAR;3325 }3326 continue;3327 }3328 }3329 }3330 }3331 3332 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) {3333 value = `\\${value}`;3334 }3335 3336 if (value === ']' && (prev.value === '[' || prev.value === '[^')) {3337 value = `\\${value}`;3338 }3339 3340 if (opts.posix === true && value === '!' && prev.value === '[') {3341 value = '^';3342 }3343 3344 prev.value += value;3345 append({ value });3346 continue;3347 }3348 3349 /**3350 * If we're inside a quoted string, continue3351 * until we reach the closing double quote.3352 */3353 3354 if (state.quotes === 1 && value !== '"') {3355 value = utils$1.escapeRegex(value);3356 prev.value += value;3357 append({ value });3358 continue;3359 }3360 3361 /**3362 * Double quotes3363 */3364 3365 if (value === '"') {3366 state.quotes = state.quotes === 1 ? 0 : 1;3367 if (opts.keepQuotes === true) {3368 push({ type: 'text', value });3369 }3370 continue;3371 }3372 3373 /**3374 * Parentheses3375 */3376 3377 if (value === '(') {3378 increment('parens');3379 push({ type: 'paren', value });3380 continue;3381 }3382 3383 if (value === ')') {3384 if (state.parens === 0 && opts.strictBrackets === true) {3385 throw new SyntaxError(syntaxError('opening', '('));3386 }3387 3388 const extglob = extglobs[extglobs.length - 1];3389 if (extglob && state.parens === extglob.parens + 1) {3390 extglobClose(extglobs.pop());3391 continue;3392 }3393 3394 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' });3395 decrement('parens');3396 continue;3397 }3398 3399 /**3400 * Square brackets3401 */3402 3403 if (value === '[') {3404 if (opts.nobracket === true || !remaining().includes(']')) {3405 if (opts.nobracket !== true && opts.strictBrackets === true) {3406 throw new SyntaxError(syntaxError('closing', ']'));3407 }3408 3409 value = `\\${value}`;3410 } else {3411 increment('brackets');3412 }3413 3414 push({ type: 'bracket', value });3415 continue;3416 }3417 3418 if (value === ']') {3419 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) {3420 push({ type: 'text', value, output: `\\${value}` });3421 continue;3422 }3423 3424 if (state.brackets === 0) {3425 if (opts.strictBrackets === true) {3426 throw new SyntaxError(syntaxError('opening', '['));3427 }3428 3429 push({ type: 'text', value, output: `\\${value}` });3430 continue;3431 }3432 3433 decrement('brackets');3434 3435 const prevValue = prev.value.slice(1);3436 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) {3437 value = `/${value}`;3438 }3439 3440 prev.value += value;3441 append({ value });3442 3443 // when literal brackets are explicitly disabled3444 // assume we should match with a regex character class3445 if (opts.literalBrackets === false || utils$1.hasRegexChars(prevValue)) {3446 continue;3447 }3448 3449 const escaped = utils$1.escapeRegex(prev.value);3450 state.output = state.output.slice(0, -prev.value.length);3451 3452 // when literal brackets are explicitly enabled3453 // assume we should escape the brackets to match literal characters3454 if (opts.literalBrackets === true) {3455 state.output += escaped;3456 prev.value = escaped;3457 continue;3458 }3459 3460 // when the user specifies nothing, try to match both3461 prev.value = `(${capture}${escaped}|${prev.value})`;3462 state.output += prev.value;3463 continue;3464 }3465 3466 /**3467 * Braces3468 */3469 3470 if (value === '{' && opts.nobrace !== true) {3471 increment('braces');3472 3473 const open = {3474 type: 'brace',3475 value,3476 output: '(',3477 outputIndex: state.output.length,3478 tokensIndex: state.tokens.length3479 };3480 3481 braces.push(open);3482 push(open);3483 continue;3484 }3485 3486 if (value === '}') {3487 const brace = braces[braces.length - 1];3488 3489 if (opts.nobrace === true || !brace) {3490 push({ type: 'text', value, output: value });3491 continue;3492 }3493 3494 let output = ')';3495 3496 if (brace.dots === true) {3497 const arr = tokens.slice();3498 const range = [];3499 3500 for (let i = arr.length - 1; i >= 0; i--) {3501 tokens.pop();3502 if (arr[i].type === 'brace') {3503 break;3504 }3505 if (arr[i].type !== 'dots') {3506 range.unshift(arr[i].value);3507 }3508 }3509 3510 output = expandRange(range, opts);3511 state.backtrack = true;3512 }3513 3514 if (brace.comma !== true && brace.dots !== true) {3515 const out = state.output.slice(0, brace.outputIndex);3516 const toks = state.tokens.slice(brace.tokensIndex);3517 brace.value = brace.output = '\\{';3518 value = output = '\\}';3519 state.output = out;3520 for (const t of toks) {3521 state.output += (t.output || t.value);3522 }3523 }3524 3525 push({ type: 'brace', value, output });3526 decrement('braces');3527 braces.pop();3528 continue;3529 }3530 3531 /**3532 * Pipes3533 */3534 3535 if (value === '|') {3536 if (extglobs.length > 0) {3537 extglobs[extglobs.length - 1].conditions++;3538 }3539 push({ type: 'text', value });3540 continue;3541 }3542 3543 /**3544 * Commas3545 */3546 3547 if (value === ',') {3548 let output = value;3549 3550 const brace = braces[braces.length - 1];3551 if (brace && stack[stack.length - 1] === 'braces') {3552 brace.comma = true;3553 output = '|';3554 }3555 3556 push({ type: 'comma', value, output });3557 continue;3558 }3559 3560 /**3561 * Slashes3562 */3563 3564 if (value === '/') {3565 // if the beginning of the glob is "./", advance the start3566 // to the current index, and don't add the "./" characters3567 // to the state. This greatly simplifies lookbehinds when3568 // checking for BOS characters like "!" and "." (not "./")3569 if (prev.type === 'dot' && state.index === state.start + 1) {3570 state.start = state.index + 1;3571 state.consumed = '';3572 state.output = '';3573 tokens.pop();3574 prev = bos; // reset "prev" to the first token3575 continue;3576 }3577 3578 push({ type: 'slash', value, output: SLASH_LITERAL });3579 continue;3580 }3581 3582 /**3583 * Dots3584 */3585 3586 if (value === '.') {3587 if (state.braces > 0 && prev.type === 'dot') {3588 if (prev.value === '.') prev.output = DOT_LITERAL;3589 const brace = braces[braces.length - 1];3590 prev.type = 'dots';3591 prev.output += value;3592 prev.value += value;3593 brace.dots = true;3594 continue;3595 }3596 3597 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') {3598 push({ type: 'text', value, output: DOT_LITERAL });3599 continue;3600 }3601 3602 push({ type: 'dot', value, output: DOT_LITERAL });3603 continue;3604 }3605 3606 /**3607 * Question marks3608 */3609 3610 if (value === '?') {3611 const isGroup = prev && prev.value === '(';3612 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {3613 extglobOpen('qmark', value);3614 continue;3615 }3616 3617 if (prev && prev.type === 'paren') {3618 const next = peek();3619 let output = value;3620 3621 if (next === '<' && !utils$1.supportsLookbehinds()) {3622 throw new Error('Node.js v10 or higher is required for regex lookbehinds');3623 }3624 3625 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) {3626 output = `\\${value}`;3627 }3628 3629 push({ type: 'text', value, output });3630 continue;3631 }3632 3633 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) {3634 push({ type: 'qmark', value, output: QMARK_NO_DOT });3635 continue;3636 }3637 3638 push({ type: 'qmark', value, output: QMARK });3639 continue;3640 }3641 3642 /**3643 * Exclamation3644 */3645 3646 if (value === '!') {3647 if (opts.noextglob !== true && peek() === '(') {3648 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) {3649 extglobOpen('negate', value);3650 continue;3651 }3652 }3653 3654 if (opts.nonegate !== true && state.index === 0) {3655 negate();3656 continue;3657 }3658 }3659 3660 /**3661 * Plus3662 */3663 3664 if (value === '+') {3665 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {3666 extglobOpen('plus', value);3667 continue;3668 }3669 3670 if ((prev && prev.value === '(') || opts.regex === false) {3671 push({ type: 'plus', value, output: PLUS_LITERAL });3672 continue;3673 }3674 3675 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) {3676 push({ type: 'plus', value });3677 continue;3678 }3679 3680 push({ type: 'plus', value: PLUS_LITERAL });3681 continue;3682 }3683 3684 /**3685 * Plain text3686 */3687 3688 if (value === '@') {3689 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') {3690 push({ type: 'at', extglob: true, value, output: '' });3691 continue;3692 }3693 3694 push({ type: 'text', value });3695 continue;3696 }3697 3698 /**3699 * Plain text3700 */3701 3702 if (value !== '*') {3703 if (value === '$' || value === '^') {3704 value = `\\${value}`;3705 }3706 3707 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());3708 if (match) {3709 value += match[0];3710 state.index += match[0].length;3711 }3712 3713 push({ type: 'text', value });3714 continue;3715 }3716 3717 /**3718 * Stars3719 */3720 3721 if (prev && (prev.type === 'globstar' || prev.star === true)) {3722 prev.type = 'star';3723 prev.star = true;3724 prev.value += value;3725 prev.output = star;3726 state.backtrack = true;3727 state.globstar = true;3728 consume(value);3729 continue;3730 }3731 3732 let rest = remaining();3733 if (opts.noextglob !== true && /^\([^?]/.test(rest)) {3734 extglobOpen('star', value);3735 continue;3736 }3737 3738 if (prev.type === 'star') {3739 if (opts.noglobstar === true) {3740 consume(value);3741 continue;3742 }3743 3744 const prior = prev.prev;3745 const before = prior.prev;3746 const isStart = prior.type === 'slash' || prior.type === 'bos';3747 const afterStar = before && (before.type === 'star' || before.type === 'globstar');3748 3749 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) {3750 push({ type: 'star', value, output: '' });3751 continue;3752 }3753 3754 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace');3755 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren');3756 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) {3757 push({ type: 'star', value, output: '' });3758 continue;3759 }3760 3761 // strip consecutive `/**/`3762 while (rest.slice(0, 3) === '/**') {3763 const after = input[state.index + 4];3764 if (after && after !== '/') {3765 break;3766 }3767 rest = rest.slice(3);3768 consume('/**', 3);3769 }3770 3771 if (prior.type === 'bos' && eos()) {3772 prev.type = 'globstar';3773 prev.value += value;3774 prev.output = globstar(opts);3775 state.output = prev.output;3776 state.globstar = true;3777 consume(value);3778 continue;3779 }3780 3781 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) {3782 state.output = state.output.slice(0, -(prior.output + prev.output).length);3783 prior.output = `(?:${prior.output}`;3784 3785 prev.type = 'globstar';3786 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)');3787 prev.value += value;3788 state.globstar = true;3789 state.output += prior.output + prev.output;3790 consume(value);3791 continue;3792 }3793 3794 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') {3795 const end = rest[1] !== void 0 ? '|$' : '';3796 3797 state.output = state.output.slice(0, -(prior.output + prev.output).length);3798 prior.output = `(?:${prior.output}`;3799 3800 prev.type = 'globstar';3801 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;3802 prev.value += value;3803 3804 state.output += prior.output + prev.output;3805 state.globstar = true;3806 3807 consume(value + advance());3808 3809 push({ type: 'slash', value: '/', output: '' });3810 continue;3811 }3812 3813 if (prior.type === 'bos' && rest[0] === '/') {3814 prev.type = 'globstar';3815 prev.value += value;3816 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;3817 state.output = prev.output;3818 state.globstar = true;3819 consume(value + advance());3820 push({ type: 'slash', value: '/', output: '' });3821 continue;3822 }3823 3824 // remove single star from output3825 state.output = state.output.slice(0, -prev.output.length);3826 3827 // reset previous token to globstar3828 prev.type = 'globstar';3829 prev.output = globstar(opts);3830 prev.value += value;3831 3832 // reset output with globstar3833 state.output += prev.output;3834 state.globstar = true;3835 consume(value);3836 continue;3837 }3838 3839 const token = { type: 'star', value, output: star };3840 3841 if (opts.bash === true) {3842 token.output = '.*?';3843 if (prev.type === 'bos' || prev.type === 'slash') {3844 token.output = nodot + token.output;3845 }3846 push(token);3847 continue;3848 }3849 3850 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) {3851 token.output = value;3852 push(token);3853 continue;3854 }3855 3856 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') {3857 if (prev.type === 'dot') {3858 state.output += NO_DOT_SLASH;3859 prev.output += NO_DOT_SLASH;3860 3861 } else if (opts.dot === true) {3862 state.output += NO_DOTS_SLASH;3863 prev.output += NO_DOTS_SLASH;3864 3865 } else {3866 state.output += nodot;3867 prev.output += nodot;3868 }3869 3870 if (peek() !== '*') {3871 state.output += ONE_CHAR;3872 prev.output += ONE_CHAR;3873 }3874 }3875 3876 push(token);3877 }3878 3879 while (state.brackets > 0) {3880 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']'));3881 state.output = utils$1.escapeLast(state.output, '[');3882 decrement('brackets');3883 }3884 3885 while (state.parens > 0) {3886 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')'));3887 state.output = utils$1.escapeLast(state.output, '(');3888 decrement('parens');3889 }3890 3891 while (state.braces > 0) {3892 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}'));3893 state.output = utils$1.escapeLast(state.output, '{');3894 decrement('braces');3895 }3896 3897 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) {3898 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` });3899 }3900 3901 // rebuild the output if we had to backtrack at any point3902 if (state.backtrack === true) {3903 state.output = '';3904 3905 for (const token of state.tokens) {3906 state.output += token.output != null ? token.output : token.value;3907 3908 if (token.suffix) {3909 state.output += token.suffix;3910 }3911 }3912 }3913 3914 return state;3915 };3916 3917 /**3918 * Fast paths for creating regular expressions for common glob patterns.3919 * This can significantly speed up processing and has very little downside3920 * impact when none of the fast paths match.3921 */3922 3923 parse$1.fastpaths = (input, options) => {3924 const opts = { ...options };3925 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH;3926 const len = input.length;3927 if (len > max) {3928 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`);3929 }3930 3931 input = REPLACEMENTS[input] || input;3932 const win32 = utils$1.isWindows(options);3933 3934 // create constants based on platform, for windows or posix3935 const {3936 DOT_LITERAL,3937 SLASH_LITERAL,3938 ONE_CHAR,3939 DOTS_SLASH,3940 NO_DOT,3941 NO_DOTS,3942 NO_DOTS_SLASH,3943 STAR,3944 START_ANCHOR3945 } = constants$1.globChars(win32);3946 3947 const nodot = opts.dot ? NO_DOTS : NO_DOT;3948 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;3949 const capture = opts.capture ? '' : '?:';3950 const state = { negated: false, prefix: '' };3951 let star = opts.bash === true ? '.*?' : STAR;3952 3953 if (opts.capture) {3954 star = `(${star})`;3955 }3956 3957 const globstar = opts => {3958 if (opts.noglobstar === true) return star;3959 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`;3960 };3961 3962 const create = str => {3963 switch (str) {3964 case '*':3965 return `${nodot}${ONE_CHAR}${star}`;3966 3967 case '.*':3968 return `${DOT_LITERAL}${ONE_CHAR}${star}`;3969 3970 case '*.*':3971 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;3972 3973 case '*/*':3974 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`;3975 3976 case '**':3977 return nodot + globstar(opts);3978 3979 case '**/*':3980 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`;3981 3982 case '**/*.*':3983 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`;3984 3985 case '**/.*':3986 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`;3987 3988 default: {3989 const match = /^(.*?)\.(\w+)$/.exec(str);3990 if (!match) return;3991 3992 const source = create(match[1]);3993 if (!source) return;3994 3995 return source + DOT_LITERAL + match[2];3996 }3997 }3998 };3999 4000 const output = utils$1.removePrefix(input, state);4001 let source = create(output);4002 4003 if (source && opts.strictSlashes !== true) {4004 source += `${SLASH_LITERAL}?`;4005 }4006 4007 return source;4008 };4009 4010 var parse_1 = parse$1;4011 4012 const path = require$$0;4013 const scan = scan_1;4014 const parse = parse_1;4015 const utils = utils$3;4016 const constants = constants$2;4017 const isObject = val => val && typeof val === 'object' && !Array.isArray(val);4018 4019 /**4020 * Creates a matcher function from one or more glob patterns. The4021 * returned function takes a string to match as its first argument,4022 * and returns true if the string is a match. The returned matcher4023 * function also takes a boolean as the second argument that, when true,4024 * returns an object with additional information.4025 *4026 * ```js4027 * const picomatch = require('picomatch');4028 * // picomatch(glob[, options]);4029 *4030 * const isMatch = picomatch('*.!(*a)');4031 * console.log(isMatch('a.a')); //=> false4032 * console.log(isMatch('a.b')); //=> true4033 * ```4034 * @name picomatch4035 * @param {String|Array} `globs` One or more glob patterns.4036 * @param {Object=} `options`4037 * @return {Function=} Returns a matcher function.4038 * @api public4039 */4040 4041 const picomatch$1 = (glob, options, returnState = false) => {4042 if (Array.isArray(glob)) {4043 const fns = glob.map(input => picomatch$1(input, options, returnState));4044 const arrayMatcher = str => {4045 for (const isMatch of fns) {4046 const state = isMatch(str);4047 if (state) return state;4048 }4049 return false;4050 };4051 return arrayMatcher;4052 }4053 4054 const isState = isObject(glob) && glob.tokens && glob.input;4055 4056 if (glob === '' || (typeof glob !== 'string' && !isState)) {4057 throw new TypeError('Expected pattern to be a non-empty string');4058 }4059 4060 const opts = options || {};4061 const posix = utils.isWindows(options);4062 const regex = isState4063 ? picomatch$1.compileRe(glob, options)4064 : picomatch$1.makeRe(glob, options, false, true);4065 4066 const state = regex.state;4067 delete regex.state;4068 4069 let isIgnored = () => false;4070 if (opts.ignore) {4071 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null };4072 isIgnored = picomatch$1(opts.ignore, ignoreOpts, returnState);4073 }4074 4075 const matcher = (input, returnObject = false) => {4076 const { isMatch, match, output } = picomatch$1.test(input, regex, options, { glob, posix });4077 const result = { glob, state, regex, posix, input, output, match, isMatch };4078 4079 if (typeof opts.onResult === 'function') {4080 opts.onResult(result);4081 }4082 4083 if (isMatch === false) {4084 result.isMatch = false;4085 return returnObject ? result : false;4086 }4087 4088 if (isIgnored(input)) {4089 if (typeof opts.onIgnore === 'function') {4090 opts.onIgnore(result);4091 }4092 result.isMatch = false;4093 return returnObject ? result : false;4094 }4095 4096 if (typeof opts.onMatch === 'function') {4097 opts.onMatch(result);4098 }4099 return returnObject ? result : true;4100 };4101 4102 if (returnState) {4103 matcher.state = state;4104 }4105 4106 return matcher;4107 };4108 4109 /**4110 * Test `input` with the given `regex`. This is used by the main4111 * `picomatch()` function to test the input string.4112 *4113 * ```js4114 * const picomatch = require('picomatch');4115 * // picomatch.test(input, regex[, options]);4116 *4117 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/));4118 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' }4119 * ```4120 * @param {String} `input` String to test.4121 * @param {RegExp} `regex`4122 * @return {Object} Returns an object with matching info.4123 * @api public4124 */4125 4126 picomatch$1.test = (input, regex, options, { glob, posix } = {}) => {4127 if (typeof input !== 'string') {4128 throw new TypeError('Expected input to be a string');4129 }4130 4131 if (input === '') {4132 return { isMatch: false, output: '' };4133 }4134 4135 const opts = options || {};4136 const format = opts.format || (posix ? utils.toPosixSlashes : null);4137 let match = input === glob;4138 let output = (match && format) ? format(input) : input;4139 4140 if (match === false) {4141 output = format ? format(input) : input;4142 match = output === glob;4143 }4144 4145 if (match === false || opts.capture === true) {4146 if (opts.matchBase === true || opts.basename === true) {4147 match = picomatch$1.matchBase(input, regex, options, posix);4148 } else {4149 match = regex.exec(output);4150 }4151 }4152 4153 return { isMatch: Boolean(match), match, output };4154 };4155 4156 /**4157 * Match the basename of a filepath.4158 *4159 * ```js4160 * const picomatch = require('picomatch');4161 * // picomatch.matchBase(input, glob[, options]);4162 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true4163 * ```4164 * @param {String} `input` String to test.4165 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe).4166 * @return {Boolean}4167 * @api public4168 */4169 4170 picomatch$1.matchBase = (input, glob, options, posix = utils.isWindows(options)) => {4171 const regex = glob instanceof RegExp ? glob : picomatch$1.makeRe(glob, options);4172 return regex.test(path.basename(input));4173 };4174 4175 /**4176 * Returns true if **any** of the given glob `patterns` match the specified `string`.4177 *4178 * ```js4179 * const picomatch = require('picomatch');4180 * // picomatch.isMatch(string, patterns[, options]);4181 *4182 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true4183 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false4184 * ```4185 * @param {String|Array} str The string to test.4186 * @param {String|Array} patterns One or more glob patterns to use for matching.4187 * @param {Object} [options] See available [options](#options).4188 * @return {Boolean} Returns true if any patterns match `str`4189 * @api public4190 */4191 4192 picomatch$1.isMatch = (str, patterns, options) => picomatch$1(patterns, options)(str);4193 4194 /**4195 * Parse a glob pattern to create the source string for a regular4196 * expression.4197 *4198 * ```js4199 * const picomatch = require('picomatch');4200 * const result = picomatch.parse(pattern[, options]);4201 * ```4202 * @param {String} `pattern`4203 * @param {Object} `options`4204 * @return {Object} Returns an object with useful properties and output to be used as a regex source string.4205 * @api public4206 */4207 4208 picomatch$1.parse = (pattern, options) => {4209 if (Array.isArray(pattern)) return pattern.map(p => picomatch$1.parse(p, options));4210 return parse(pattern, { ...options, fastpaths: false });4211 };4212 4213 /**4214 * Scan a glob pattern to separate the pattern into segments.4215 *4216 * ```js4217 * const picomatch = require('picomatch');4218 * // picomatch.scan(input[, options]);4219 *4220 * const result = picomatch.scan('!./foo/*.js');4221 * console.log(result);4222 * { prefix: '!./',4223 * input: '!./foo/*.js',4224 * start: 3,4225 * base: 'foo',4226 * glob: '*.js',4227 * isBrace: false,4228 * isBracket: false,4229 * isGlob: true,4230 * isExtglob: false,4231 * isGlobstar: false,4232 * negated: true }4233 * ```4234 * @param {String} `input` Glob pattern to scan.4235 * @param {Object} `options`4236 * @return {Object} Returns an object with4237 * @api public4238 */4239 4240 picomatch$1.scan = (input, options) => scan(input, options);4241 4242 /**4243 * Compile a regular expression from the `state` object returned by the4244 * [parse()](#parse) method.4245 *4246 * @param {Object} `state`4247 * @param {Object} `options`4248 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser.4249 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging.4250 * @return {RegExp}4251 * @api public4252 */4253 4254 picomatch$1.compileRe = (state, options, returnOutput = false, returnState = false) => {4255 if (returnOutput === true) {4256 return state.output;4257 }4258 4259 const opts = options || {};4260 const prepend = opts.contains ? '' : '^';4261 const append = opts.contains ? '' : '$';4262 4263 let source = `${prepend}(?:${state.output})${append}`;4264 if (state && state.negated === true) {4265 source = `^(?!${source}).*$`;4266 }4267 4268 const regex = picomatch$1.toRegex(source, options);4269 if (returnState === true) {4270 regex.state = state;4271 }4272 4273 return regex;4274 };4275 4276 /**4277 * Create a regular expression from a parsed glob pattern.4278 *4279 * ```js4280 * const picomatch = require('picomatch');4281 * const state = picomatch.parse('*.js');4282 * // picomatch.compileRe(state[, options]);4283 *4284 * console.log(picomatch.compileRe(state));4285 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/4286 * ```4287 * @param {String} `state` The object returned from the `.parse` method.4288 * @param {Object} `options`4289 * @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.4290 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression.4291 * @return {RegExp} Returns a regex created from the given pattern.4292 * @api public4293 */4294 4295 picomatch$1.makeRe = (input, options = {}, returnOutput = false, returnState = false) => {4296 if (!input || typeof input !== 'string') {4297 throw new TypeError('Expected a non-empty string');4298 }4299 4300 let parsed = { negated: false, fastpaths: true };4301 4302 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) {4303 parsed.output = parse.fastpaths(input, options);4304 }4305 4306 if (!parsed.output) {4307 parsed = parse(input, options);4308 }4309 4310 return picomatch$1.compileRe(parsed, options, returnOutput, returnState);4311 };4312 4313 /**4314 * Create a regular expression from the given regex source string.4315 *4316 * ```js4317 * const picomatch = require('picomatch');4318 * // picomatch.toRegex(source[, options]);4319 *4320 * const { output } = picomatch.parse('*.js');4321 * console.log(picomatch.toRegex(output));4322 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/4323 * ```4324 * @param {String} `source` Regular expression source string.4325 * @param {Object} `options`4326 * @return {RegExp}4327 * @api public4328 */4329 4330 picomatch$1.toRegex = (source, options) => {4331 try {4332 const opts = options || {};4333 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : ''));4334 } catch (err) {4335 if (options && options.debug === true) throw err;4336 return /$^/;4337 }4338 };4339 4340 /**4341 * Picomatch constants.4342 * @return {Object}4343 */4344 4345 picomatch$1.constants = constants;4346 4347 /**4348 * Expose "picomatch"4349 */4350 4351 var picomatch_1 = picomatch$1;4352 4353 var picomatch = picomatch_1;4354 4355 const pm = /*@__PURE__*/getDefaultExportFromCjs(picomatch);4356 4357 const extractors = {4358 ArrayPattern(names, param) {4359 for (const element of param.elements) {4360 if (element)4361 extractors[element.type](names, element);4362 }4363 },4364 AssignmentPattern(names, param) {4365 extractors[param.left.type](names, param.left);4366 },4367 Identifier(names, param) {4368 names.push(param.name);4369 },4370 MemberExpression() { },4371 ObjectPattern(names, param) {4372 for (const prop of param.properties) {4373 // @ts-ignore Typescript reports that this is not a valid type4374 if (prop.type === 'RestElement') {4375 extractors.RestElement(names, prop);4376 }4377 else {4378 extractors[prop.value.type](names, prop.value);4379 }4380 }4381 },4382 RestElement(names, param) {4383 extractors[param.argument.type](names, param.argument);4384 }4385 };4386 const extractAssignedNames = function extractAssignedNames(param) {4387 const names = [];4388 extractors[param.type](names, param);4389 return names;4390 };4391 4392 // Helper since Typescript can't detect readonly arrays with Array.isArray4393 function isArray(arg) {4394 return Array.isArray(arg);4395 }4396 function ensureArray$1(thing) {4397 if (isArray(thing))4398 return thing;4399 if (thing == null)4400 return [];4401 return [thing];4402 }4403 4404 const normalizePath = function normalizePath(filename) {4405 return filename.split(win32.sep).join(posix.sep);4406 };4407 4408 function getMatcherString(id, resolutionBase) {4409 if (resolutionBase === false || isAbsolute(id) || id.startsWith('**')) {4410 return normalizePath(id);4411 }4412 // resolve('') is valid and will default to process.cwd()4413 const basePath = normalizePath(resolve(resolutionBase || ''))4414 // escape all possible (posix + win) path characters that might interfere with regex4415 .replace(/[-^$*+?.()|[\]{}]/g, '\\$&');4416 // Note that we use posix.join because:4417 // 1. the basePath has been normalized to use /4418 // 2. the incoming glob (id) matcher, also uses /4419 // otherwise Node will force backslash (\) on windows4420 return posix.join(basePath, normalizePath(id));4421 }4422 const createFilter = function createFilter(include, exclude, options) {4423 const resolutionBase = options && options.resolve;4424 const getMatcher = (id) => id instanceof RegExp4425 ? id4426 : {4427 test: (what) => {4428 // this refactor is a tad overly verbose but makes for easy debugging4429 const pattern = getMatcherString(id, resolutionBase);4430 const fn = pm(pattern, { dot: true });4431 const result = fn(what);4432 return result;4433 }4434 };4435 const includeMatchers = ensureArray$1(include).map(getMatcher);4436 const excludeMatchers = ensureArray$1(exclude).map(getMatcher);4437 return function result(id) {4438 if (typeof id !== 'string')4439 return false;4440 if (/\0/.test(id))4441 return false;4442 const pathId = normalizePath(id);4443 for (let i = 0; i < excludeMatchers.length; ++i) {4444 const matcher = excludeMatchers[i];4445 if (matcher.test(pathId))4446 return false;4447 }4448 for (let i = 0; i < includeMatchers.length; ++i) {4449 const matcher = includeMatchers[i];4450 if (matcher.test(pathId))4451 return true;4452 }4453 return !includeMatchers.length;4454 };4455 };4456 4457 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';4458 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';4459 const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));4460 forbiddenIdentifiers.add('');4461 2592 4462 2593 function createInclusionContext() { … … 4488 2619 replacedVariableInits: new Map() 4489 2620 }; 2621 } 2622 2623 const INCLUDE_PARAMETERS = 'variables'; 2624 const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN'); 2625 class NodeBase extends ExpressionEntity { 2626 /** 2627 * Nodes can apply custom deoptimizations once they become part of the 2628 * executed code. To do this, they must initialize this as false, implement 2629 * applyDeoptimizations and call this from include and hasEffects if they have 2630 * custom handlers 2631 */ 2632 get deoptimized() { 2633 return isFlagSet(this.flags, 2 /* Flag.deoptimized */); 2634 } 2635 set deoptimized(value) { 2636 this.flags = setFlag(this.flags, 2 /* Flag.deoptimized */, value); 2637 } 2638 constructor(parent, parentScope) { 2639 super(); 2640 this.parent = parent; 2641 this.scope = parentScope; 2642 this.createScope(parentScope); 2643 } 2644 addExportedVariables(_variables, _exportNamesByVariable) { } 2645 /** 2646 * Override this to bind assignments to variables and do any initialisations 2647 * that require the scopes to be populated with variables. 2648 */ 2649 bind() { 2650 for (const key of childNodeKeys[this.type]) { 2651 const value = this[key]; 2652 if (Array.isArray(value)) { 2653 for (const child of value) { 2654 child?.bind(); 2655 } 2656 } 2657 else if (value) { 2658 value.bind(); 2659 } 2660 } 2661 } 2662 /** 2663 * Override if this node should receive a different scope than the parent 2664 * scope. 2665 */ 2666 createScope(parentScope) { 2667 this.scope = parentScope; 2668 } 2669 hasEffects(context) { 2670 if (!this.deoptimized) 2671 this.applyDeoptimizations(); 2672 for (const key of childNodeKeys[this.type]) { 2673 const value = this[key]; 2674 if (value === null) 2675 continue; 2676 if (Array.isArray(value)) { 2677 for (const child of value) { 2678 if (child?.hasEffects(context)) 2679 return true; 2680 } 2681 } 2682 else if (value.hasEffects(context)) 2683 return true; 2684 } 2685 return false; 2686 } 2687 hasEffectsAsAssignmentTarget(context, _checkAccess) { 2688 return (this.hasEffects(context) || 2689 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context)); 2690 } 2691 include(context, includeChildrenRecursively, _options) { 2692 if (!this.deoptimized) 2693 this.applyDeoptimizations(); 2694 this.included = true; 2695 for (const key of childNodeKeys[this.type]) { 2696 const value = this[key]; 2697 if (value === null) 2698 continue; 2699 if (Array.isArray(value)) { 2700 for (const child of value) { 2701 child?.include(context, includeChildrenRecursively); 2702 } 2703 } 2704 else { 2705 value.include(context, includeChildrenRecursively); 2706 } 2707 } 2708 } 2709 includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) { 2710 this.include(context, includeChildrenRecursively); 2711 } 2712 /** 2713 * Override to perform special initialisation steps after the scope is 2714 * initialised 2715 */ 2716 initialise() { 2717 this.scope.context.magicString.addSourcemapLocation(this.start); 2718 this.scope.context.magicString.addSourcemapLocation(this.end); 2719 } 2720 parseNode(esTreeNode) { 2721 for (const [key, value] of Object.entries(esTreeNode)) { 2722 // Skip properties defined on the class already. 2723 // This way, we can override this function to add custom initialisation and then call super.parseNode 2724 // Note: this doesn't skip properties with defined getters/setters which we use to pack wrap booleans 2725 // in bitfields. Those are still assigned from the value in the esTreeNode. 2726 if (this.hasOwnProperty(key)) 2727 continue; 2728 if (key.charCodeAt(0) === 95 /* _ */) { 2729 if (key === ANNOTATION_KEY) { 2730 this.annotations = value; 2731 } 2732 else if (key === INVALID_ANNOTATION_KEY) { 2733 this.invalidAnnotations = value; 2734 } 2735 } 2736 else if (typeof value !== 'object' || value === null) { 2737 this[key] = value; 2738 } 2739 else if (Array.isArray(value)) { 2740 this[key] = new Array(value.length); 2741 let index = 0; 2742 for (const child of value) { 2743 this[key][index++] = 2744 child === null 2745 ? null 2746 : new (this.scope.context.getNodeConstructor(child.type))(this, this.scope).parseNode(child); 2747 } 2748 } 2749 else { 2750 this[key] = new (this.scope.context.getNodeConstructor(value.type))(this, this.scope).parseNode(value); 2751 } 2752 } 2753 // extend child keys for unknown node types 2754 childNodeKeys[esTreeNode.type] ||= createChildNodeKeysForNode(esTreeNode); 2755 this.initialise(); 2756 return this; 2757 } 2758 removeAnnotations(code) { 2759 if (this.annotations) { 2760 for (const annotation of this.annotations) { 2761 code.remove(annotation.start, annotation.end); 2762 } 2763 } 2764 } 2765 render(code, options) { 2766 for (const key of childNodeKeys[this.type]) { 2767 const value = this[key]; 2768 if (value === null) 2769 continue; 2770 if (Array.isArray(value)) { 2771 for (const child of value) { 2772 child?.render(code, options); 2773 } 2774 } 2775 else { 2776 value.render(code, options); 2777 } 2778 } 2779 } 2780 setAssignedValue(value) { 2781 this.assignmentInteraction = { args: [null, value], type: INTERACTION_ASSIGNED }; 2782 } 2783 shouldBeIncluded(context) { 2784 return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext())); 2785 } 2786 /** 2787 * Just deoptimize everything by default so that when e.g. we do not track 2788 * something properly, it is deoptimized. 2789 * @protected 2790 */ 2791 applyDeoptimizations() { 2792 this.deoptimized = true; 2793 for (const key of childNodeKeys[this.type]) { 2794 const value = this[key]; 2795 if (value === null) 2796 continue; 2797 if (Array.isArray(value)) { 2798 for (const child of value) { 2799 child?.deoptimizePath(UNKNOWN_PATH); 2800 } 2801 } 2802 else { 2803 value.deoptimizePath(UNKNOWN_PATH); 2804 } 2805 } 2806 this.scope.context.requestTreeshakingPass(); 2807 } 2808 } 2809 function createChildNodeKeysForNode(esTreeNode) { 2810 return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */); 2811 } 2812 2813 function isObjectExpressionNode(node) { 2814 return node instanceof NodeBase && node.type === ObjectExpression$1; 2815 } 2816 function isPropertyNode(node) { 2817 return node.type === Property$1; 4490 2818 } 4491 2819 … … 4692 3020 } 4693 3021 4694 // This file is generated by scripts/generate-child-node-keys.js.4695 // Do not edit this file directly.4696 const childNodeKeys = {4697 ArrayExpression: ['elements'],4698 ArrayPattern: ['elements'],4699 ArrowFunctionExpression: ['params', 'body'],4700 AssignmentExpression: ['left', 'right'],4701 AssignmentPattern: ['left', 'right'],4702 AwaitExpression: ['argument'],4703 BinaryExpression: ['left', 'right'],4704 BlockStatement: ['body'],4705 BreakStatement: ['label'],4706 CallExpression: ['callee', 'arguments'],4707 CatchClause: ['param', 'body'],4708 ChainExpression: ['expression'],4709 ClassBody: ['body'],4710 ClassDeclaration: ['decorators', 'id', 'superClass', 'body'],4711 ClassExpression: ['decorators', 'id', 'superClass', 'body'],4712 ConditionalExpression: ['test', 'consequent', 'alternate'],4713 ContinueStatement: ['label'],4714 DebuggerStatement: [],4715 Decorator: ['expression'],4716 DoWhileStatement: ['body', 'test'],4717 EmptyStatement: [],4718 ExportAllDeclaration: ['exported', 'source', 'attributes'],4719 ExportDefaultDeclaration: ['declaration'],4720 ExportNamedDeclaration: ['specifiers', 'source', 'attributes', 'declaration'],4721 ExportSpecifier: ['local', 'exported'],4722 ExpressionStatement: ['expression'],4723 ForInStatement: ['left', 'right', 'body'],4724 ForOfStatement: ['left', 'right', 'body'],4725 ForStatement: ['init', 'test', 'update', 'body'],4726 FunctionDeclaration: ['id', 'params', 'body'],4727 FunctionExpression: ['id', 'params', 'body'],4728 Identifier: [],4729 IfStatement: ['test', 'consequent', 'alternate'],4730 ImportAttribute: ['key', 'value'],4731 ImportDeclaration: ['specifiers', 'source', 'attributes'],4732 ImportDefaultSpecifier: ['local'],4733 ImportExpression: ['source', 'options'],4734 ImportNamespaceSpecifier: ['local'],4735 ImportSpecifier: ['imported', 'local'],4736 LabeledStatement: ['label', 'body'],4737 Literal: [],4738 LogicalExpression: ['left', 'right'],4739 MemberExpression: ['object', 'property'],4740 MetaProperty: ['meta', 'property'],4741 MethodDefinition: ['decorators', 'key', 'value'],4742 NewExpression: ['callee', 'arguments'],4743 ObjectExpression: ['properties'],4744 ObjectPattern: ['properties'],4745 PanicError: [],4746 ParseError: [],4747 PrivateIdentifier: [],4748 Program: ['body'],4749 Property: ['key', 'value'],4750 PropertyDefinition: ['decorators', 'key', 'value'],4751 RestElement: ['argument'],4752 ReturnStatement: ['argument'],4753 SequenceExpression: ['expressions'],4754 SpreadElement: ['argument'],4755 StaticBlock: ['body'],4756 Super: [],4757 SwitchCase: ['test', 'consequent'],4758 SwitchStatement: ['discriminant', 'cases'],4759 TaggedTemplateExpression: ['tag', 'quasi'],4760 TemplateElement: [],4761 TemplateLiteral: ['quasis', 'expressions'],4762 ThisExpression: [],4763 ThrowStatement: ['argument'],4764 TryStatement: ['block', 'handler', 'finalizer'],4765 UnaryExpression: ['argument'],4766 UpdateExpression: ['argument'],4767 VariableDeclaration: ['declarations'],4768 VariableDeclarator: ['id', 'init'],4769 WhileStatement: ['test', 'body'],4770 YieldExpression: ['argument']4771 };4772 4773 const INCLUDE_PARAMETERS = 'variables';4774 const IS_SKIPPED_CHAIN = Symbol('IS_SKIPPED_CHAIN');4775 class NodeBase extends ExpressionEntity {4776 /**4777 * Nodes can apply custom deoptimizations once they become part of the4778 * executed code. To do this, they must initialize this as false, implement4779 * applyDeoptimizations and call this from include and hasEffects if they have4780 * custom handlers4781 */4782 get deoptimized() {4783 return isFlagSet(this.flags, 2 /* Flag.deoptimized */);4784 }4785 set deoptimized(value) {4786 this.flags = setFlag(this.flags, 2 /* Flag.deoptimized */, value);4787 }4788 constructor(parent, parentScope) {4789 super();4790 this.parent = parent;4791 this.scope = parentScope;4792 this.createScope(parentScope);4793 }4794 addExportedVariables(_variables, _exportNamesByVariable) { }4795 /**4796 * Override this to bind assignments to variables and do any initialisations4797 * that require the scopes to be populated with variables.4798 */4799 bind() {4800 for (const key of childNodeKeys[this.type]) {4801 const value = this[key];4802 if (Array.isArray(value)) {4803 for (const child of value) {4804 child?.bind();4805 }4806 }4807 else if (value) {4808 value.bind();4809 }4810 }4811 }4812 /**4813 * Override if this node should receive a different scope than the parent4814 * scope.4815 */4816 createScope(parentScope) {4817 this.scope = parentScope;4818 }4819 hasEffects(context) {4820 if (!this.deoptimized)4821 this.applyDeoptimizations();4822 for (const key of childNodeKeys[this.type]) {4823 const value = this[key];4824 if (value === null)4825 continue;4826 if (Array.isArray(value)) {4827 for (const child of value) {4828 if (child?.hasEffects(context))4829 return true;4830 }4831 }4832 else if (value.hasEffects(context))4833 return true;4834 }4835 return false;4836 }4837 hasEffectsAsAssignmentTarget(context, _checkAccess) {4838 return (this.hasEffects(context) ||4839 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));4840 }4841 include(context, includeChildrenRecursively, _options) {4842 if (!this.deoptimized)4843 this.applyDeoptimizations();4844 this.included = true;4845 for (const key of childNodeKeys[this.type]) {4846 const value = this[key];4847 if (value === null)4848 continue;4849 if (Array.isArray(value)) {4850 for (const child of value) {4851 child?.include(context, includeChildrenRecursively);4852 }4853 }4854 else {4855 value.include(context, includeChildrenRecursively);4856 }4857 }4858 }4859 includeAsAssignmentTarget(context, includeChildrenRecursively, _deoptimizeAccess) {4860 this.include(context, includeChildrenRecursively);4861 }4862 /**4863 * Override to perform special initialisation steps after the scope is4864 * initialised4865 */4866 initialise() {4867 this.scope.context.magicString.addSourcemapLocation(this.start);4868 this.scope.context.magicString.addSourcemapLocation(this.end);4869 }4870 parseNode(esTreeNode) {4871 for (const [key, value] of Object.entries(esTreeNode)) {4872 // Skip properties defined on the class already.4873 // This way, we can override this function to add custom initialisation and then call super.parseNode4874 // Note: this doesn't skip properties with defined getters/setters which we use to pack wrap booleans4875 // in bitfields. Those are still assigned from the value in the esTreeNode.4876 if (this.hasOwnProperty(key))4877 continue;4878 if (key.charCodeAt(0) === 95 /* _ */) {4879 if (key === ANNOTATION_KEY) {4880 this.annotations = value;4881 }4882 else if (key === INVALID_ANNOTATION_KEY) {4883 this.invalidAnnotations = value;4884 }4885 }4886 else if (typeof value !== 'object' || value === null) {4887 this[key] = value;4888 }4889 else if (Array.isArray(value)) {4890 this[key] = [];4891 for (const child of value) {4892 this[key].push(child === null4893 ? null4894 : new (this.scope.context.getNodeConstructor(child.type))(this, this.scope).parseNode(child));4895 }4896 }4897 else {4898 this[key] = new (this.scope.context.getNodeConstructor(value.type))(this, this.scope).parseNode(value);4899 }4900 }4901 // extend child keys for unknown node types4902 childNodeKeys[esTreeNode.type] ||= createChildNodeKeysForNode(esTreeNode);4903 this.initialise();4904 return this;4905 }4906 removeAnnotations(code) {4907 if (this.annotations) {4908 for (const annotation of this.annotations) {4909 code.remove(annotation.start, annotation.end);4910 }4911 }4912 }4913 render(code, options) {4914 for (const key of childNodeKeys[this.type]) {4915 const value = this[key];4916 if (value === null)4917 continue;4918 if (Array.isArray(value)) {4919 for (const child of value) {4920 child?.render(code, options);4921 }4922 }4923 else {4924 value.render(code, options);4925 }4926 }4927 }4928 setAssignedValue(value) {4929 this.assignmentInteraction = { args: [null, value], type: INTERACTION_ASSIGNED };4930 }4931 shouldBeIncluded(context) {4932 return this.included || (!context.brokenFlow && this.hasEffects(createHasEffectsContext()));4933 }4934 /**4935 * Just deoptimize everything by default so that when e.g. we do not track4936 * something properly, it is deoptimized.4937 * @protected4938 */4939 applyDeoptimizations() {4940 this.deoptimized = true;4941 for (const key of childNodeKeys[this.type]) {4942 const value = this[key];4943 if (value === null)4944 continue;4945 if (Array.isArray(value)) {4946 for (const child of value) {4947 child?.deoptimizePath(UNKNOWN_PATH);4948 }4949 }4950 else {4951 value.deoptimizePath(UNKNOWN_PATH);4952 }4953 }4954 this.scope.context.requestTreeshakingPass();4955 }4956 }4957 function createChildNodeKeysForNode(esTreeNode) {4958 return Object.keys(esTreeNode).filter(key => typeof esTreeNode[key] === 'object' && key.charCodeAt(0) !== 95 /* _ */);4959 }4960 4961 3022 class SpreadElement extends NodeBase { 4962 3023 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 4963 3024 if (path.length > 0) { 4964 this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, [UnknownKey, ...path], recursionTracker);3025 this.argument.deoptimizeArgumentsOnInteractionAtPath(interaction, UNKNOWN_PATH, recursionTracker); 4965 3026 } 4966 3027 } … … 5261 3322 property.deoptimizePath(subPath); 5262 3323 } 5263 this.prototypeExpression?.deoptimizePath(path.length === 1 ? [ ...path, UnknownKey] : path);3324 this.prototypeExpression?.deoptimizePath(path.length === 1 ? [path[0], UnknownKey] : path); 5264 3325 } 5265 3326 getLiteralValueAtPath(path, recursionTracker, origin) { … … 5674 3735 } 5675 3736 5676 class ArrayPattern extends NodeBase {5677 addExportedVariables(variables, exportNamesByVariable) {5678 for (const element of this.elements) {5679 element?.addExportedVariables(variables, exportNamesByVariable);5680 }5681 }5682 declare(kind) {5683 const variables = [];5684 for (const element of this.elements) {5685 if (element !== null) {5686 variables.push(...element.declare(kind, UNKNOWN_EXPRESSION));5687 }5688 }5689 return variables;5690 }5691 // Patterns can only be deoptimized at the empty path at the moment5692 deoptimizePath() {5693 for (const element of this.elements) {5694 element?.deoptimizePath(EMPTY_PATH);5695 }5696 }5697 // Patterns are only checked at the empty path at the moment5698 hasEffectsOnInteractionAtPath(_path, interaction, context) {5699 for (const element of this.elements) {5700 if (element?.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))5701 return true;5702 }5703 return false;5704 }5705 markDeclarationReached() {5706 for (const element of this.elements) {5707 element?.markDeclarationReached();5708 }5709 }5710 }5711 5712 /** @typedef { import('estree').Node} Node */5713 /** @typedef {Node | {5714 * type: 'PropertyDefinition';5715 * computed: boolean;5716 * value: Node5717 * }} NodeWithPropertyDefinition */5718 5719 /**5720 *5721 * @param {NodeWithPropertyDefinition} node5722 * @param {NodeWithPropertyDefinition} parent5723 * @returns {boolean}5724 */5725 function is_reference (node, parent) {5726 if (node.type === 'MemberExpression') {5727 return !node.computed && is_reference(node.object, node);5728 }5729 5730 if (node.type === 'Identifier') {5731 if (!parent) return true;5732 5733 switch (parent.type) {5734 // disregard `bar` in `foo.bar`5735 case 'MemberExpression': return parent.computed || node === parent.object;5736 5737 // disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`5738 case 'MethodDefinition': return parent.computed;5739 5740 // disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`5741 case 'PropertyDefinition': return parent.computed || node === parent.value;5742 5743 // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`5744 case 'Property': return parent.computed || node === parent.value;5745 5746 // disregard the `bar` in `export { foo as bar }` or5747 // the foo in `import { foo as bar }`5748 case 'ExportSpecifier':5749 case 'ImportSpecifier': return node === parent.local;5750 5751 // disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`5752 case 'LabeledStatement':5753 case 'BreakStatement':5754 case 'ContinueStatement': return false;5755 default: return true;5756 }5757 }5758 5759 return false;5760 }5761 5762 const PureFunctionKey = Symbol('PureFunction');5763 const getPureFunctions = ({ treeshake }) => {5764 const pureFunctions = Object.create(null);5765 for (const functionName of treeshake ? treeshake.manualPureFunctions : []) {5766 let currentFunctions = pureFunctions;5767 for (const pathSegment of functionName.split('.')) {5768 currentFunctions = currentFunctions[pathSegment] ||= Object.create(null);5769 }5770 currentFunctions[PureFunctionKey] = true;5771 }5772 return pureFunctions;5773 };5774 5775 const doNothing = () => { };5776 5777 3737 /* eslint sort-keys: "off" */ 5778 3738 const ValueProperties = Symbol('Value Properties'); … … 5888 3848 prototype: O 5889 3849 }, 3850 AggregateError: PC_WITH_ARRAY, 5890 3851 Atomics: O, 5891 3852 BigInt: C, … … 5911 3872 eval: O, 5912 3873 EvalError: PC, 3874 FinalizationRegistry: C, 5913 3875 Float32Array: ARRAY_TYPE, 5914 3876 Float64Array: ARRAY_TYPE, … … 6015 3977 }, 6016 3978 propertyIsEnumerable: O, 6017 Proxy: O, 3979 Proxy: { 3980 __proto__: null, 3981 [ValueProperties]: { 3982 deoptimizeArgumentsOnCall: ({ args: [, target, parameter] }) => { 3983 if (isObjectExpressionNode(parameter)) { 3984 const hasSpreadElement = parameter.properties.some(property => !isPropertyNode(property)); 3985 if (!hasSpreadElement) { 3986 for (const property of parameter.properties) { 3987 property.deoptimizeArgumentsOnInteractionAtPath({ 3988 args: [null, target], 3989 type: INTERACTION_CALLED, 3990 withNew: false 3991 }, EMPTY_PATH, SHARED_RECURSION_TRACKER); 3992 } 3993 return; 3994 } 3995 } 3996 target.deoptimizePath(UNKNOWN_PATH); 3997 }, 3998 getLiteralValue: getTruthyLiteralValue, 3999 hasEffectsWhenCalled: returnTrue 4000 } 4001 }, 6018 4002 RangeError: PC, 6019 4003 ReferenceError: PC, … … 6061 4045 valueOf: O, 6062 4046 WeakMap: PC_WITH_ARRAY, 4047 WeakRef: C, 6063 4048 WeakSet: PC_WITH_ARRAY, 6064 4049 // Additional globals shared by Node and Browser that are not strictly part of the language … … 6916 4901 6917 4902 const tdzVariableKinds = new Set(['class', 'const', 'let', 'var', 'using', 'await using']); 6918 class Identifier extends NodeBase {4903 class IdentifierBase extends NodeBase { 6919 4904 constructor() { 6920 4905 super(...arguments); 6921 4906 this.variable = null; 6922 this.is ReferenceVariable = false;4907 this.isVariableReference = false; 6923 4908 } 6924 4909 get isTDZAccess() { … … 6931 4916 this.flags = setFlag(this.flags, 4 /* Flag.tdzAccessDefined */, true); 6932 4917 this.flags = setFlag(this.flags, 8 /* Flag.tdzAccess */, value); 4918 } 4919 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 4920 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 4921 } 4922 deoptimizePath(path) { 4923 if (path.length === 0 && !this.scope.contains(this.name)) { 4924 this.disallowImportReassignment(); 4925 } 4926 // We keep conditional chaining because an unknown Node could have an 4927 // Identifier as property that might be deoptimized by default 4928 this.variable?.deoptimizePath(path); 4929 } 4930 getLiteralValueAtPath(path, recursionTracker, origin) { 4931 return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin); 4932 } 4933 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 4934 const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 4935 return [expression, isPure || this.isPureFunction(path)]; 4936 } 4937 hasEffects(context) { 4938 if (!this.deoptimized) 4939 this.applyDeoptimizations(); 4940 if (this.isPossibleTDZ() && this.variable.kind !== 'var') { 4941 return true; 4942 } 4943 return (this.scope.context.options.treeshake 4944 .unknownGlobalSideEffects && 4945 this.variable instanceof GlobalVariable && 4946 !this.isPureFunction(EMPTY_PATH) && 4947 this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context)); 4948 } 4949 hasEffectsOnInteractionAtPath(path, interaction, context) { 4950 switch (interaction.type) { 4951 case INTERACTION_ACCESSED: { 4952 return (this.variable !== null && 4953 !this.isPureFunction(path) && 4954 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context)); 4955 } 4956 case INTERACTION_ASSIGNED: { 4957 return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context); 4958 } 4959 case INTERACTION_CALLED: { 4960 return (!this.isPureFunction(path) && 4961 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context)); 4962 } 4963 } 4964 } 4965 include() { 4966 if (!this.deoptimized) 4967 this.applyDeoptimizations(); 4968 if (!this.included) { 4969 this.included = true; 4970 if (this.variable !== null) { 4971 this.scope.context.includeVariableInModule(this.variable); 4972 } 4973 } 4974 } 4975 includeCallArguments(context, parameters) { 4976 this.variable.includeCallArguments(context, parameters); 4977 } 4978 isPossibleTDZ() { 4979 // return cached value to avoid issues with the next tree-shaking pass 4980 const cachedTdzAccess = this.isTDZAccess; 4981 if (cachedTdzAccess !== null) 4982 return cachedTdzAccess; 4983 if (!(this.variable instanceof LocalVariable && 4984 this.variable.kind && 4985 tdzVariableKinds.has(this.variable.kind) && 4986 // We ignore modules that did not receive a treeshaking pass yet as that 4987 // causes many false positives due to circular dependencies or disabled 4988 // moduleSideEffects. 4989 this.variable.module.hasTreeShakingPassStarted)) { 4990 return (this.isTDZAccess = false); 4991 } 4992 let decl_id; 4993 if (this.variable.declarations && 4994 this.variable.declarations.length === 1 && 4995 (decl_id = this.variable.declarations[0]) && 4996 this.start < decl_id.start && 4997 closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) { 4998 // a variable accessed before its declaration 4999 // in the same function or at top level of module 5000 return (this.isTDZAccess = true); 5001 } 5002 if (!this.variable.initReached) { 5003 // Either a const/let TDZ violation or 5004 // var use before declaration was encountered. 5005 return (this.isTDZAccess = true); 5006 } 5007 return (this.isTDZAccess = false); 5008 } 5009 applyDeoptimizations() { 5010 this.deoptimized = true; 5011 if (this.variable instanceof LocalVariable) { 5012 // When accessing a variable from a module without side effects, this 5013 // means we use an export of that module and therefore need to potentially 5014 // include it in the bundle. 5015 if (!this.variable.module.isExecuted) { 5016 markModuleAndImpureDependenciesAsExecuted(this.variable.module); 5017 } 5018 this.variable.consolidateInitializers(); 5019 this.scope.context.requestTreeshakingPass(); 5020 } 5021 if (this.isVariableReference) { 5022 this.variable.addUsedPlace(this); 5023 this.scope.context.requestTreeshakingPass(); 5024 } 5025 } 5026 disallowImportReassignment() { 5027 return this.scope.context.error(logIllegalImportReassignment(this.name, this.scope.context.module.id), this.start); 5028 } 5029 getVariableRespectingTDZ() { 5030 if (this.isPossibleTDZ()) { 5031 return UNKNOWN_EXPRESSION; 5032 } 5033 return this.variable; 5034 } 5035 isPureFunction(path) { 5036 let currentPureFunction = this.scope.context.manualPureFunctions[this.name]; 5037 for (const segment of path) { 5038 if (currentPureFunction) { 5039 if (currentPureFunction[PureFunctionKey]) { 5040 return true; 5041 } 5042 currentPureFunction = currentPureFunction[segment]; 5043 } 5044 else { 5045 return false; 5046 } 5047 } 5048 return currentPureFunction?.[PureFunctionKey]; 5049 } 5050 } 5051 function closestParentFunctionOrProgram(node) { 5052 while (node && !/^Program|Function/.test(node.type)) { 5053 node = node.parent; 5054 } 5055 // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program 5056 return node; 5057 } 5058 5059 class Identifier extends IdentifierBase { 5060 constructor() { 5061 super(...arguments); 5062 this.variable = null; 6933 5063 } 6934 5064 addExportedVariables(variables, exportNamesByVariable) { … … 6941 5071 this.variable = this.scope.findVariable(this.name); 6942 5072 this.variable.addReference(this); 6943 this.is ReferenceVariable = true;5073 this.isVariableReference = true; 6944 5074 } 6945 5075 } … … 6981 5111 return [(this.variable = variable)]; 6982 5112 } 6983 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {6984 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);6985 }6986 deoptimizePath(path) {6987 if (path.length === 0 && !this.scope.contains(this.name)) {6988 this.disallowImportReassignment();6989 }6990 // We keep conditional chaining because an unknown Node could have an6991 // Identifier as property that might be deoptimized by default6992 this.variable?.deoptimizePath(path);6993 }6994 getLiteralValueAtPath(path, recursionTracker, origin) {6995 return this.getVariableRespectingTDZ().getLiteralValueAtPath(path, recursionTracker, origin);6996 }6997 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {6998 const [expression, isPure] = this.getVariableRespectingTDZ().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);6999 return [expression, isPure || this.isPureFunction(path)];7000 }7001 hasEffects(context) {7002 if (!this.deoptimized)7003 this.applyDeoptimizations();7004 if (this.isPossibleTDZ() && this.variable.kind !== 'var') {7005 return true;7006 }7007 return (this.scope.context.options.treeshake7008 .unknownGlobalSideEffects &&7009 this.variable instanceof GlobalVariable &&7010 !this.isPureFunction(EMPTY_PATH) &&7011 this.variable.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_ACCESS, context));7012 }7013 hasEffectsOnInteractionAtPath(path, interaction, context) {7014 switch (interaction.type) {7015 case INTERACTION_ACCESSED: {7016 return (this.variable !== null &&7017 !this.isPureFunction(path) &&7018 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));7019 }7020 case INTERACTION_ASSIGNED: {7021 return (path.length > 0 ? this.getVariableRespectingTDZ() : this.variable).hasEffectsOnInteractionAtPath(path, interaction, context);7022 }7023 case INTERACTION_CALLED: {7024 return (!this.isPureFunction(path) &&7025 this.getVariableRespectingTDZ().hasEffectsOnInteractionAtPath(path, interaction, context));7026 }7027 }7028 }7029 include() {7030 if (!this.deoptimized)7031 this.applyDeoptimizations();7032 if (!this.included) {7033 this.included = true;7034 if (this.variable !== null) {7035 this.scope.context.includeVariableInModule(this.variable);7036 }7037 }7038 }7039 includeCallArguments(context, parameters) {7040 this.variable.includeCallArguments(context, parameters);7041 }7042 isPossibleTDZ() {7043 // return cached value to avoid issues with the next tree-shaking pass7044 const cachedTdzAccess = this.isTDZAccess;7045 if (cachedTdzAccess !== null)7046 return cachedTdzAccess;7047 if (!(this.variable instanceof LocalVariable &&7048 this.variable.kind &&7049 tdzVariableKinds.has(this.variable.kind) &&7050 // we ignore possible TDZs due to circular module dependencies as7051 // otherwise we get many false positives7052 this.variable.module === this.scope.context.module)) {7053 return (this.isTDZAccess = false);7054 }7055 let decl_id;7056 if (this.variable.declarations &&7057 this.variable.declarations.length === 1 &&7058 (decl_id = this.variable.declarations[0]) &&7059 this.start < decl_id.start &&7060 closestParentFunctionOrProgram(this) === closestParentFunctionOrProgram(decl_id)) {7061 // a variable accessed before its declaration7062 // in the same function or at top level of module7063 return (this.isTDZAccess = true);7064 }7065 // We ignore the case where the module is not yet executed because7066 // moduleSideEffects are false.7067 if (!this.variable.initReached && this.scope.context.module.isExecuted) {7068 // Either a const/let TDZ violation or7069 // var use before declaration was encountered.7070 return (this.isTDZAccess = true);7071 }7072 return (this.isTDZAccess = false);7073 }7074 5113 markDeclarationReached() { 7075 5114 this.variable.initReached = true; … … 7094 5133 } 7095 5134 } 7096 }7097 disallowImportReassignment() {7098 return this.scope.context.error(logIllegalImportReassignment(this.name, this.scope.context.module.id), this.start);7099 }7100 applyDeoptimizations() {7101 this.deoptimized = true;7102 if (this.variable instanceof LocalVariable) {7103 this.variable.consolidateInitializers();7104 this.scope.context.requestTreeshakingPass();7105 }7106 if (this.isReferenceVariable) {7107 this.variable.addUsedPlace(this);7108 this.scope.context.requestTreeshakingPass();7109 }7110 }7111 getVariableRespectingTDZ() {7112 if (this.isPossibleTDZ()) {7113 return UNKNOWN_EXPRESSION;7114 }7115 return this.variable;7116 }7117 isPureFunction(path) {7118 let currentPureFunction = this.scope.context.manualPureFunctions[this.name];7119 for (const segment of path) {7120 if (currentPureFunction) {7121 if (currentPureFunction[PureFunctionKey]) {7122 return true;7123 }7124 currentPureFunction = currentPureFunction[segment];7125 }7126 else {7127 return false;7128 }7129 }7130 return currentPureFunction?.[PureFunctionKey];7131 }7132 }7133 function closestParentFunctionOrProgram(node) {7134 while (node && !/^Program|Function/.test(node.type)) {7135 node = node.parent;7136 }7137 // one of: ArrowFunctionExpression, FunctionDeclaration, FunctionExpression or Program7138 return node;7139 }7140 7141 const MAX_TRACKED_INTERACTIONS = 20;7142 const NO_INTERACTIONS = EMPTY_ARRAY;7143 const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]);7144 const EMPTY_PATH_TRACKER = new PathTracker();7145 const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]);7146 class ParameterVariable extends LocalVariable {7147 constructor(name, declarator, context) {7148 super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter');7149 this.deoptimizationInteractions = [];7150 this.deoptimizations = new PathTracker();7151 this.deoptimizedFields = new Set();7152 this.entitiesToBeDeoptimized = new Set();7153 this.expressionsUseTheKnownValue = [];7154 this.knownValue = null;7155 this.knownValueLiteral = UnknownValue;7156 this.frozenValue = null;7157 }7158 addEntityToBeDeoptimized(entity) {7159 if (entity === UNKNOWN_EXPRESSION) {7160 // As unknown expressions fully deoptimize all interactions, we can clear7161 // the interaction cache at this point provided we keep this optimization7162 // in mind when adding new interactions7163 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {7164 this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION);7165 for (const { interaction } of this.deoptimizationInteractions) {7166 deoptimizeInteraction(interaction);7167 }7168 this.deoptimizationInteractions = NO_INTERACTIONS;7169 }7170 }7171 else if (this.deoptimizedFields.has(UnknownKey)) {7172 // This means that we already deoptimized all interactions and no longer7173 // track them7174 entity.deoptimizePath(UNKNOWN_PATH);7175 }7176 else if (!this.entitiesToBeDeoptimized.has(entity)) {7177 this.entitiesToBeDeoptimized.add(entity);7178 for (const field of this.deoptimizedFields) {7179 entity.deoptimizePath([field]);7180 }7181 for (const { interaction, path } of this.deoptimizationInteractions) {7182 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);7183 }7184 }7185 }7186 markReassigned() {7187 if (this.isReassigned) {7188 return;7189 }7190 super.markReassigned();7191 for (const expression of this.expressionsUseTheKnownValue) {7192 expression.deoptimizeCache();7193 }7194 this.expressionsUseTheKnownValue = EMPTY_ARRAY;7195 }7196 deoptimizeCache() {7197 this.markReassigned();7198 }7199 /**7200 * Update the known value of the parameter variable.7201 * Must be called for every function call, so it can track all the arguments,7202 * and deoptimizeCache itself to mark reassigned if the argument is changed.7203 * @param argument The argument of the function call7204 */7205 updateKnownValue(argument) {7206 if (this.isReassigned) {7207 return;7208 }7209 if (this.knownValue === null) {7210 this.knownValue = argument;7211 this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);7212 return;7213 }7214 // the same literal or identifier, do nothing7215 if (this.knownValue === argument ||7216 (this.knownValue instanceof Identifier &&7217 argument instanceof Identifier &&7218 this.knownValue.variable === argument.variable)) {7219 return;7220 }7221 const oldValue = this.knownValueLiteral;7222 if (typeof oldValue === 'symbol') {7223 this.markReassigned();7224 return;7225 }7226 // add tracking for the new argument7227 const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);7228 if (newValue !== oldValue) {7229 this.markReassigned();7230 }7231 }7232 /**7233 * This function freezes the known value of the parameter variable,7234 * so the optimization starts with a certain ExpressionEntity.7235 * The optimization can be undone by calling `markReassigned`.7236 * @returns the frozen value7237 */7238 getKnownValue() {7239 if (this.frozenValue === null) {7240 this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION;7241 }7242 return this.frozenValue;7243 }7244 getLiteralValueAtPath(path, recursionTracker, origin) {7245 if (this.isReassigned) {7246 return UnknownValue;7247 }7248 const knownValue = this.getKnownValue();7249 this.expressionsUseTheKnownValue.push(origin);7250 return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue);7251 }7252 hasEffectsOnInteractionAtPath(path, interaction, context) {7253 if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) {7254 return super.hasEffectsOnInteractionAtPath(path, interaction, context);7255 }7256 const knownValue = this.getKnownValue();7257 return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context);7258 }7259 deoptimizeArgumentsOnInteractionAtPath(interaction, path) {7260 // For performance reasons, we fully deoptimize all deeper interactions7261 if (path.length >= 2 ||7262 this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) ||7263 this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS ||7264 (path.length === 1 &&7265 (this.deoptimizedFields.has(UnknownKey) ||7266 (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) {7267 deoptimizeInteraction(interaction);7268 return;7269 }7270 if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) {7271 for (const entity of this.entitiesToBeDeoptimized) {7272 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER);7273 }7274 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) {7275 this.deoptimizationInteractions.push({7276 interaction,7277 path7278 });7279 }7280 }7281 }7282 deoptimizePath(path) {7283 if (path.length === 0) {7284 this.markReassigned();7285 return;7286 }7287 if (this.deoptimizedFields.has(UnknownKey)) {7288 return;7289 }7290 const key = path[0];7291 if (this.deoptimizedFields.has(key)) {7292 return;7293 }7294 this.deoptimizedFields.add(key);7295 for (const entity of this.entitiesToBeDeoptimized) {7296 // We do not need a recursion tracker here as we already track whether7297 // this field is deoptimized7298 entity.deoptimizePath([key]);7299 }7300 if (key === UnknownKey) {7301 // save some memory7302 this.deoptimizationInteractions = NO_INTERACTIONS;7303 this.deoptimizations = EMPTY_PATH_TRACKER;7304 this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD;7305 this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY;7306 }7307 }7308 getReturnExpressionWhenCalledAtPath(path) {7309 // We deoptimize everything that is called as that will trivially deoptimize7310 // the corresponding return expressions as well and avoid badly performing7311 // and complicated alternatives7312 if (path.length === 0) {7313 this.deoptimizePath(UNKNOWN_PATH);7314 }7315 else if (!this.deoptimizedFields.has(path[0])) {7316 this.deoptimizePath([path[0]]);7317 }7318 return UNKNOWN_RETURN_EXPRESSION;7319 5135 } 7320 5136 } … … 7415 5231 } 7416 5232 addReturnExpression(expression) { 7417 this.parent instanceof ChildScope && this.parent.addReturnExpression(expression); 5233 if (this.parent instanceof ChildScope) { 5234 this.parent.addReturnExpression(expression); 5235 } 7418 5236 } 7419 5237 addUsedOutsideNames(usedNames, format, exportNamesByVariable, accessedGlobalsByScope) { … … 7458 5276 return this.parent.findLexicalBoundary(); 7459 5277 } 5278 findGlobal(name) { 5279 const variable = this.parent.findVariable(name); 5280 this.accessedOutsideVariables.set(name, variable); 5281 return variable; 5282 } 7460 5283 findVariable(name) { 7461 5284 const knownVariable = this.variables.get(name) || this.accessedOutsideVariables.get(name); … … 7466 5289 this.accessedOutsideVariables.set(name, variable); 7467 5290 return variable; 5291 } 5292 } 5293 5294 function checkEffectForNodes(nodes, context) { 5295 for (const node of nodes) { 5296 if (node.hasEffects(context)) { 5297 return true; 5298 } 5299 } 5300 return false; 5301 } 5302 5303 class MethodBase extends NodeBase { 5304 constructor() { 5305 super(...arguments); 5306 this.accessedValue = null; 5307 } 5308 get computed() { 5309 return isFlagSet(this.flags, 1024 /* Flag.computed */); 5310 } 5311 set computed(value) { 5312 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value); 5313 } 5314 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 5315 if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) { 5316 return this.value.deoptimizeArgumentsOnInteractionAtPath({ 5317 args: interaction.args, 5318 type: INTERACTION_CALLED, 5319 withNew: false 5320 }, EMPTY_PATH, recursionTracker); 5321 } 5322 if (interaction.type === INTERACTION_ASSIGNED && this.kind === 'set' && path.length === 0) { 5323 return this.value.deoptimizeArgumentsOnInteractionAtPath({ 5324 args: interaction.args, 5325 type: INTERACTION_CALLED, 5326 withNew: false 5327 }, EMPTY_PATH, recursionTracker); 5328 } 5329 this.getAccessedValue()[0].deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 5330 } 5331 // As getter properties directly receive their values from fixed function 5332 // expressions, there is no known situation where a getter is deoptimized. 5333 deoptimizeCache() { } 5334 deoptimizePath(path) { 5335 this.getAccessedValue()[0].deoptimizePath(path); 5336 } 5337 getLiteralValueAtPath(path, recursionTracker, origin) { 5338 return this.getAccessedValue()[0].getLiteralValueAtPath(path, recursionTracker, origin); 5339 } 5340 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 5341 return this.getAccessedValue()[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 5342 } 5343 hasEffects(context) { 5344 return this.key.hasEffects(context); 5345 } 5346 hasEffectsOnInteractionAtPath(path, interaction, context) { 5347 if (this.kind === 'get' && interaction.type === INTERACTION_ACCESSED && path.length === 0) { 5348 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, { 5349 args: interaction.args, 5350 type: INTERACTION_CALLED, 5351 withNew: false 5352 }, context); 5353 } 5354 // setters are only called for empty paths 5355 if (this.kind === 'set' && interaction.type === INTERACTION_ASSIGNED) { 5356 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, { 5357 args: interaction.args, 5358 type: INTERACTION_CALLED, 5359 withNew: false 5360 }, context); 5361 } 5362 return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context); 5363 } 5364 applyDeoptimizations() { } 5365 getAccessedValue() { 5366 if (this.accessedValue === null) { 5367 if (this.kind === 'get') { 5368 this.accessedValue = UNKNOWN_RETURN_EXPRESSION; 5369 return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this)); 5370 } 5371 else { 5372 return (this.accessedValue = [this.value, false]); 5373 } 5374 } 5375 return this.accessedValue; 5376 } 5377 } 5378 5379 class MethodDefinition extends MethodBase { 5380 hasEffects(context) { 5381 return super.hasEffects(context) || checkEffectForNodes(this.decorators, context); 5382 } 5383 applyDeoptimizations() { } 5384 } 5385 5386 class BlockScope extends ChildScope { 5387 constructor(parent) { 5388 super(parent, parent.context); 5389 } 5390 addDeclaration(identifier, context, init, kind) { 5391 if (kind === 'var') { 5392 const name = identifier.name; 5393 const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name); 5394 if (existingVariable) { 5395 if (existingVariable.kind === 'var' || 5396 (kind === 'var' && existingVariable.kind === 'parameter')) { 5397 existingVariable.addDeclaration(identifier, init); 5398 return existingVariable; 5399 } 5400 return context.error(logRedeclarationError(name), identifier.start); 5401 } 5402 const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind); 5403 // Necessary to make sure the init is deoptimized for conditional declarations. 5404 // We cannot call deoptimizePath here. 5405 declaredVariable.markInitializersForDeoptimization(); 5406 // We add the variable to this and all parent scopes to reliably detect conflicts 5407 this.addHoistedVariable(name, declaredVariable); 5408 return declaredVariable; 5409 } 5410 return super.addDeclaration(identifier, context, init, kind); 5411 } 5412 } 5413 5414 class StaticBlock extends NodeBase { 5415 createScope(parentScope) { 5416 this.scope = new BlockScope(parentScope); 5417 } 5418 hasEffects(context) { 5419 for (const node of this.body) { 5420 if (node.hasEffects(context)) 5421 return true; 5422 } 5423 return false; 5424 } 5425 include(context, includeChildrenRecursively) { 5426 this.included = true; 5427 for (const node of this.body) { 5428 if (includeChildrenRecursively || node.shouldBeIncluded(context)) 5429 node.include(context, includeChildrenRecursively); 5430 } 5431 } 5432 render(code, options) { 5433 if (this.body.length > 0) { 5434 const bodyStartPos = findFirstOccurrenceOutsideComment(code.original.slice(this.start, this.end), '{') + 1; 5435 renderStatementList(this.body, code, this.start + bodyStartPos, this.end - 1, options); 5436 } 5437 else { 5438 super.render(code, options); 5439 } 5440 } 5441 } 5442 function isStaticBlock(statement) { 5443 return statement.type === StaticBlock$1; 5444 } 5445 5446 class ObjectMember extends ExpressionEntity { 5447 constructor(object, key) { 5448 super(); 5449 this.object = object; 5450 this.key = key; 5451 } 5452 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 5453 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker); 5454 } 5455 deoptimizePath(path) { 5456 this.object.deoptimizePath([this.key, ...path]); 5457 } 5458 getLiteralValueAtPath(path, recursionTracker, origin) { 5459 return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin); 5460 } 5461 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 5462 return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin); 5463 } 5464 hasEffectsOnInteractionAtPath(path, interaction, context) { 5465 return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context); 5466 } 5467 } 5468 5469 class ClassNode extends NodeBase { 5470 constructor() { 5471 super(...arguments); 5472 this.objectEntity = null; 5473 } 5474 createScope(parentScope) { 5475 this.scope = new ChildScope(parentScope, parentScope.context); 5476 } 5477 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 5478 this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 5479 } 5480 deoptimizeCache() { 5481 this.getObjectEntity().deoptimizeAllProperties(); 5482 } 5483 deoptimizePath(path) { 5484 this.getObjectEntity().deoptimizePath(path); 5485 } 5486 getLiteralValueAtPath(path, recursionTracker, origin) { 5487 return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin); 5488 } 5489 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 5490 return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 5491 } 5492 hasEffects(context) { 5493 if (!this.deoptimized) 5494 this.applyDeoptimizations(); 5495 const initEffect = this.superClass?.hasEffects(context) || this.body.hasEffects(context); 5496 this.id?.markDeclarationReached(); 5497 return initEffect || super.hasEffects(context) || checkEffectForNodes(this.decorators, context); 5498 } 5499 hasEffectsOnInteractionAtPath(path, interaction, context) { 5500 return interaction.type === INTERACTION_CALLED && path.length === 0 5501 ? !interaction.withNew || 5502 (this.classConstructor === null 5503 ? this.superClass?.hasEffectsOnInteractionAtPath(path, interaction, context) 5504 : this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)) || 5505 false 5506 : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context); 5507 } 5508 include(context, includeChildrenRecursively) { 5509 if (!this.deoptimized) 5510 this.applyDeoptimizations(); 5511 this.included = true; 5512 this.superClass?.include(context, includeChildrenRecursively); 5513 this.body.include(context, includeChildrenRecursively); 5514 for (const decorator of this.decorators) 5515 decorator.include(context, includeChildrenRecursively); 5516 if (this.id) { 5517 this.id.markDeclarationReached(); 5518 this.id.include(); 5519 } 5520 } 5521 initialise() { 5522 super.initialise(); 5523 this.id?.declare('class', this); 5524 for (const method of this.body.body) { 5525 if (method instanceof MethodDefinition && method.kind === 'constructor') { 5526 this.classConstructor = method; 5527 return; 5528 } 5529 } 5530 this.classConstructor = null; 5531 } 5532 applyDeoptimizations() { 5533 this.deoptimized = true; 5534 for (const definition of this.body.body) { 5535 if (!isStaticBlock(definition) && 5536 !(definition.static || 5537 (definition instanceof MethodDefinition && definition.kind === 'constructor'))) { 5538 // Calls to methods are not tracked, ensure that the return value is deoptimized 5539 definition.deoptimizePath(UNKNOWN_PATH); 5540 } 5541 } 5542 this.scope.context.requestTreeshakingPass(); 5543 } 5544 getObjectEntity() { 5545 if (this.objectEntity !== null) { 5546 return this.objectEntity; 5547 } 5548 const staticProperties = []; 5549 const dynamicMethods = []; 5550 for (const definition of this.body.body) { 5551 if (isStaticBlock(definition)) 5552 continue; 5553 const properties = definition.static ? staticProperties : dynamicMethods; 5554 const definitionKind = definition.kind; 5555 // Note that class fields do not end up on the prototype 5556 if (properties === dynamicMethods && !definitionKind) 5557 continue; 5558 const kind = definitionKind === 'set' || definitionKind === 'get' ? definitionKind : 'init'; 5559 let key; 5560 if (definition.computed) { 5561 const keyValue = definition.key.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 5562 if (typeof keyValue === 'symbol') { 5563 properties.push({ key: UnknownKey, kind, property: definition }); 5564 continue; 5565 } 5566 else { 5567 key = String(keyValue); 5568 } 5569 } 5570 else { 5571 key = 5572 definition.key instanceof Identifier 5573 ? definition.key.name 5574 : String(definition.key.value); 5575 } 5576 properties.push({ key, kind, property: definition }); 5577 } 5578 staticProperties.unshift({ 5579 key: 'prototype', 5580 kind: 'init', 5581 property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE) 5582 }); 5583 return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE)); 5584 } 5585 } 5586 5587 class ClassDeclaration extends ClassNode { 5588 initialise() { 5589 super.initialise(); 5590 if (this.id !== null) { 5591 this.id.variable.isId = true; 5592 } 5593 } 5594 parseNode(esTreeNode) { 5595 if (esTreeNode.id !== null) { 5596 this.id = new Identifier(this, this.scope.parent).parseNode(esTreeNode.id); 5597 } 5598 return super.parseNode(esTreeNode); 5599 } 5600 render(code, options) { 5601 const { exportNamesByVariable, format, snippets: { _, getPropertyAccess } } = options; 5602 if (this.id) { 5603 const { variable, name } = this.id; 5604 if (format === 'system' && exportNamesByVariable.has(variable)) { 5605 code.appendLeft(this.end, `${_}${getSystemExportStatement([variable], options)};`); 5606 } 5607 const renderedVariable = variable.getName(getPropertyAccess); 5608 if (renderedVariable !== name) { 5609 this.decorators.map(decorator => decorator.render(code, options)); 5610 this.superClass?.render(code, options); 5611 this.body.render(code, { 5612 ...options, 5613 useOriginalName: (_variable) => _variable === variable 5614 }); 5615 code.prependRight(this.start, `let ${renderedVariable}${_}=${_}`); 5616 code.prependLeft(this.end, ';'); 5617 return; 5618 } 5619 } 5620 super.render(code, options); 5621 } 5622 applyDeoptimizations() { 5623 super.applyDeoptimizations(); 5624 const { id, scope } = this; 5625 if (id) { 5626 const { name, variable } = id; 5627 for (const accessedVariable of scope.accessedOutsideVariables.values()) { 5628 if (accessedVariable !== variable) { 5629 accessedVariable.forbidName(name); 5630 } 5631 } 5632 } 5633 } 5634 } 5635 5636 class ArgumentsVariable extends LocalVariable { 5637 constructor(context) { 5638 super('arguments', null, UNKNOWN_EXPRESSION, context, 'other'); 5639 this.deoptimizedArguments = []; 5640 } 5641 addArgumentToBeDeoptimized(argument) { 5642 if (this.included) { 5643 argument.deoptimizePath(UNKNOWN_PATH); 5644 } 5645 else { 5646 this.deoptimizedArguments.push(argument); 5647 } 5648 } 5649 hasEffectsOnInteractionAtPath(path, { type }) { 5650 return type !== INTERACTION_ACCESSED || path.length > 1; 5651 } 5652 include() { 5653 super.include(); 5654 for (const argument of this.deoptimizedArguments) { 5655 argument.deoptimizePath(UNKNOWN_PATH); 5656 } 5657 this.deoptimizedArguments.length = 0; 5658 } 5659 } 5660 5661 const MAX_TRACKED_INTERACTIONS = 20; 5662 const NO_INTERACTIONS = EMPTY_ARRAY; 5663 const UNKNOWN_DEOPTIMIZED_FIELD = new Set([UnknownKey]); 5664 const EMPTY_PATH_TRACKER = new PathTracker(); 5665 const UNKNOWN_DEOPTIMIZED_ENTITY = new Set([UNKNOWN_EXPRESSION]); 5666 class ParameterVariable extends LocalVariable { 5667 constructor(name, declarator, context) { 5668 super(name, declarator, UNKNOWN_EXPRESSION, context, 'parameter'); 5669 this.deoptimizationInteractions = []; 5670 this.deoptimizations = new PathTracker(); 5671 this.deoptimizedFields = new Set(); 5672 this.entitiesToBeDeoptimized = new Set(); 5673 this.expressionsUseTheKnownValue = []; 5674 this.knownValue = null; 5675 this.knownValueLiteral = UnknownValue; 5676 this.frozenValue = null; 5677 } 5678 addEntityToBeDeoptimized(entity) { 5679 if (entity === UNKNOWN_EXPRESSION) { 5680 // As unknown expressions fully deoptimize all interactions, we can clear 5681 // the interaction cache at this point provided we keep this optimization 5682 // in mind when adding new interactions 5683 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) { 5684 this.entitiesToBeDeoptimized.add(UNKNOWN_EXPRESSION); 5685 for (const { interaction } of this.deoptimizationInteractions) { 5686 deoptimizeInteraction(interaction); 5687 } 5688 this.deoptimizationInteractions = NO_INTERACTIONS; 5689 } 5690 } 5691 else if (this.deoptimizedFields.has(UnknownKey)) { 5692 // This means that we already deoptimized all interactions and no longer 5693 // track them 5694 entity.deoptimizePath(UNKNOWN_PATH); 5695 } 5696 else if (!this.entitiesToBeDeoptimized.has(entity)) { 5697 this.entitiesToBeDeoptimized.add(entity); 5698 for (const field of this.deoptimizedFields) { 5699 entity.deoptimizePath([field]); 5700 } 5701 for (const { interaction, path } of this.deoptimizationInteractions) { 5702 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER); 5703 } 5704 } 5705 } 5706 markReassigned() { 5707 if (this.isReassigned) { 5708 return; 5709 } 5710 super.markReassigned(); 5711 for (const expression of this.expressionsUseTheKnownValue) { 5712 expression.deoptimizeCache(); 5713 } 5714 this.expressionsUseTheKnownValue = EMPTY_ARRAY; 5715 } 5716 deoptimizeCache() { 5717 this.markReassigned(); 5718 } 5719 /** 5720 * Update the known value of the parameter variable. 5721 * Must be called for every function call, so it can track all the arguments, 5722 * and deoptimizeCache itself to mark reassigned if the argument is changed. 5723 * @param argument The argument of the function call 5724 */ 5725 updateKnownValue(argument) { 5726 if (this.isReassigned) { 5727 return; 5728 } 5729 if (this.knownValue === null) { 5730 this.knownValue = argument; 5731 this.knownValueLiteral = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 5732 return; 5733 } 5734 // the same literal or identifier, do nothing 5735 if (this.knownValue === argument || 5736 (this.knownValue instanceof Identifier && 5737 argument instanceof Identifier && 5738 this.knownValue.variable === argument.variable)) { 5739 return; 5740 } 5741 const oldValue = this.knownValueLiteral; 5742 if (typeof oldValue === 'symbol') { 5743 this.markReassigned(); 5744 return; 5745 } 5746 // add tracking for the new argument 5747 const newValue = argument.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 5748 if (newValue !== oldValue) { 5749 this.markReassigned(); 5750 } 5751 } 5752 /** 5753 * This function freezes the known value of the parameter variable, 5754 * so the optimization starts with a certain ExpressionEntity. 5755 * The optimization can be undone by calling `markReassigned`. 5756 * @returns the frozen value 5757 */ 5758 getKnownValue() { 5759 if (this.frozenValue === null) { 5760 this.frozenValue = this.knownValue || UNKNOWN_EXPRESSION; 5761 } 5762 return this.frozenValue; 5763 } 5764 getLiteralValueAtPath(path, recursionTracker, origin) { 5765 if (this.isReassigned) { 5766 return UnknownValue; 5767 } 5768 const knownValue = this.getKnownValue(); 5769 this.expressionsUseTheKnownValue.push(origin); 5770 return recursionTracker.withTrackedEntityAtPath(path, knownValue, () => knownValue.getLiteralValueAtPath(path, recursionTracker, origin), UnknownValue); 5771 } 5772 hasEffectsOnInteractionAtPath(path, interaction, context) { 5773 if (this.isReassigned || interaction.type === INTERACTION_ASSIGNED) { 5774 return super.hasEffectsOnInteractionAtPath(path, interaction, context); 5775 } 5776 const knownValue = this.getKnownValue(); 5777 return knownValue.hasEffectsOnInteractionAtPath(path, interaction, context); 5778 } 5779 deoptimizeArgumentsOnInteractionAtPath(interaction, path) { 5780 // For performance reasons, we fully deoptimize all deeper interactions 5781 if (path.length >= 2 || 5782 this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION) || 5783 this.deoptimizationInteractions.length >= MAX_TRACKED_INTERACTIONS || 5784 (path.length === 1 && 5785 (this.deoptimizedFields.has(UnknownKey) || 5786 (interaction.type === INTERACTION_CALLED && this.deoptimizedFields.has(path[0]))))) { 5787 deoptimizeInteraction(interaction); 5788 return; 5789 } 5790 if (!this.deoptimizations.trackEntityAtPathAndGetIfTracked(path, interaction.args)) { 5791 for (const entity of this.entitiesToBeDeoptimized) { 5792 entity.deoptimizeArgumentsOnInteractionAtPath(interaction, path, SHARED_RECURSION_TRACKER); 5793 } 5794 if (!this.entitiesToBeDeoptimized.has(UNKNOWN_EXPRESSION)) { 5795 this.deoptimizationInteractions.push({ 5796 interaction, 5797 path 5798 }); 5799 } 5800 } 5801 } 5802 deoptimizePath(path) { 5803 if (path.length === 0) { 5804 this.markReassigned(); 5805 return; 5806 } 5807 if (this.deoptimizedFields.has(UnknownKey)) { 5808 return; 5809 } 5810 const key = path[0]; 5811 if (this.deoptimizedFields.has(key)) { 5812 return; 5813 } 5814 this.deoptimizedFields.add(key); 5815 for (const entity of this.entitiesToBeDeoptimized) { 5816 // We do not need a recursion tracker here as we already track whether 5817 // this field is deoptimized 5818 entity.deoptimizePath([key]); 5819 } 5820 if (key === UnknownKey) { 5821 // save some memory 5822 this.deoptimizationInteractions = NO_INTERACTIONS; 5823 this.deoptimizations = EMPTY_PATH_TRACKER; 5824 this.deoptimizedFields = UNKNOWN_DEOPTIMIZED_FIELD; 5825 this.entitiesToBeDeoptimized = UNKNOWN_DEOPTIMIZED_ENTITY; 5826 } 5827 } 5828 getReturnExpressionWhenCalledAtPath(path) { 5829 // We deoptimize everything that is called as that will trivially deoptimize 5830 // the corresponding return expressions as well and avoid badly performing 5831 // and complicated alternatives 5832 if (path.length === 0) { 5833 this.deoptimizePath(UNKNOWN_PATH); 5834 } 5835 else if (!this.deoptimizedFields.has(path[0])) { 5836 this.deoptimizePath([path[0]]); 5837 } 5838 return UNKNOWN_RETURN_EXPRESSION; 5839 } 5840 } 5841 5842 class ThisVariable extends ParameterVariable { 5843 constructor(context) { 5844 super('this', null, context); 5845 } 5846 hasEffectsOnInteractionAtPath(path, interaction, context) { 5847 return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context); 7468 5848 } 7469 5849 } … … 7646 6026 } 7647 6027 7648 function treeshakeNode(node, code, start, end) { 7649 code.remove(start, end); 7650 node.removeAnnotations(code); 7651 } 7652 7653 const NO_SEMICOLON = { isNoStatement: true }; 7654 // This assumes there are only white-space and comments between start and the string we are looking for 7655 function findFirstOccurrenceOutsideComment(code, searchString, start = 0) { 7656 let searchPos, charCodeAfterSlash; 7657 searchPos = code.indexOf(searchString, start); 7658 while (true) { 7659 start = code.indexOf('/', start); 7660 if (start === -1 || start >= searchPos) 7661 return searchPos; 7662 charCodeAfterSlash = code.charCodeAt(++start); 7663 ++start; 7664 // With our assumption, '/' always starts a comment. Determine comment type: 7665 start = 7666 charCodeAfterSlash === 47 /*"/"*/ 7667 ? code.indexOf('\n', start) + 1 7668 : code.indexOf('*/', start) + 2; 7669 if (start > searchPos) { 7670 searchPos = code.indexOf(searchString, start); 7671 } 7672 } 7673 } 7674 const NON_WHITESPACE = /\S/g; 7675 function findNonWhiteSpace(code, index) { 7676 NON_WHITESPACE.lastIndex = index; 7677 const result = NON_WHITESPACE.exec(code); 7678 return result.index; 7679 } 7680 const WHITESPACE = /\s/; 7681 function findLastWhiteSpaceReverse(code, start, end) { 7682 while (true) { 7683 if (start >= end) { 7684 return end; 7685 } 7686 if (WHITESPACE.test(code[end - 1])) { 7687 end--; 7688 } 7689 else { 7690 return end; 7691 } 7692 } 7693 } 7694 // This assumes "code" only contains white-space and comments 7695 // Returns position of line-comment if applicable 7696 function findFirstLineBreakOutsideComment(code) { 7697 let lineBreakPos, charCodeAfterSlash, start = 0; 7698 lineBreakPos = code.indexOf('\n', start); 7699 while (true) { 7700 start = code.indexOf('/', start); 7701 if (start === -1 || start > lineBreakPos) 7702 return [lineBreakPos, lineBreakPos + 1]; 7703 // With our assumption, '/' always starts a comment. Determine comment type: 7704 charCodeAfterSlash = code.charCodeAt(start + 1); 7705 if (charCodeAfterSlash === 47 /*"/"*/) 7706 return [start, lineBreakPos + 1]; 7707 start = code.indexOf('*/', start + 2) + 2; 7708 if (start > lineBreakPos) { 7709 lineBreakPos = code.indexOf('\n', start); 7710 } 7711 } 7712 } 7713 function renderStatementList(statements, code, start, end, options) { 7714 let currentNode, currentNodeStart, currentNodeNeedsBoundaries, nextNodeStart; 7715 let nextNode = statements[0]; 7716 let nextNodeNeedsBoundaries = !nextNode.included || nextNode.needsBoundaries; 7717 if (nextNodeNeedsBoundaries) { 7718 nextNodeStart = 7719 start + findFirstLineBreakOutsideComment(code.original.slice(start, nextNode.start))[1]; 7720 } 7721 for (let nextIndex = 1; nextIndex <= statements.length; nextIndex++) { 7722 currentNode = nextNode; 7723 currentNodeStart = nextNodeStart; 7724 currentNodeNeedsBoundaries = nextNodeNeedsBoundaries; 7725 nextNode = statements[nextIndex]; 7726 nextNodeNeedsBoundaries = 7727 nextNode === undefined ? false : !nextNode.included || nextNode.needsBoundaries; 7728 if (currentNodeNeedsBoundaries || nextNodeNeedsBoundaries) { 7729 nextNodeStart = 7730 currentNode.end + 7731 findFirstLineBreakOutsideComment(code.original.slice(currentNode.end, nextNode === undefined ? end : nextNode.start))[1]; 7732 if (currentNode.included) { 7733 currentNodeNeedsBoundaries 7734 ? currentNode.render(code, options, { 7735 end: nextNodeStart, 7736 start: currentNodeStart 7737 }) 7738 : currentNode.render(code, options); 7739 } 7740 else { 7741 treeshakeNode(currentNode, code, currentNodeStart, nextNodeStart); 7742 } 7743 } 7744 else { 7745 currentNode.render(code, options); 7746 } 7747 } 7748 } 7749 // This assumes that the first character is not part of the first node 7750 function getCommaSeparatedNodesWithBoundaries(nodes, code, start, end) { 7751 const splitUpNodes = []; 7752 let node, nextNodeStart, contentEnd, char; 7753 let separator = start - 1; 7754 for (const nextNode of nodes) { 7755 if (node !== undefined) { 7756 separator = 7757 node.end + 7758 findFirstOccurrenceOutsideComment(code.original.slice(node.end, nextNode.start), ','); 7759 } 7760 nextNodeStart = contentEnd = 7761 separator + 7762 1 + 7763 findFirstLineBreakOutsideComment(code.original.slice(separator + 1, nextNode.start))[1]; 7764 while (((char = code.original.charCodeAt(nextNodeStart)), 7765 char === 32 /*" "*/ || char === 9 /*"\t"*/ || char === 10 /*"\n"*/ || char === 13) /*"\r"*/) 7766 nextNodeStart++; 7767 if (node !== undefined) { 7768 splitUpNodes.push({ 7769 contentEnd, 7770 end: nextNodeStart, 7771 node, 7772 separator, 7773 start 7774 }); 7775 } 7776 node = nextNode; 7777 start = nextNodeStart; 7778 } 7779 splitUpNodes.push({ 7780 contentEnd: end, 7781 end, 7782 node: node, 7783 separator: null, 7784 start 7785 }); 7786 return splitUpNodes; 7787 } 7788 // This assumes there are only white-space and comments between start and end 7789 function removeLineBreaks(code, start, end) { 7790 while (true) { 7791 const [removeStart, removeEnd] = findFirstLineBreakOutsideComment(code.original.slice(start, end)); 7792 if (removeStart === -1) { 7793 break; 7794 } 7795 code.remove(start + removeStart, (start += removeEnd)); 7796 } 7797 } 7798 7799 class BlockScope extends ChildScope { 6028 class FunctionScope extends ReturnValueScope { 7800 6029 constructor(parent) { 7801 super(parent, parent.context); 7802 } 7803 addDeclaration(identifier, context, init, kind) { 7804 if (kind === 'var') { 7805 const name = identifier.name; 7806 const existingVariable = this.hoistedVariables?.get(name) || this.variables.get(name); 7807 if (existingVariable) { 7808 if (existingVariable.kind === 'var' || 7809 (kind === 'var' && existingVariable.kind === 'parameter')) { 7810 existingVariable.addDeclaration(identifier, init); 7811 return existingVariable; 6030 const { context } = parent; 6031 super(parent, false); 6032 this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context))); 6033 this.variables.set('this', (this.thisVariable = new ThisVariable(context))); 6034 } 6035 findLexicalBoundary() { 6036 return this; 6037 } 6038 includeCallArguments(context, parameters) { 6039 super.includeCallArguments(context, parameters); 6040 if (this.argumentsVariable.included) { 6041 for (const argument of parameters) { 6042 if (!argument.included) { 6043 argument.include(context, false); 7812 6044 } 7813 return context.error(logRedeclarationError(name), identifier.start); 7814 } 7815 const declaredVariable = this.parent.addDeclaration(identifier, context, init, kind); 7816 // Necessary to make sure the init is deoptimized for conditional declarations. 7817 // We cannot call deoptimizePath here. 7818 declaredVariable.markInitializersForDeoptimization(); 7819 // We add the variable to this and all parent scopes to reliably detect conflicts 7820 this.addHoistedVariable(name, declaredVariable); 7821 return declaredVariable; 7822 } 7823 return super.addDeclaration(identifier, context, init, kind); 6045 } 6046 } 7824 6047 } 7825 6048 } … … 7930 6153 } 7931 6154 deoptimizePath(path) { 7932 path.length === 0 && this.argument.deoptimizePath(EMPTY_PATH); 6155 if (path.length === 0) { 6156 this.argument.deoptimizePath(EMPTY_PATH); 6157 } 7933 6158 } 7934 6159 hasEffectsOnInteractionAtPath(path, interaction, context) { … … 8138 6363 FunctionBase.prototype.preventChildBlockScope = true; 8139 6364 8140 class ArrowFunctionExpression extends FunctionBase {8141 constructor() {8142 super(...arguments);8143 this.objectEntity = null;8144 }8145 get expression() {8146 return isFlagSet(this.flags, 8388608 /* Flag.expression */);8147 }8148 set expression(value) {8149 this.flags = setFlag(this.flags, 8388608 /* Flag.expression */, value);8150 }8151 createScope(parentScope) {8152 this.scope = new ReturnValueScope(parentScope, false);8153 }8154 hasEffects() {8155 if (!this.deoptimized)8156 this.applyDeoptimizations();8157 return false;8158 }8159 hasEffectsOnInteractionAtPath(path, interaction, context) {8160 if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) {8161 return true;8162 }8163 if (this.annotationNoSideEffects) {8164 return false;8165 }8166 if (interaction.type === INTERACTION_CALLED) {8167 const { ignore, brokenFlow } = context;8168 context.ignore = {8169 breaks: false,8170 continues: false,8171 labels: new Set(),8172 returnYield: true,8173 this: false8174 };8175 if (this.body.hasEffects(context))8176 return true;8177 context.ignore = ignore;8178 context.brokenFlow = brokenFlow;8179 }8180 return false;8181 }8182 onlyFunctionCallUsed() {8183 const isIIFE = this.parent.type === CallExpression$1 &&8184 this.parent.callee === this;8185 return isIIFE || super.onlyFunctionCallUsed();8186 }8187 include(context, includeChildrenRecursively) {8188 super.include(context, includeChildrenRecursively);8189 for (const parameter of this.params) {8190 if (!(parameter instanceof Identifier)) {8191 parameter.include(context, includeChildrenRecursively);8192 }8193 }8194 }8195 getObjectEntity() {8196 if (this.objectEntity !== null) {8197 return this.objectEntity;8198 }8199 return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE));8200 }8201 }8202 8203 function getSystemExportStatement(exportedVariables, { exportNamesByVariable, snippets: { _, getObject, getPropertyAccess } }, modifier = '') {8204 if (exportedVariables.length === 1 &&8205 exportNamesByVariable.get(exportedVariables[0]).length === 1) {8206 const variable = exportedVariables[0];8207 return `exports(${JSON.stringify(exportNamesByVariable.get(variable)[0])},${_}${variable.getName(getPropertyAccess)}${modifier})`;8208 }8209 else {8210 const fields = [];8211 for (const variable of exportedVariables) {8212 for (const exportName of exportNamesByVariable.get(variable)) {8213 fields.push([exportName, variable.getName(getPropertyAccess) + modifier]);8214 }8215 }8216 return `exports(${getObject(fields, { lineBreakIndent: null })})`;8217 }8218 }8219 // This is only invoked if there is exactly one export name8220 function renderSystemExportExpression(exportedVariable, expressionStart, expressionEnd, code, { exportNamesByVariable, snippets: { _ } }) {8221 code.prependRight(expressionStart, `exports(${JSON.stringify(exportNamesByVariable.get(exportedVariable)[0])},${_}`);8222 code.appendLeft(expressionEnd, ')');8223 }8224 function renderSystemExportFunction(exportedVariables, expressionStart, expressionEnd, needsParens, code, options) {8225 const { _, getDirectReturnIifeLeft } = options.snippets;8226 code.prependRight(expressionStart, getDirectReturnIifeLeft(['v'], `${getSystemExportStatement(exportedVariables, options)},${_}v`, { needsArrowReturnParens: true, needsWrappedFunction: needsParens }));8227 code.appendLeft(expressionEnd, ')');8228 }8229 function renderSystemExportSequenceAfterExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options) {8230 const { _, getPropertyAccess } = options.snippets;8231 code.appendLeft(expressionEnd, `,${_}${getSystemExportStatement([exportedVariable], options)},${_}${exportedVariable.getName(getPropertyAccess)}`);8232 if (needsParens) {8233 code.prependRight(expressionStart, '(');8234 code.appendLeft(expressionEnd, ')');8235 }8236 }8237 function renderSystemExportSequenceBeforeExpression(exportedVariable, expressionStart, expressionEnd, needsParens, code, options, modifier) {8238 const { _ } = options.snippets;8239 code.prependRight(expressionStart, `${getSystemExportStatement([exportedVariable], options, modifier)},${_}`);8240 if (needsParens) {8241 code.prependRight(expressionStart, '(');8242 code.appendLeft(expressionEnd, ')');8243 }8244 }8245 8246 class ObjectPattern extends NodeBase {8247 addExportedVariables(variables, exportNamesByVariable) {8248 for (const property of this.properties) {8249 if (property.type === Property$1) {8250 property.value.addExportedVariables(variables, exportNamesByVariable);8251 }8252 else {8253 property.argument.addExportedVariables(variables, exportNamesByVariable);8254 }8255 }8256 }8257 declare(kind, init) {8258 const variables = [];8259 for (const property of this.properties) {8260 variables.push(...property.declare(kind, init));8261 }8262 return variables;8263 }8264 deoptimizePath(path) {8265 if (path.length === 0) {8266 for (const property of this.properties) {8267 property.deoptimizePath(path);8268 }8269 }8270 }8271 hasEffectsOnInteractionAtPath(8272 // At the moment, this is only triggered for assignment left-hand sides,8273 // where the path is empty8274 _path, interaction, context) {8275 for (const property of this.properties) {8276 if (property.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context))8277 return true;8278 }8279 return false;8280 }8281 markDeclarationReached() {8282 for (const property of this.properties) {8283 property.markDeclarationReached();8284 }8285 }8286 }8287 8288 class AssignmentExpression extends NodeBase {8289 hasEffects(context) {8290 const { deoptimized, left, operator, right } = this;8291 if (!deoptimized)8292 this.applyDeoptimizations();8293 // MemberExpressions do not access the property before assignments if the8294 // operator is '='.8295 return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '='));8296 }8297 hasEffectsOnInteractionAtPath(path, interaction, context) {8298 return this.right.hasEffectsOnInteractionAtPath(path, interaction, context);8299 }8300 include(context, includeChildrenRecursively) {8301 const { deoptimized, left, right, operator } = this;8302 if (!deoptimized)8303 this.applyDeoptimizations();8304 this.included = true;8305 if (includeChildrenRecursively ||8306 operator !== '=' ||8307 left.included ||8308 left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) {8309 left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '=');8310 }8311 right.include(context, includeChildrenRecursively);8312 }8313 initialise() {8314 super.initialise();8315 if (this.left instanceof Identifier) {8316 const variable = this.scope.variables.get(this.left.name);8317 if (variable?.kind === 'const') {8318 this.scope.context.error(logConstVariableReassignError(), this.left.start);8319 }8320 }8321 this.left.setAssignedValue(this.right);8322 }8323 render(code, options, { preventASI, renderedParentType, renderedSurroundingElement } = BLANK) {8324 const { left, right, start, end, parent } = this;8325 if (left.included) {8326 left.render(code, options);8327 right.render(code, options);8328 }8329 else {8330 const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', left.end) + 1);8331 code.remove(start, inclusionStart);8332 if (preventASI) {8333 removeLineBreaks(code, inclusionStart, right.start);8334 }8335 right.render(code, options, {8336 renderedParentType: renderedParentType || parent.type,8337 renderedSurroundingElement: renderedSurroundingElement || parent.type8338 });8339 }8340 if (options.format === 'system') {8341 if (left instanceof Identifier) {8342 const variable = left.variable;8343 const exportNames = options.exportNamesByVariable.get(variable);8344 if (exportNames) {8345 if (exportNames.length === 1) {8346 renderSystemExportExpression(variable, start, end, code, options);8347 }8348 else {8349 renderSystemExportSequenceAfterExpression(variable, start, end, parent.type !== ExpressionStatement$1, code, options);8350 }8351 return;8352 }8353 }8354 else {8355 const systemPatternExports = [];8356 left.addExportedVariables(systemPatternExports, options.exportNamesByVariable);8357 if (systemPatternExports.length > 0) {8358 renderSystemExportFunction(systemPatternExports, start, end, renderedSurroundingElement === ExpressionStatement$1, code, options);8359 return;8360 }8361 }8362 }8363 if (left.included &&8364 left instanceof ObjectPattern &&8365 (renderedSurroundingElement === ExpressionStatement$1 ||8366 renderedSurroundingElement === ArrowFunctionExpression$1)) {8367 code.appendRight(start, '(');8368 code.prependLeft(end, ')');8369 }8370 }8371 applyDeoptimizations() {8372 this.deoptimized = true;8373 this.left.deoptimizePath(EMPTY_PATH);8374 this.right.deoptimizePath(UNKNOWN_PATH);8375 this.scope.context.requestTreeshakingPass();8376 }8377 }8378 8379 class AssignmentPattern extends NodeBase {8380 addExportedVariables(variables, exportNamesByVariable) {8381 this.left.addExportedVariables(variables, exportNamesByVariable);8382 }8383 declare(kind, init) {8384 return this.left.declare(kind, init);8385 }8386 deoptimizePath(path) {8387 path.length === 0 && this.left.deoptimizePath(path);8388 }8389 hasEffectsOnInteractionAtPath(path, interaction, context) {8390 return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context));8391 }8392 markDeclarationReached() {8393 this.left.markDeclarationReached();8394 }8395 render(code, options, { isShorthandProperty } = BLANK) {8396 this.left.render(code, options, { isShorthandProperty });8397 this.right.render(code, options);8398 }8399 applyDeoptimizations() {8400 this.deoptimized = true;8401 this.left.deoptimizePath(EMPTY_PATH);8402 this.right.deoptimizePath(UNKNOWN_PATH);8403 this.scope.context.requestTreeshakingPass();8404 }8405 }8406 8407 class ArgumentsVariable extends LocalVariable {8408 constructor(context) {8409 super('arguments', null, UNKNOWN_EXPRESSION, context, 'other');8410 this.deoptimizedArguments = [];8411 }8412 addArgumentToBeDeoptimized(argument) {8413 if (this.included) {8414 argument.deoptimizePath(UNKNOWN_PATH);8415 }8416 else {8417 this.deoptimizedArguments.push(argument);8418 }8419 }8420 hasEffectsOnInteractionAtPath(path, { type }) {8421 return type !== INTERACTION_ACCESSED || path.length > 1;8422 }8423 include() {8424 super.include();8425 for (const argument of this.deoptimizedArguments) {8426 argument.deoptimizePath(UNKNOWN_PATH);8427 }8428 this.deoptimizedArguments.length = 0;8429 }8430 }8431 8432 class ThisVariable extends ParameterVariable {8433 constructor(context) {8434 super('this', null, context);8435 }8436 hasEffectsOnInteractionAtPath(path, interaction, context) {8437 return (context.replacedVariableInits.get(this) || UNKNOWN_EXPRESSION).hasEffectsOnInteractionAtPath(path, interaction, context);8438 }8439 }8440 8441 class FunctionScope extends ReturnValueScope {8442 constructor(parent) {8443 const { context } = parent;8444 super(parent, false);8445 this.variables.set('arguments', (this.argumentsVariable = new ArgumentsVariable(context)));8446 this.variables.set('this', (this.thisVariable = new ThisVariable(context)));8447 }8448 findLexicalBoundary() {8449 return this;8450 }8451 includeCallArguments(context, parameters) {8452 super.includeCallArguments(context, parameters);8453 if (this.argumentsVariable.included) {8454 for (const argument of parameters) {8455 if (!argument.included) {8456 argument.include(context, false);8457 }8458 }8459 }8460 }8461 }8462 8463 6365 class FunctionNode extends FunctionBase { 8464 6366 constructor() { … … 8549 6451 } 8550 6452 8551 class AwaitExpression extends NodeBase {8552 hasEffects() {8553 if (!this.deoptimized)8554 this.applyDeoptimizations();8555 return true;8556 }8557 include(context, includeChildrenRecursively) {8558 if (!this.deoptimized)8559 this.applyDeoptimizations();8560 if (!this.included) {8561 this.included = true;8562 checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) {8563 let parent = this.parent;8564 do {8565 if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression)8566 break checkTopLevelAwait;8567 } while ((parent = parent.parent));8568 this.scope.context.usesTopLevelAwait = true;8569 }8570 }8571 this.argument.include(context, includeChildrenRecursively);8572 }8573 }8574 8575 const binaryOperators = {8576 '!=': (left, right) => left != right,8577 '!==': (left, right) => left !== right,8578 '%': (left, right) => left % right,8579 '&': (left, right) => left & right,8580 '*': (left, right) => left * right,8581 // At the moment, "**" will be transpiled to Math.pow8582 '**': (left, right) => left ** right,8583 '+': (left, right) => left + right,8584 '-': (left, right) => left - right,8585 '/': (left, right) => left / right,8586 '<': (left, right) => left < right,8587 '<<': (left, right) => left << right,8588 '<=': (left, right) => left <= right,8589 '==': (left, right) => left == right,8590 '===': (left, right) => left === right,8591 '>': (left, right) => left > right,8592 '>=': (left, right) => left >= right,8593 '>>': (left, right) => left >> right,8594 '>>>': (left, right) => left >>> right,8595 '^': (left, right) => left ^ right,8596 '|': (left, right) => left | right8597 // We use the fallback for cases where we return something unknown8598 // in: () => UnknownValue,8599 // instanceof: () => UnknownValue,8600 };8601 class BinaryExpression extends NodeBase {8602 deoptimizeCache() { }8603 getLiteralValueAtPath(path, recursionTracker, origin) {8604 if (path.length > 0)8605 return UnknownValue;8606 const leftValue = this.left.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin);8607 if (typeof leftValue === 'symbol')8608 return UnknownValue;8609 const rightValue = this.right.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin);8610 if (typeof rightValue === 'symbol')8611 return UnknownValue;8612 const operatorFunction = binaryOperators[this.operator];8613 if (!operatorFunction)8614 return UnknownValue;8615 return operatorFunction(leftValue, rightValue);8616 }8617 hasEffects(context) {8618 // support some implicit type coercion runtime errors8619 if (this.operator === '+' &&8620 this.parent instanceof ExpressionStatement &&8621 this.left.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) === '') {8622 return true;8623 }8624 return super.hasEffects(context);8625 }8626 hasEffectsOnInteractionAtPath(path, { type }) {8627 return type !== INTERACTION_ACCESSED || path.length > 1;8628 }8629 removeAnnotations(code) {8630 this.left.removeAnnotations(code);8631 }8632 render(code, options, { renderedSurroundingElement } = BLANK) {8633 this.left.render(code, options, { renderedSurroundingElement });8634 this.right.render(code, options);8635 }8636 }8637 8638 class BreakStatement extends NodeBase {8639 hasEffects(context) {8640 if (this.label) {8641 if (!context.ignore.labels.has(this.label.name))8642 return true;8643 context.includedLabels.add(this.label.name);8644 }8645 else {8646 if (!context.ignore.breaks)8647 return true;8648 context.hasBreak = true;8649 }8650 context.brokenFlow = true;8651 return false;8652 }8653 include(context) {8654 this.included = true;8655 if (this.label) {8656 this.label.include();8657 context.includedLabels.add(this.label.name);8658 }8659 else {8660 context.hasBreak = true;8661 }8662 context.brokenFlow = true;8663 }8664 }8665 8666 function renderCallArguments(code, options, node) {8667 if (node.arguments.length > 0) {8668 if (node.arguments[node.arguments.length - 1].included) {8669 for (const argument of node.arguments) {8670 argument.render(code, options);8671 }8672 }8673 else {8674 let lastIncludedIndex = node.arguments.length - 2;8675 while (lastIncludedIndex >= 0 && !node.arguments[lastIncludedIndex].included) {8676 lastIncludedIndex--;8677 }8678 if (lastIncludedIndex >= 0) {8679 for (let index = 0; index <= lastIncludedIndex; index++) {8680 node.arguments[index].render(code, options);8681 }8682 code.remove(findFirstOccurrenceOutsideComment(code.original, ',', node.arguments[lastIncludedIndex].end), node.end - 1);8683 }8684 else {8685 code.remove(findFirstOccurrenceOutsideComment(code.original, '(', node.callee.end) + 1, node.end - 1);8686 }8687 }8688 }8689 }8690 8691 class Literal extends NodeBase {8692 deoptimizeArgumentsOnInteractionAtPath() { }8693 getLiteralValueAtPath(path) {8694 if (path.length > 0 ||8695 // unknown literals can also be null but do not start with an "n"8696 (this.value === null && this.scope.context.code.charCodeAt(this.start) !== 110) ||8697 typeof this.value === 'bigint' ||8698 // to support shims for regular expressions8699 this.scope.context.code.charCodeAt(this.start) === 47) {8700 return UnknownValue;8701 }8702 return this.value;8703 }8704 getReturnExpressionWhenCalledAtPath(path) {8705 if (path.length !== 1)8706 return UNKNOWN_RETURN_EXPRESSION;8707 return getMemberReturnExpressionWhenCalled(this.members, path[0]);8708 }8709 hasEffectsOnInteractionAtPath(path, interaction, context) {8710 switch (interaction.type) {8711 case INTERACTION_ACCESSED: {8712 return path.length > (this.value === null ? 0 : 1);8713 }8714 case INTERACTION_ASSIGNED: {8715 return true;8716 }8717 case INTERACTION_CALLED: {8718 if (this.included &&8719 this.value instanceof RegExp &&8720 (this.value.global || this.value.sticky)) {8721 return true;8722 }8723 return (path.length !== 1 ||8724 hasMemberEffectWhenCalled(this.members, path[0], interaction, context));8725 }8726 }8727 }8728 initialise() {8729 super.initialise();8730 this.members = getLiteralMembersForValue(this.value);8731 }8732 parseNode(esTreeNode) {8733 this.value = esTreeNode.value;8734 this.regex = esTreeNode.regex;8735 return super.parseNode(esTreeNode);8736 }8737 render(code) {8738 if (typeof this.value === 'string') {8739 code.indentExclusionRanges.push([this.start + 1, this.end - 1]);8740 }8741 }8742 }8743 8744 function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) {8745 if ('getLiteralValueAtPathAsChainElement' in object) {8746 const calleeValue = object.getLiteralValueAtPathAsChainElement(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin);8747 if (calleeValue === IS_SKIPPED_CHAIN || (element.optional && calleeValue == null)) {8748 return IS_SKIPPED_CHAIN;8749 }8750 }8751 else if (element.optional &&8752 object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin) == null) {8753 return IS_SKIPPED_CHAIN;8754 }8755 return element.getLiteralValueAtPath(path, recursionTracker, origin);8756 }8757 8758 // To avoid infinite recursions8759 const MAX_PATH_DEPTH = 7;8760 function getResolvablePropertyKey(memberExpression) {8761 return memberExpression.computed8762 ? getResolvableComputedPropertyKey(memberExpression.property)8763 : memberExpression.property.name;8764 }8765 function getResolvableComputedPropertyKey(propertyKey) {8766 if (propertyKey instanceof Literal) {8767 return String(propertyKey.value);8768 }8769 return null;8770 }8771 function getPathIfNotComputed(memberExpression) {8772 const nextPathKey = memberExpression.propertyKey;8773 const object = memberExpression.object;8774 if (typeof nextPathKey === 'string') {8775 if (object instanceof Identifier) {8776 return [8777 { key: object.name, pos: object.start },8778 { key: nextPathKey, pos: memberExpression.property.start }8779 ];8780 }8781 if (object instanceof MemberExpression) {8782 const parentPath = getPathIfNotComputed(object);8783 return (parentPath && [...parentPath, { key: nextPathKey, pos: memberExpression.property.start }]);8784 }8785 }8786 return null;8787 }8788 function getStringFromPath(path) {8789 let pathString = path[0].key;8790 for (let index = 1; index < path.length; index++) {8791 pathString += '.' + path[index].key;8792 }8793 return pathString;8794 }8795 class MemberExpression extends NodeBase {8796 constructor() {8797 super(...arguments);8798 this.variable = null;8799 this.expressionsToBeDeoptimized = [];8800 }8801 get computed() {8802 return isFlagSet(this.flags, 1024 /* Flag.computed */);8803 }8804 set computed(value) {8805 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value);8806 }8807 get optional() {8808 return isFlagSet(this.flags, 128 /* Flag.optional */);8809 }8810 set optional(value) {8811 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value);8812 }8813 get assignmentDeoptimized() {8814 return isFlagSet(this.flags, 16 /* Flag.assignmentDeoptimized */);8815 }8816 set assignmentDeoptimized(value) {8817 this.flags = setFlag(this.flags, 16 /* Flag.assignmentDeoptimized */, value);8818 }8819 get bound() {8820 return isFlagSet(this.flags, 32 /* Flag.bound */);8821 }8822 set bound(value) {8823 this.flags = setFlag(this.flags, 32 /* Flag.bound */, value);8824 }8825 get isUndefined() {8826 return isFlagSet(this.flags, 64 /* Flag.isUndefined */);8827 }8828 set isUndefined(value) {8829 this.flags = setFlag(this.flags, 64 /* Flag.isUndefined */, value);8830 }8831 bind() {8832 this.bound = true;8833 const path = getPathIfNotComputed(this);8834 const baseVariable = path && this.scope.findVariable(path[0].key);8835 if (baseVariable?.isNamespace) {8836 const resolvedVariable = resolveNamespaceVariables(baseVariable, path.slice(1), this.scope.context);8837 if (!resolvedVariable) {8838 super.bind();8839 }8840 else if (resolvedVariable === 'undefined') {8841 this.isUndefined = true;8842 }8843 else {8844 this.variable = resolvedVariable;8845 this.scope.addNamespaceMemberAccess(getStringFromPath(path), resolvedVariable);8846 }8847 }8848 else {8849 super.bind();8850 }8851 }8852 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {8853 if (this.variable) {8854 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);8855 }8856 else if (!this.isUndefined) {8857 if (path.length < MAX_PATH_DEPTH) {8858 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker);8859 }8860 else {8861 deoptimizeInteraction(interaction);8862 }8863 }8864 }8865 deoptimizeCache() {8866 const { expressionsToBeDeoptimized, object } = this;8867 this.expressionsToBeDeoptimized = EMPTY_ARRAY;8868 this.propertyKey = UnknownKey;8869 object.deoptimizePath(UNKNOWN_PATH);8870 for (const expression of expressionsToBeDeoptimized) {8871 expression.deoptimizeCache();8872 }8873 }8874 deoptimizePath(path) {8875 if (path.length === 0)8876 this.disallowNamespaceReassignment();8877 if (this.variable) {8878 this.variable.deoptimizePath(path);8879 }8880 else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) {8881 const propertyKey = this.getPropertyKey();8882 this.object.deoptimizePath([8883 propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey,8884 ...path8885 ]);8886 }8887 }8888 getLiteralValueAtPath(path, recursionTracker, origin) {8889 if (this.variable) {8890 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin);8891 }8892 if (this.isUndefined) {8893 return undefined;8894 }8895 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {8896 this.expressionsToBeDeoptimized.push(origin);8897 return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin);8898 }8899 return UnknownValue;8900 }8901 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) {8902 if (this.variable) {8903 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin);8904 }8905 if (this.isUndefined) {8906 return undefined;8907 }8908 return getChainElementLiteralValueAtPath(this, this.object, path, recursionTracker, origin);8909 }8910 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {8911 if (this.variable) {8912 return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);8913 }8914 if (this.isUndefined) {8915 return [UNDEFINED_EXPRESSION, false];8916 }8917 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) {8918 this.expressionsToBeDeoptimized.push(origin);8919 return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin);8920 }8921 return UNKNOWN_RETURN_EXPRESSION;8922 }8923 hasEffects(context) {8924 if (!this.deoptimized)8925 this.applyDeoptimizations();8926 return (this.property.hasEffects(context) ||8927 this.object.hasEffects(context) ||8928 this.hasAccessEffect(context));8929 }8930 hasEffectsAsChainElement(context) {8931 if (this.variable || this.isUndefined)8932 return this.hasEffects(context);8933 const objectHasEffects = 'hasEffectsAsChainElement' in this.object8934 ? this.object.hasEffectsAsChainElement(context)8935 : this.object.hasEffects(context);8936 if (objectHasEffects === IS_SKIPPED_CHAIN)8937 return IS_SKIPPED_CHAIN;8938 if (this.optional &&8939 this.object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) {8940 return objectHasEffects || IS_SKIPPED_CHAIN;8941 }8942 // We only apply deoptimizations lazily once we know we are not skipping8943 if (!this.deoptimized)8944 this.applyDeoptimizations();8945 return this.property.hasEffects(context) || this.hasAccessEffect(context);8946 }8947 hasEffectsAsAssignmentTarget(context, checkAccess) {8948 if (checkAccess && !this.deoptimized)8949 this.applyDeoptimizations();8950 if (!this.assignmentDeoptimized)8951 this.applyAssignmentDeoptimization();8952 return (this.property.hasEffects(context) ||8953 this.object.hasEffects(context) ||8954 (checkAccess && this.hasAccessEffect(context)) ||8955 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context));8956 }8957 hasEffectsOnInteractionAtPath(path, interaction, context) {8958 if (this.variable) {8959 return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context);8960 }8961 if (this.isUndefined) {8962 return true;8963 }8964 if (path.length < MAX_PATH_DEPTH) {8965 return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context);8966 }8967 return true;8968 }8969 include(context, includeChildrenRecursively) {8970 if (!this.deoptimized)8971 this.applyDeoptimizations();8972 this.includeProperties(context, includeChildrenRecursively);8973 }8974 includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) {8975 if (!this.assignmentDeoptimized)8976 this.applyAssignmentDeoptimization();8977 if (deoptimizeAccess) {8978 this.include(context, includeChildrenRecursively);8979 }8980 else {8981 this.includeProperties(context, includeChildrenRecursively);8982 }8983 }8984 includeCallArguments(context, parameters) {8985 if (this.variable) {8986 this.variable.includeCallArguments(context, parameters);8987 }8988 else {8989 super.includeCallArguments(context, parameters);8990 }8991 }8992 initialise() {8993 super.initialise();8994 this.propertyKey = getResolvablePropertyKey(this);8995 this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED };8996 }8997 render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = BLANK) {8998 if (this.variable || this.isUndefined) {8999 const { snippets: { getPropertyAccess } } = options;9000 let replacement = this.variable ? this.variable.getName(getPropertyAccess) : 'undefined';9001 if (renderedParentType && isCalleeOfRenderedParent)9002 replacement = '0, ' + replacement;9003 code.overwrite(this.start, this.end, replacement, {9004 contentOnly: true,9005 storeName: true9006 });9007 }9008 else {9009 if (renderedParentType && isCalleeOfRenderedParent) {9010 code.appendRight(this.start, '0, ');9011 }9012 this.object.render(code, options, { renderedSurroundingElement });9013 this.property.render(code, options);9014 }9015 }9016 setAssignedValue(value) {9017 this.assignmentInteraction = {9018 args: [this.object, value],9019 type: INTERACTION_ASSIGNED9020 };9021 }9022 applyDeoptimizations() {9023 this.deoptimized = true;9024 const { propertyReadSideEffects } = this.scope.context.options9025 .treeshake;9026 if (9027 // Namespaces are not bound and should not be deoptimized9028 this.bound &&9029 propertyReadSideEffects &&9030 !(this.variable || this.isUndefined)) {9031 const propertyKey = this.getPropertyKey();9032 this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER);9033 this.scope.context.requestTreeshakingPass();9034 }9035 if (this.variable) {9036 this.variable.addUsedPlace(this);9037 this.scope.context.requestTreeshakingPass();9038 }9039 }9040 applyAssignmentDeoptimization() {9041 this.assignmentDeoptimized = true;9042 const { propertyReadSideEffects } = this.scope.context.options9043 .treeshake;9044 if (9045 // Namespaces are not bound and should not be deoptimized9046 this.bound &&9047 propertyReadSideEffects &&9048 !(this.variable || this.isUndefined)) {9049 this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER);9050 this.scope.context.requestTreeshakingPass();9051 }9052 }9053 disallowNamespaceReassignment() {9054 if (this.object instanceof Identifier) {9055 const variable = this.scope.findVariable(this.object.name);9056 if (variable.isNamespace) {9057 if (this.variable) {9058 this.scope.context.includeVariableInModule(this.variable);9059 }9060 this.scope.context.log(LOGLEVEL_WARN, logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start);9061 }9062 }9063 }9064 getPropertyKey() {9065 if (this.propertyKey === null) {9066 this.propertyKey = UnknownKey;9067 const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);9068 return (this.propertyKey =9069 value === SymbolToStringTag9070 ? value9071 : typeof value === 'symbol'9072 ? UnknownKey9073 : String(value));9074 }9075 return this.propertyKey;9076 }9077 hasAccessEffect(context) {9078 const { propertyReadSideEffects } = this.scope.context.options9079 .treeshake;9080 return (!(this.variable || this.isUndefined) &&9081 propertyReadSideEffects &&9082 (propertyReadSideEffects === 'always' ||9083 this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context)));9084 }9085 includeProperties(context, includeChildrenRecursively) {9086 if (!this.included) {9087 this.included = true;9088 if (this.variable) {9089 this.scope.context.includeVariableInModule(this.variable);9090 }9091 }9092 this.object.include(context, includeChildrenRecursively);9093 this.property.include(context, includeChildrenRecursively);9094 }9095 }9096 function resolveNamespaceVariables(baseVariable, path, astContext) {9097 if (path.length === 0)9098 return baseVariable;9099 if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable)9100 return null;9101 const exportName = path[0].key;9102 const variable = baseVariable.context.traceExport(exportName);9103 if (!variable) {9104 if (path.length === 1) {9105 const fileName = baseVariable.context.fileName;9106 astContext.log(LOGLEVEL_WARN, logMissingExport(exportName, astContext.module.id, fileName), path[0].pos);9107 return 'undefined';9108 }9109 return null;9110 }9111 return resolveNamespaceVariables(variable, path.slice(1), astContext);9112 }9113 9114 class CallExpressionBase extends NodeBase {9115 constructor() {9116 super(...arguments);9117 this.returnExpression = null;9118 this.deoptimizableDependentExpressions = [];9119 this.expressionsToBeDeoptimized = new Set();9120 }9121 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {9122 const { args } = interaction;9123 const [returnExpression, isPure] = this.getReturnExpression(recursionTracker);9124 if (isPure)9125 return;9126 const deoptimizedExpressions = args.filter(expression => !!expression && expression !== UNKNOWN_EXPRESSION);9127 if (deoptimizedExpressions.length === 0)9128 return;9129 if (returnExpression === UNKNOWN_EXPRESSION) {9130 for (const expression of deoptimizedExpressions) {9131 expression.deoptimizePath(UNKNOWN_PATH);9132 }9133 }9134 else {9135 recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {9136 for (const expression of deoptimizedExpressions) {9137 this.expressionsToBeDeoptimized.add(expression);9138 }9139 returnExpression.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);9140 }, null);9141 }9142 }9143 deoptimizeCache() {9144 if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) {9145 this.returnExpression = UNKNOWN_RETURN_EXPRESSION;9146 const { deoptimizableDependentExpressions, expressionsToBeDeoptimized } = this;9147 this.expressionsToBeDeoptimized = EMPTY_SET;9148 this.deoptimizableDependentExpressions = EMPTY_ARRAY;9149 for (const expression of deoptimizableDependentExpressions) {9150 expression.deoptimizeCache();9151 }9152 for (const expression of expressionsToBeDeoptimized) {9153 expression.deoptimizePath(UNKNOWN_PATH);9154 }9155 }9156 }9157 deoptimizePath(path) {9158 if (path.length === 0 ||9159 this.scope.context.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) {9160 return;9161 }9162 const [returnExpression] = this.getReturnExpression();9163 if (returnExpression !== UNKNOWN_EXPRESSION) {9164 returnExpression.deoptimizePath(path);9165 }9166 }9167 getLiteralValueAtPath(path, recursionTracker, origin) {9168 const [returnExpression] = this.getReturnExpression(recursionTracker);9169 if (returnExpression === UNKNOWN_EXPRESSION) {9170 return UnknownValue;9171 }9172 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {9173 this.deoptimizableDependentExpressions.push(origin);9174 return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin);9175 }, UnknownValue);9176 }9177 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {9178 const returnExpression = this.getReturnExpression(recursionTracker);9179 if (returnExpression[0] === UNKNOWN_EXPRESSION) {9180 return returnExpression;9181 }9182 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => {9183 this.deoptimizableDependentExpressions.push(origin);9184 const [expression, isPure] = returnExpression[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);9185 return [expression, isPure || returnExpression[1]];9186 }, UNKNOWN_RETURN_EXPRESSION);9187 }9188 hasEffectsOnInteractionAtPath(path, interaction, context) {9189 const { type } = interaction;9190 if (type === INTERACTION_CALLED) {9191 const { args, withNew } = interaction;9192 if ((withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, args, this)) {9193 return false;9194 }9195 }9196 else if ((type === INTERACTION_ASSIGNED9197 ? context.assigned9198 : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) {9199 return false;9200 }9201 const [returnExpression, isPure] = this.getReturnExpression();9202 return ((type === INTERACTION_ASSIGNED || !isPure) &&9203 returnExpression.hasEffectsOnInteractionAtPath(path, interaction, context));9204 }9205 }9206 9207 class CallExpression extends CallExpressionBase {9208 get optional() {9209 return isFlagSet(this.flags, 128 /* Flag.optional */);9210 }9211 set optional(value) {9212 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value);9213 }9214 bind() {9215 super.bind();9216 if (this.callee instanceof Identifier) {9217 const variable = this.scope.findVariable(this.callee.name);9218 if (variable.isNamespace) {9219 this.scope.context.log(LOGLEVEL_WARN, logCannotCallNamespace(this.callee.name), this.start);9220 }9221 if (this.callee.name === 'eval') {9222 this.scope.context.log(LOGLEVEL_WARN, logEval(this.scope.context.module.id), this.start);9223 }9224 }9225 this.interaction = {9226 args: [9227 this.callee instanceof MemberExpression && !this.callee.variable9228 ? this.callee.object9229 : null,9230 ...this.arguments9231 ],9232 type: INTERACTION_CALLED,9233 withNew: false9234 };9235 }9236 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) {9237 return getChainElementLiteralValueAtPath(this, this.callee, path, recursionTracker, origin);9238 }9239 hasEffects(context) {9240 if (!this.deoptimized)9241 this.applyDeoptimizations();9242 for (const argument of this.arguments) {9243 if (argument.hasEffects(context))9244 return true;9245 }9246 if (this.annotationPure) {9247 return false;9248 }9249 return (this.callee.hasEffects(context) ||9250 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));9251 }9252 hasEffectsAsChainElement(context) {9253 const calleeHasEffects = 'hasEffectsAsChainElement' in this.callee9254 ? this.callee.hasEffectsAsChainElement(context)9255 : this.callee.hasEffects(context);9256 if (calleeHasEffects === IS_SKIPPED_CHAIN)9257 return IS_SKIPPED_CHAIN;9258 if (this.optional &&9259 this.callee.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) {9260 return (!this.annotationPure && calleeHasEffects) || IS_SKIPPED_CHAIN;9261 }9262 // We only apply deoptimizations lazily once we know we are not skipping9263 if (!this.deoptimized)9264 this.applyDeoptimizations();9265 for (const argument of this.arguments) {9266 if (argument.hasEffects(context))9267 return true;9268 }9269 return (!this.annotationPure &&9270 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context));9271 }9272 include(context, includeChildrenRecursively) {9273 if (!this.deoptimized)9274 this.applyDeoptimizations();9275 if (includeChildrenRecursively) {9276 super.include(context, includeChildrenRecursively);9277 if (includeChildrenRecursively === INCLUDE_PARAMETERS &&9278 this.callee instanceof Identifier &&9279 this.callee.variable) {9280 this.callee.variable.markCalledFromTryStatement();9281 }9282 }9283 else {9284 this.included = true;9285 this.callee.include(context, false);9286 }9287 this.callee.includeCallArguments(context, this.arguments);9288 }9289 initialise() {9290 super.initialise();9291 if (this.annotations &&9292 this.scope.context.options.treeshake.annotations) {9293 this.annotationPure = this.annotations.some(comment => comment.type === 'pure');9294 }9295 }9296 render(code, options, { renderedSurroundingElement } = BLANK) {9297 this.callee.render(code, options, {9298 isCalleeOfRenderedParent: true,9299 renderedSurroundingElement9300 });9301 renderCallArguments(code, options, this);9302 }9303 applyDeoptimizations() {9304 this.deoptimized = true;9305 this.callee.deoptimizeArgumentsOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER);9306 this.scope.context.requestTreeshakingPass();9307 }9308 getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) {9309 if (this.returnExpression === null) {9310 this.returnExpression = UNKNOWN_RETURN_EXPRESSION;9311 return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this));9312 }9313 return this.returnExpression;9314 }9315 }9316 9317 class CatchClause extends NodeBase {9318 createScope(parentScope) {9319 this.scope = new ParameterScope(parentScope, true);9320 }9321 parseNode(esTreeNode) {9322 const { body, param, type } = esTreeNode;9323 this.type = type;9324 if (param) {9325 this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param);9326 this.param.declare('parameter', UNKNOWN_EXPRESSION);9327 }9328 this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body);9329 return super.parseNode(esTreeNode);9330 }9331 }9332 CatchClause.prototype.preventChildBlockScope = true;9333 9334 class ChainExpression extends NodeBase {9335 // deoptimizations are not relevant as we are not caching values9336 deoptimizeCache() { }9337 getLiteralValueAtPath(path, recursionTracker, origin) {9338 const literalValue = this.expression.getLiteralValueAtPathAsChainElement(path, recursionTracker, origin);9339 return literalValue === IS_SKIPPED_CHAIN ? undefined : literalValue;9340 }9341 hasEffects(context) {9342 return this.expression.hasEffectsAsChainElement(context) === true;9343 }9344 removeAnnotations(code) {9345 this.expression.removeAnnotations(code);9346 }9347 applyDeoptimizations() { }9348 }9349 9350 class ClassBodyScope extends ChildScope {9351 constructor(parent, classNode) {9352 const { context } = parent;9353 super(parent, context);9354 this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other')));9355 this.instanceScope = new ChildScope(this, context);9356 this.instanceScope.variables.set('this', new ThisVariable(context));9357 }9358 findLexicalBoundary() {9359 return this;9360 }9361 }9362 9363 class ClassBody extends NodeBase {9364 createScope(parentScope) {9365 this.scope = new ClassBodyScope(parentScope, this.parent);9366 }9367 include(context, includeChildrenRecursively) {9368 this.included = true;9369 this.scope.context.includeVariableInModule(this.scope.thisVariable);9370 for (const definition of this.body) {9371 definition.include(context, includeChildrenRecursively);9372 }9373 }9374 parseNode(esTreeNode) {9375 const body = (this.body = []);9376 for (const definition of esTreeNode.body) {9377 body.push(new (this.scope.context.getNodeConstructor(definition.type))(this, definition.static ? this.scope : this.scope.instanceScope).parseNode(definition));9378 }9379 return super.parseNode(esTreeNode);9380 }9381 applyDeoptimizations() { }9382 }9383 9384 function checkEffectForNodes(nodes, context) {9385 for (const node of nodes) {9386 if (node.hasEffects(context)) {9387 return true;9388 }9389 }9390 return false;9391 }9392 9393 class MethodBase extends NodeBase {9394 constructor() {9395 super(...arguments);9396 this.accessedValue = null;9397 }9398 get computed() {9399 return isFlagSet(this.flags, 1024 /* Flag.computed */);9400 }9401 set computed(value) {9402 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value);9403 }9404 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {9405 if (interaction.type === INTERACTION_ACCESSED && this.kind === 'get' && path.length === 0) {9406 return this.value.deoptimizeArgumentsOnInteractionAtPath({9407 args: interaction.args,9408 type: INTERACTION_CALLED,9409 withNew: false9410 }, EMPTY_PATH, recursionTracker);9411 }9412 if (interaction.type === INTERACTION_ASSIGNED && this.kind === 'set' && path.length === 0) {9413 return this.value.deoptimizeArgumentsOnInteractionAtPath({9414 args: interaction.args,9415 type: INTERACTION_CALLED,9416 withNew: false9417 }, EMPTY_PATH, recursionTracker);9418 }9419 this.getAccessedValue()[0].deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);9420 }9421 // As getter properties directly receive their values from fixed function9422 // expressions, there is no known situation where a getter is deoptimized.9423 deoptimizeCache() { }9424 deoptimizePath(path) {9425 this.getAccessedValue()[0].deoptimizePath(path);9426 }9427 getLiteralValueAtPath(path, recursionTracker, origin) {9428 return this.getAccessedValue()[0].getLiteralValueAtPath(path, recursionTracker, origin);9429 }9430 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {9431 return this.getAccessedValue()[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);9432 }9433 hasEffects(context) {9434 return this.key.hasEffects(context);9435 }9436 hasEffectsOnInteractionAtPath(path, interaction, context) {9437 if (this.kind === 'get' && interaction.type === INTERACTION_ACCESSED && path.length === 0) {9438 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {9439 args: interaction.args,9440 type: INTERACTION_CALLED,9441 withNew: false9442 }, context);9443 }9444 // setters are only called for empty paths9445 if (this.kind === 'set' && interaction.type === INTERACTION_ASSIGNED) {9446 return this.value.hasEffectsOnInteractionAtPath(EMPTY_PATH, {9447 args: interaction.args,9448 type: INTERACTION_CALLED,9449 withNew: false9450 }, context);9451 }9452 return this.getAccessedValue()[0].hasEffectsOnInteractionAtPath(path, interaction, context);9453 }9454 applyDeoptimizations() { }9455 getAccessedValue() {9456 if (this.accessedValue === null) {9457 if (this.kind === 'get') {9458 this.accessedValue = UNKNOWN_RETURN_EXPRESSION;9459 return (this.accessedValue = this.value.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, SHARED_RECURSION_TRACKER, this));9460 }9461 else {9462 return (this.accessedValue = [this.value, false]);9463 }9464 }9465 return this.accessedValue;9466 }9467 }9468 9469 class MethodDefinition extends MethodBase {9470 hasEffects(context) {9471 return super.hasEffects(context) || checkEffectForNodes(this.decorators, context);9472 }9473 applyDeoptimizations() { }9474 }9475 9476 class StaticBlock extends NodeBase {9477 createScope(parentScope) {9478 this.scope = new BlockScope(parentScope);9479 }9480 hasEffects(context) {9481 for (const node of this.body) {9482 if (node.hasEffects(context))9483 return true;9484 }9485 return false;9486 }9487 include(context, includeChildrenRecursively) {9488 this.included = true;9489 for (const node of this.body) {9490 if (includeChildrenRecursively || node.shouldBeIncluded(context))9491 node.include(context, includeChildrenRecursively);9492 }9493 }9494 render(code, options) {9495 if (this.body.length > 0) {9496 const bodyStartPos = findFirstOccurrenceOutsideComment(code.original.slice(this.start, this.end), '{') + 1;9497 renderStatementList(this.body, code, this.start + bodyStartPos, this.end - 1, options);9498 }9499 else {9500 super.render(code, options);9501 }9502 }9503 }9504 function isStaticBlock(statement) {9505 return statement.type === StaticBlock$1;9506 }9507 9508 class ObjectMember extends ExpressionEntity {9509 constructor(object, key) {9510 super();9511 this.object = object;9512 this.key = key;9513 }9514 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {9515 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.key, ...path], recursionTracker);9516 }9517 deoptimizePath(path) {9518 this.object.deoptimizePath([this.key, ...path]);9519 }9520 getLiteralValueAtPath(path, recursionTracker, origin) {9521 return this.object.getLiteralValueAtPath([this.key, ...path], recursionTracker, origin);9522 }9523 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {9524 return this.object.getReturnExpressionWhenCalledAtPath([this.key, ...path], interaction, recursionTracker, origin);9525 }9526 hasEffectsOnInteractionAtPath(path, interaction, context) {9527 return this.object.hasEffectsOnInteractionAtPath([this.key, ...path], interaction, context);9528 }9529 }9530 9531 class ClassNode extends NodeBase {9532 constructor() {9533 super(...arguments);9534 this.objectEntity = null;9535 }9536 createScope(parentScope) {9537 this.scope = new ChildScope(parentScope, parentScope.context);9538 }9539 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {9540 this.getObjectEntity().deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);9541 }9542 deoptimizeCache() {9543 this.getObjectEntity().deoptimizeAllProperties();9544 }9545 deoptimizePath(path) {9546 this.getObjectEntity().deoptimizePath(path);9547 }9548 getLiteralValueAtPath(path, recursionTracker, origin) {9549 return this.getObjectEntity().getLiteralValueAtPath(path, recursionTracker, origin);9550 }9551 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {9552 return this.getObjectEntity().getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);9553 }9554 hasEffects(context) {9555 if (!this.deoptimized)9556 this.applyDeoptimizations();9557 const initEffect = this.superClass?.hasEffects(context) || this.body.hasEffects(context);9558 this.id?.markDeclarationReached();9559 return initEffect || super.hasEffects(context) || checkEffectForNodes(this.decorators, context);9560 }9561 hasEffectsOnInteractionAtPath(path, interaction, context) {9562 return interaction.type === INTERACTION_CALLED && path.length === 09563 ? !interaction.withNew ||9564 (this.classConstructor === null9565 ? this.superClass?.hasEffectsOnInteractionAtPath(path, interaction, context)9566 : this.classConstructor.hasEffectsOnInteractionAtPath(path, interaction, context)) ||9567 false9568 : this.getObjectEntity().hasEffectsOnInteractionAtPath(path, interaction, context);9569 }9570 include(context, includeChildrenRecursively) {9571 if (!this.deoptimized)9572 this.applyDeoptimizations();9573 this.included = true;9574 this.superClass?.include(context, includeChildrenRecursively);9575 this.body.include(context, includeChildrenRecursively);9576 for (const decorator of this.decorators)9577 decorator.include(context, includeChildrenRecursively);9578 if (this.id) {9579 this.id.markDeclarationReached();9580 this.id.include();9581 }9582 }9583 initialise() {9584 super.initialise();9585 this.id?.declare('class', this);9586 for (const method of this.body.body) {9587 if (method instanceof MethodDefinition && method.kind === 'constructor') {9588 this.classConstructor = method;9589 return;9590 }9591 }9592 this.classConstructor = null;9593 }9594 applyDeoptimizations() {9595 this.deoptimized = true;9596 for (const definition of this.body.body) {9597 if (!isStaticBlock(definition) &&9598 !(definition.static ||9599 (definition instanceof MethodDefinition && definition.kind === 'constructor'))) {9600 // Calls to methods are not tracked, ensure that the return value is deoptimized9601 definition.deoptimizePath(UNKNOWN_PATH);9602 }9603 }9604 this.scope.context.requestTreeshakingPass();9605 }9606 getObjectEntity() {9607 if (this.objectEntity !== null) {9608 return this.objectEntity;9609 }9610 const staticProperties = [];9611 const dynamicMethods = [];9612 for (const definition of this.body.body) {9613 if (isStaticBlock(definition))9614 continue;9615 const properties = definition.static ? staticProperties : dynamicMethods;9616 const definitionKind = definition.kind;9617 // Note that class fields do not end up on the prototype9618 if (properties === dynamicMethods && !definitionKind)9619 continue;9620 const kind = definitionKind === 'set' || definitionKind === 'get' ? definitionKind : 'init';9621 let key;9622 if (definition.computed) {9623 const keyValue = definition.key.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);9624 if (typeof keyValue === 'symbol') {9625 properties.push({ key: UnknownKey, kind, property: definition });9626 continue;9627 }9628 else {9629 key = String(keyValue);9630 }9631 }9632 else {9633 key =9634 definition.key instanceof Identifier9635 ? definition.key.name9636 : String(definition.key.value);9637 }9638 properties.push({ key, kind, property: definition });9639 }9640 staticProperties.unshift({9641 key: 'prototype',9642 kind: 'init',9643 property: new ObjectEntity(dynamicMethods, this.superClass ? new ObjectMember(this.superClass, 'prototype') : OBJECT_PROTOTYPE)9644 });9645 return (this.objectEntity = new ObjectEntity(staticProperties, this.superClass || OBJECT_PROTOTYPE));9646 }9647 }9648 9649 class ClassDeclaration extends ClassNode {9650 initialise() {9651 super.initialise();9652 if (this.id !== null) {9653 this.id.variable.isId = true;9654 }9655 }9656 parseNode(esTreeNode) {9657 if (esTreeNode.id !== null) {9658 this.id = new Identifier(this, this.scope.parent).parseNode(esTreeNode.id);9659 }9660 return super.parseNode(esTreeNode);9661 }9662 render(code, options) {9663 const { exportNamesByVariable, format, snippets: { _, getPropertyAccess } } = options;9664 if (this.id) {9665 const { variable, name } = this.id;9666 if (format === 'system' && exportNamesByVariable.has(variable)) {9667 code.appendLeft(this.end, `${_}${getSystemExportStatement([variable], options)};`);9668 }9669 const renderedVariable = variable.getName(getPropertyAccess);9670 if (renderedVariable !== name) {9671 this.decorators.map(decorator => decorator.render(code, options));9672 this.superClass?.render(code, options);9673 this.body.render(code, {9674 ...options,9675 useOriginalName: (_variable) => _variable === variable9676 });9677 code.prependRight(this.start, `let ${renderedVariable}${_}=${_}`);9678 code.prependLeft(this.end, ';');9679 return;9680 }9681 }9682 super.render(code, options);9683 }9684 applyDeoptimizations() {9685 super.applyDeoptimizations();9686 const { id, scope } = this;9687 if (id) {9688 const { name, variable } = id;9689 for (const accessedVariable of scope.accessedOutsideVariables.values()) {9690 if (accessedVariable !== variable) {9691 accessedVariable.forbidName(name);9692 }9693 }9694 }9695 }9696 }9697 9698 class ClassExpression extends ClassNode {9699 render(code, options, { renderedSurroundingElement } = BLANK) {9700 super.render(code, options);9701 if (renderedSurroundingElement === ExpressionStatement$1) {9702 code.appendRight(this.start, '(');9703 code.prependLeft(this.end, ')');9704 }9705 }9706 }9707 9708 class MultiExpression extends ExpressionEntity {9709 constructor(expressions) {9710 super();9711 this.expressions = expressions;9712 }9713 deoptimizePath(path) {9714 for (const expression of this.expressions) {9715 expression.deoptimizePath(path);9716 }9717 }9718 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {9719 return [9720 new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])),9721 false9722 ];9723 }9724 hasEffectsOnInteractionAtPath(path, interaction, context) {9725 for (const expression of this.expressions) {9726 if (expression.hasEffectsOnInteractionAtPath(path, interaction, context))9727 return true;9728 }9729 return false;9730 }9731 }9732 9733 class ConditionalExpression extends NodeBase {9734 constructor() {9735 super(...arguments);9736 this.expressionsToBeDeoptimized = [];9737 this.usedBranch = null;9738 }9739 get isBranchResolutionAnalysed() {9740 return isFlagSet(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */);9741 }9742 set isBranchResolutionAnalysed(value) {9743 this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value);9744 }9745 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {9746 this.consequent.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);9747 this.alternate.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker);9748 }9749 deoptimizeCache() {9750 if (this.usedBranch !== null) {9751 const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent;9752 this.usedBranch = null;9753 unusedBranch.deoptimizePath(UNKNOWN_PATH);9754 const { expressionsToBeDeoptimized } = this;9755 this.expressionsToBeDeoptimized = EMPTY_ARRAY;9756 for (const expression of expressionsToBeDeoptimized) {9757 expression.deoptimizeCache();9758 }9759 }9760 }9761 deoptimizePath(path) {9762 const usedBranch = this.getUsedBranch();9763 if (usedBranch) {9764 usedBranch.deoptimizePath(path);9765 }9766 else {9767 this.consequent.deoptimizePath(path);9768 this.alternate.deoptimizePath(path);9769 }9770 }9771 getLiteralValueAtPath(path, recursionTracker, origin) {9772 const usedBranch = this.getUsedBranch();9773 if (!usedBranch)9774 return UnknownValue;9775 this.expressionsToBeDeoptimized.push(origin);9776 return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin);9777 }9778 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) {9779 const usedBranch = this.getUsedBranch();9780 if (!usedBranch)9781 return [9782 new MultiExpression([9783 this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0],9784 this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0]9785 ]),9786 false9787 ];9788 this.expressionsToBeDeoptimized.push(origin);9789 return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin);9790 }9791 hasEffects(context) {9792 if (this.test.hasEffects(context))9793 return true;9794 const usedBranch = this.getUsedBranch();9795 if (!usedBranch) {9796 return this.consequent.hasEffects(context) || this.alternate.hasEffects(context);9797 }9798 return usedBranch.hasEffects(context);9799 }9800 hasEffectsOnInteractionAtPath(path, interaction, context) {9801 const usedBranch = this.getUsedBranch();9802 if (!usedBranch) {9803 return (this.consequent.hasEffectsOnInteractionAtPath(path, interaction, context) ||9804 this.alternate.hasEffectsOnInteractionAtPath(path, interaction, context));9805 }9806 return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context);9807 }9808 include(context, includeChildrenRecursively) {9809 this.included = true;9810 const usedBranch = this.getUsedBranch();9811 if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) {9812 this.test.include(context, includeChildrenRecursively);9813 this.consequent.include(context, includeChildrenRecursively);9814 this.alternate.include(context, includeChildrenRecursively);9815 }9816 else {9817 usedBranch.include(context, includeChildrenRecursively);9818 }9819 }9820 includeCallArguments(context, parameters) {9821 const usedBranch = this.getUsedBranch();9822 if (usedBranch) {9823 usedBranch.includeCallArguments(context, parameters);9824 }9825 else {9826 this.consequent.includeCallArguments(context, parameters);9827 this.alternate.includeCallArguments(context, parameters);9828 }9829 }9830 removeAnnotations(code) {9831 this.test.removeAnnotations(code);9832 }9833 render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = BLANK) {9834 const usedBranch = this.getUsedBranch();9835 if (this.test.included) {9836 this.test.render(code, options, { renderedSurroundingElement });9837 this.consequent.render(code, options);9838 this.alternate.render(code, options);9839 }9840 else {9841 const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end);9842 const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included9843 ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end)9844 : colonPos) + 1);9845 if (preventASI) {9846 removeLineBreaks(code, inclusionStart, usedBranch.start);9847 }9848 code.remove(this.start, inclusionStart);9849 if (this.consequent.included) {9850 code.remove(colonPos, this.end);9851 }9852 this.test.removeAnnotations(code);9853 usedBranch.render(code, options, {9854 isCalleeOfRenderedParent,9855 preventASI: true,9856 renderedParentType: renderedParentType || this.parent.type,9857 renderedSurroundingElement: renderedSurroundingElement || this.parent.type9858 });9859 }9860 }9861 getUsedBranch() {9862 if (this.isBranchResolutionAnalysed) {9863 return this.usedBranch;9864 }9865 this.isBranchResolutionAnalysed = true;9866 const testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this);9867 return typeof testValue === 'symbol'9868 ? null9869 : (this.usedBranch = testValue ? this.consequent : this.alternate);9870 }9871 }9872 9873 class ContinueStatement extends NodeBase {9874 hasEffects(context) {9875 if (this.label) {9876 if (!context.ignore.labels.has(this.label.name))9877 return true;9878 context.includedLabels.add(this.label.name);9879 }9880 else {9881 if (!context.ignore.continues)9882 return true;9883 context.hasContinue = true;9884 }9885 context.brokenFlow = true;9886 return false;9887 }9888 include(context) {9889 this.included = true;9890 if (this.label) {9891 this.label.include();9892 context.includedLabels.add(this.label.name);9893 }9894 else {9895 context.hasContinue = true;9896 }9897 context.brokenFlow = true;9898 }9899 }9900 9901 class DebuggerStatement extends NodeBase {9902 hasEffects() {9903 return true;9904 }9905 }9906 9907 class Decorator extends NodeBase {9908 hasEffects(context) {9909 return (this.expression.hasEffects(context) ||9910 this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context));9911 }9912 }9913 9914 function hasLoopBodyEffects(context, body) {9915 const { brokenFlow, hasBreak, hasContinue, ignore } = context;9916 const { breaks, continues } = ignore;9917 ignore.breaks = true;9918 ignore.continues = true;9919 context.hasBreak = false;9920 context.hasContinue = false;9921 if (body.hasEffects(context))9922 return true;9923 ignore.breaks = breaks;9924 ignore.continues = continues;9925 context.hasBreak = hasBreak;9926 context.hasContinue = hasContinue;9927 context.brokenFlow = brokenFlow;9928 return false;9929 }9930 function includeLoopBody(context, body, includeChildrenRecursively) {9931 const { brokenFlow, hasBreak, hasContinue } = context;9932 context.hasBreak = false;9933 context.hasContinue = false;9934 body.include(context, includeChildrenRecursively, { asSingleStatement: true });9935 context.hasBreak = hasBreak;9936 context.hasContinue = hasContinue;9937 context.brokenFlow = brokenFlow;9938 }9939 9940 class DoWhileStatement extends NodeBase {9941 hasEffects(context) {9942 if (this.test.hasEffects(context))9943 return true;9944 return hasLoopBodyEffects(context, this.body);9945 }9946 include(context, includeChildrenRecursively) {9947 this.included = true;9948 this.test.include(context, includeChildrenRecursively);9949 includeLoopBody(context, this.body, includeChildrenRecursively);9950 }9951 }9952 9953 class EmptyStatement extends NodeBase {9954 hasEffects() {9955 return false;9956 }9957 }9958 9959 class ExportAllDeclaration extends NodeBase {9960 hasEffects() {9961 return false;9962 }9963 initialise() {9964 super.initialise();9965 this.scope.context.addExport(this);9966 }9967 render(code, _options, nodeRenderOptions) {9968 code.remove(nodeRenderOptions.start, nodeRenderOptions.end);9969 }9970 applyDeoptimizations() { }9971 }9972 ExportAllDeclaration.prototype.needsBoundaries = true;9973 9974 6453 class FunctionDeclaration extends FunctionNode { 9975 6454 initialise() { … … 10087 6566 ExportDefaultDeclaration.prototype.needsBoundaries = true; 10088 6567 10089 class ExportNamedDeclaration extends NodeBase { 10090 bind() { 10091 // Do not bind specifiers 10092 this.declaration?.bind(); 10093 } 10094 hasEffects(context) { 10095 return !!this.declaration?.hasEffects(context); 10096 } 10097 initialise() { 10098 super.initialise(); 10099 this.scope.context.addExport(this); 10100 } 10101 removeAnnotations(code) { 10102 this.declaration?.removeAnnotations(code); 10103 } 10104 render(code, options, nodeRenderOptions) { 10105 const { start, end } = nodeRenderOptions; 10106 if (this.declaration === null) { 10107 code.remove(start, end); 10108 } 10109 else { 10110 code.remove(this.start, this.declaration.start); 10111 this.declaration.render(code, options, { end, start }); 10112 } 10113 } 10114 applyDeoptimizations() { } 10115 } 10116 ExportNamedDeclaration.prototype.needsBoundaries = true; 10117 10118 class ExportSpecifier extends NodeBase { 10119 applyDeoptimizations() { } 10120 } 10121 10122 class ForInStatement extends NodeBase { 10123 createScope(parentScope) { 10124 this.scope = new BlockScope(parentScope); 10125 } 10126 hasEffects(context) { 10127 const { body, deoptimized, left, right } = this; 10128 if (!deoptimized) 10129 this.applyDeoptimizations(); 10130 if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context)) 10131 return true; 10132 return hasLoopBodyEffects(context, body); 10133 } 10134 include(context, includeChildrenRecursively) { 10135 const { body, deoptimized, left, right } = this; 10136 if (!deoptimized) 10137 this.applyDeoptimizations(); 10138 this.included = true; 10139 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 10140 right.include(context, includeChildrenRecursively); 10141 includeLoopBody(context, body, includeChildrenRecursively); 10142 } 10143 initialise() { 10144 super.initialise(); 10145 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 10146 } 10147 render(code, options) { 10148 this.left.render(code, options, NO_SEMICOLON); 10149 this.right.render(code, options, NO_SEMICOLON); 10150 // handle no space between "in" and the right side 10151 if (code.original.charCodeAt(this.right.start - 1) === 110 /* n */) { 10152 code.prependLeft(this.right.start, ' '); 10153 } 10154 this.body.render(code, options); 10155 } 10156 applyDeoptimizations() { 10157 this.deoptimized = true; 10158 this.left.deoptimizePath(EMPTY_PATH); 10159 this.scope.context.requestTreeshakingPass(); 10160 } 10161 } 10162 10163 class ForOfStatement extends NodeBase { 10164 get await() { 10165 return isFlagSet(this.flags, 131072 /* Flag.await */); 10166 } 10167 set await(value) { 10168 this.flags = setFlag(this.flags, 131072 /* Flag.await */, value); 10169 } 10170 createScope(parentScope) { 10171 this.scope = new BlockScope(parentScope); 10172 } 10173 hasEffects() { 10174 if (!this.deoptimized) 10175 this.applyDeoptimizations(); 10176 // Placeholder until proper Symbol.Iterator support 10177 return true; 10178 } 10179 include(context, includeChildrenRecursively) { 10180 const { body, deoptimized, left, right } = this; 10181 if (!deoptimized) 10182 this.applyDeoptimizations(); 10183 this.included = true; 10184 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 10185 right.include(context, includeChildrenRecursively); 10186 includeLoopBody(context, body, includeChildrenRecursively); 10187 } 10188 initialise() { 10189 super.initialise(); 10190 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 10191 } 10192 render(code, options) { 10193 this.left.render(code, options, NO_SEMICOLON); 10194 this.right.render(code, options, NO_SEMICOLON); 10195 // handle no space between "of" and the right side 10196 if (code.original.charCodeAt(this.right.start - 1) === 102 /* f */) { 10197 code.prependLeft(this.right.start, ' '); 10198 } 10199 this.body.render(code, options); 10200 } 10201 applyDeoptimizations() { 10202 this.deoptimized = true; 10203 this.left.deoptimizePath(EMPTY_PATH); 10204 this.right.deoptimizePath(UNKNOWN_PATH); 10205 this.scope.context.requestTreeshakingPass(); 10206 } 10207 } 10208 10209 class ForStatement extends NodeBase { 10210 createScope(parentScope) { 10211 this.scope = new BlockScope(parentScope); 10212 } 10213 hasEffects(context) { 10214 if (this.init?.hasEffects(context) || 10215 this.test?.hasEffects(context) || 10216 this.update?.hasEffects(context)) { 10217 return true; 10218 } 10219 return hasLoopBodyEffects(context, this.body); 10220 } 10221 include(context, includeChildrenRecursively) { 10222 this.included = true; 10223 this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true }); 10224 this.test?.include(context, includeChildrenRecursively); 10225 this.update?.include(context, includeChildrenRecursively); 10226 includeLoopBody(context, this.body, includeChildrenRecursively); 10227 } 10228 render(code, options) { 10229 this.init?.render(code, options, NO_SEMICOLON); 10230 this.test?.render(code, options, NO_SEMICOLON); 10231 this.update?.render(code, options, NO_SEMICOLON); 10232 this.body.render(code, options); 10233 } 10234 } 10235 10236 class FunctionExpression extends FunctionNode { 10237 createScope(parentScope) { 10238 super.createScope((this.idScope = new ChildScope(parentScope, parentScope.context))); 10239 } 10240 parseNode(esTreeNode) { 10241 if (esTreeNode.id !== null) { 10242 this.id = new Identifier(this, this.idScope).parseNode(esTreeNode.id); 10243 } 10244 return super.parseNode(esTreeNode); 10245 } 10246 onlyFunctionCallUsed() { 10247 const isIIFE = this.parent.type === CallExpression$1 && 10248 this.parent.callee === this && 10249 (this.id === null || this.id.variable.getOnlyFunctionCallUsed()); 10250 return isIIFE || super.onlyFunctionCallUsed(); 10251 } 10252 render(code, options, { renderedSurroundingElement } = BLANK) { 10253 super.render(code, options); 10254 if (renderedSurroundingElement === ExpressionStatement$1) { 10255 code.appendRight(this.start, '('); 10256 code.prependLeft(this.end, ')'); 10257 } 10258 } 10259 } 10260 10261 class TrackingScope extends BlockScope { 10262 constructor() { 10263 super(...arguments); 10264 this.hoistedDeclarations = []; 10265 } 10266 addDeclaration(identifier, context, init, kind) { 10267 this.hoistedDeclarations.push(identifier); 10268 return super.addDeclaration(identifier, context, init, kind); 10269 } 10270 } 10271 10272 const unset = Symbol('unset'); 10273 class IfStatement extends NodeBase { 10274 constructor() { 10275 super(...arguments); 10276 this.testValue = unset; 10277 } 10278 deoptimizeCache() { 10279 this.testValue = UnknownValue; 10280 } 10281 hasEffects(context) { 10282 if (this.test.hasEffects(context)) { 10283 return true; 10284 } 10285 const testValue = this.getTestValue(); 10286 if (typeof testValue === 'symbol') { 10287 const { brokenFlow } = context; 10288 if (this.consequent.hasEffects(context)) 10289 return true; 10290 const consequentBrokenFlow = context.brokenFlow; 10291 context.brokenFlow = brokenFlow; 10292 if (this.alternate === null) 10293 return false; 10294 if (this.alternate.hasEffects(context)) 10295 return true; 10296 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 10297 return false; 10298 } 10299 return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context); 10300 } 10301 include(context, includeChildrenRecursively) { 10302 this.included = true; 10303 if (includeChildrenRecursively) { 10304 this.includeRecursively(includeChildrenRecursively, context); 10305 } 10306 else { 10307 const testValue = this.getTestValue(); 10308 if (typeof testValue === 'symbol') { 10309 this.includeUnknownTest(context); 10310 } 10311 else { 10312 this.includeKnownTest(context, testValue); 10313 } 10314 } 10315 } 10316 parseNode(esTreeNode) { 10317 this.consequent = new (this.scope.context.getNodeConstructor(esTreeNode.consequent.type))(this, (this.consequentScope = new TrackingScope(this.scope))).parseNode(esTreeNode.consequent); 10318 if (esTreeNode.alternate) { 10319 this.alternate = new (this.scope.context.getNodeConstructor(esTreeNode.alternate.type))(this, (this.alternateScope = new TrackingScope(this.scope))).parseNode(esTreeNode.alternate); 10320 } 10321 return super.parseNode(esTreeNode); 10322 } 10323 render(code, options) { 10324 const { snippets: { getPropertyAccess } } = options; 10325 // Note that unknown test values are always included 10326 const testValue = this.getTestValue(); 10327 const hoistedDeclarations = []; 10328 const includesIfElse = this.test.included; 10329 const noTreeshake = !this.scope.context.options.treeshake; 10330 if (includesIfElse) { 10331 this.test.render(code, options); 10332 } 10333 else { 10334 code.remove(this.start, this.consequent.start); 10335 } 10336 if (this.consequent.included && (noTreeshake || typeof testValue === 'symbol' || testValue)) { 10337 this.consequent.render(code, options); 10338 } 10339 else { 10340 code.overwrite(this.consequent.start, this.consequent.end, includesIfElse ? ';' : ''); 10341 hoistedDeclarations.push(...this.consequentScope.hoistedDeclarations); 10342 } 10343 if (this.alternate) { 10344 if (this.alternate.included && (noTreeshake || typeof testValue === 'symbol' || !testValue)) { 10345 if (includesIfElse) { 10346 if (code.original.charCodeAt(this.alternate.start - 1) === 101) { 10347 code.prependLeft(this.alternate.start, ' '); 10348 } 10349 } 10350 else { 10351 code.remove(this.consequent.end, this.alternate.start); 10352 } 10353 this.alternate.render(code, options); 10354 } 10355 else { 10356 if (includesIfElse && this.shouldKeepAlternateBranch()) { 10357 code.overwrite(this.alternate.start, this.end, ';'); 10358 } 10359 else { 10360 code.remove(this.consequent.end, this.end); 10361 } 10362 hoistedDeclarations.push(...this.alternateScope.hoistedDeclarations); 10363 } 10364 } 10365 this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess); 10366 } 10367 applyDeoptimizations() { } 10368 getTestValue() { 10369 if (this.testValue === unset) { 10370 return (this.testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)); 10371 } 10372 return this.testValue; 10373 } 10374 includeKnownTest(context, testValue) { 10375 if (this.test.shouldBeIncluded(context)) { 10376 this.test.include(context, false); 10377 } 10378 if (testValue && this.consequent.shouldBeIncluded(context)) { 10379 this.consequent.include(context, false, { asSingleStatement: true }); 10380 } 10381 if (!testValue && this.alternate?.shouldBeIncluded(context)) { 10382 this.alternate.include(context, false, { asSingleStatement: true }); 10383 } 10384 } 10385 includeRecursively(includeChildrenRecursively, context) { 10386 this.test.include(context, includeChildrenRecursively); 10387 this.consequent.include(context, includeChildrenRecursively); 10388 this.alternate?.include(context, includeChildrenRecursively); 10389 } 10390 includeUnknownTest(context) { 10391 this.test.include(context, false); 10392 const { brokenFlow } = context; 10393 let consequentBrokenFlow = false; 10394 if (this.consequent.shouldBeIncluded(context)) { 10395 this.consequent.include(context, false, { asSingleStatement: true }); 10396 consequentBrokenFlow = context.brokenFlow; 10397 context.brokenFlow = brokenFlow; 10398 } 10399 if (this.alternate?.shouldBeIncluded(context)) { 10400 this.alternate.include(context, false, { asSingleStatement: true }); 10401 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 10402 } 10403 } 10404 renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess) { 10405 const hoistedVariables = [ 10406 ...new Set(hoistedDeclarations.map(identifier => { 10407 const variable = identifier.variable; 10408 return variable.included ? variable.getName(getPropertyAccess) : ''; 10409 })) 10410 ] 10411 .filter(Boolean) 10412 .join(', '); 10413 if (hoistedVariables) { 10414 const parentType = this.parent.type; 10415 const needsBraces = parentType !== Program$1 && parentType !== BlockStatement$1; 10416 code.prependRight(this.start, `${needsBraces ? '{ ' : ''}var ${hoistedVariables}; `); 10417 if (needsBraces) { 10418 code.appendLeft(this.end, ` }`); 10419 } 10420 } 10421 } 10422 shouldKeepAlternateBranch() { 10423 let currentParent = this.parent; 10424 do { 10425 if (currentParent instanceof IfStatement && currentParent.alternate) { 10426 return true; 10427 } 10428 if (currentParent instanceof BlockStatement) { 10429 return false; 10430 } 10431 currentParent = currentParent.parent; 10432 } while (currentParent); 10433 return false; 10434 } 10435 } 10436 10437 class ImportAttribute extends NodeBase { 10438 } 10439 10440 class ImportDeclaration extends NodeBase { 10441 // Do not bind specifiers or attributes 10442 bind() { } 10443 hasEffects() { 10444 return false; 10445 } 10446 initialise() { 10447 super.initialise(); 10448 this.scope.context.addImport(this); 10449 } 10450 render(code, _options, nodeRenderOptions) { 10451 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 10452 } 10453 applyDeoptimizations() { } 10454 } 10455 ImportDeclaration.prototype.needsBoundaries = true; 10456 10457 class ImportDefaultSpecifier extends NodeBase { 10458 applyDeoptimizations() { } 6568 const needsEscapeRegEx = /[\n\r'\\\u2028\u2029]/; 6569 const quoteNewlineRegEx = /([\n\r'\u2028\u2029])/g; 6570 const backSlashRegEx = /\\/g; 6571 function escapeId(id) { 6572 if (!needsEscapeRegEx.test(id)) 6573 return id; 6574 return id.replace(backSlashRegEx, '\\\\').replace(quoteNewlineRegEx, '\\$1'); 10459 6575 } 10460 6576 … … 10497 6613 const HELPER_GENERATORS = { 10498 6614 [DOCUMENT_CURRENT_SCRIPT](_t, { _, n }) { 10499 return `var ${_}${DOCUMENT_CURRENT_SCRIPT}${_}=${_}typeof${_}document${_}!==${_}'undefined'${_}?${_}document.currentScript${_}:${_}null;${n}`;6615 return `var ${DOCUMENT_CURRENT_SCRIPT}${_}=${_}typeof document${_}!==${_}'undefined'${_}?${_}document.currentScript${_}:${_}null;${n}`; 10500 6616 }, 10501 6617 [INTEROP_DEFAULT_COMPAT_VARIABLE](_t, snippets, liveBindings) { … … 10666 6782 } 10667 6783 6784 class Literal extends NodeBase { 6785 deoptimizeArgumentsOnInteractionAtPath() { } 6786 getLiteralValueAtPath(path) { 6787 if (path.length > 0 || 6788 // unknown literals can also be null but do not start with an "n" 6789 (this.value === null && this.scope.context.code.charCodeAt(this.start) !== 110) || 6790 typeof this.value === 'bigint' || 6791 // to support shims for regular expressions 6792 this.scope.context.code.charCodeAt(this.start) === 47) { 6793 return UnknownValue; 6794 } 6795 return this.value; 6796 } 6797 getReturnExpressionWhenCalledAtPath(path) { 6798 if (path.length !== 1) 6799 return UNKNOWN_RETURN_EXPRESSION; 6800 return getMemberReturnExpressionWhenCalled(this.members, path[0]); 6801 } 6802 hasEffectsOnInteractionAtPath(path, interaction, context) { 6803 switch (interaction.type) { 6804 case INTERACTION_ACCESSED: { 6805 return path.length > (this.value === null ? 0 : 1); 6806 } 6807 case INTERACTION_ASSIGNED: { 6808 return true; 6809 } 6810 case INTERACTION_CALLED: { 6811 if (this.included && 6812 this.value instanceof RegExp && 6813 (this.value.global || this.value.sticky)) { 6814 return true; 6815 } 6816 return (path.length !== 1 || 6817 hasMemberEffectWhenCalled(this.members, path[0], interaction, context)); 6818 } 6819 } 6820 } 6821 initialise() { 6822 super.initialise(); 6823 this.members = getLiteralMembersForValue(this.value); 6824 } 6825 parseNode(esTreeNode) { 6826 this.value = esTreeNode.value; 6827 this.regex = esTreeNode.regex; 6828 return super.parseNode(esTreeNode); 6829 } 6830 render(code) { 6831 if (typeof this.value === 'string') { 6832 code.indentExclusionRanges.push([this.start + 1, this.end - 1]); 6833 } 6834 } 6835 } 6836 6837 function getChainElementLiteralValueAtPath(element, object, path, recursionTracker, origin) { 6838 if ('getLiteralValueAtPathAsChainElement' in object) { 6839 const calleeValue = object.getLiteralValueAtPathAsChainElement(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin); 6840 if (calleeValue === IS_SKIPPED_CHAIN || (element.optional && calleeValue == null)) { 6841 return IS_SKIPPED_CHAIN; 6842 } 6843 } 6844 else if (element.optional && 6845 object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, origin) == null) { 6846 return IS_SKIPPED_CHAIN; 6847 } 6848 return element.getLiteralValueAtPath(path, recursionTracker, origin); 6849 } 6850 6851 // To avoid infinite recursions 6852 const MAX_PATH_DEPTH = 7; 6853 function getResolvablePropertyKey(memberExpression) { 6854 return memberExpression.computed 6855 ? getResolvableComputedPropertyKey(memberExpression.property) 6856 : memberExpression.property.name; 6857 } 6858 function getResolvableComputedPropertyKey(propertyKey) { 6859 if (propertyKey instanceof Literal) { 6860 return String(propertyKey.value); 6861 } 6862 return null; 6863 } 6864 function getPathIfNotComputed(memberExpression) { 6865 const nextPathKey = memberExpression.propertyKey; 6866 const object = memberExpression.object; 6867 if (typeof nextPathKey === 'string') { 6868 if (object instanceof Identifier) { 6869 return [ 6870 { key: object.name, pos: object.start }, 6871 { key: nextPathKey, pos: memberExpression.property.start } 6872 ]; 6873 } 6874 if (object instanceof MemberExpression) { 6875 const parentPath = getPathIfNotComputed(object); 6876 return (parentPath && [...parentPath, { key: nextPathKey, pos: memberExpression.property.start }]); 6877 } 6878 } 6879 return null; 6880 } 6881 function getStringFromPath(path) { 6882 let pathString = path[0].key; 6883 for (let index = 1; index < path.length; index++) { 6884 pathString += '.' + path[index].key; 6885 } 6886 return pathString; 6887 } 6888 class MemberExpression extends NodeBase { 6889 constructor() { 6890 super(...arguments); 6891 this.variable = null; 6892 this.expressionsToBeDeoptimized = []; 6893 } 6894 get computed() { 6895 return isFlagSet(this.flags, 1024 /* Flag.computed */); 6896 } 6897 set computed(value) { 6898 this.flags = setFlag(this.flags, 1024 /* Flag.computed */, value); 6899 } 6900 get optional() { 6901 return isFlagSet(this.flags, 128 /* Flag.optional */); 6902 } 6903 set optional(value) { 6904 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value); 6905 } 6906 get assignmentDeoptimized() { 6907 return isFlagSet(this.flags, 16 /* Flag.assignmentDeoptimized */); 6908 } 6909 set assignmentDeoptimized(value) { 6910 this.flags = setFlag(this.flags, 16 /* Flag.assignmentDeoptimized */, value); 6911 } 6912 get bound() { 6913 return isFlagSet(this.flags, 32 /* Flag.bound */); 6914 } 6915 set bound(value) { 6916 this.flags = setFlag(this.flags, 32 /* Flag.bound */, value); 6917 } 6918 get isUndefined() { 6919 return isFlagSet(this.flags, 64 /* Flag.isUndefined */); 6920 } 6921 set isUndefined(value) { 6922 this.flags = setFlag(this.flags, 64 /* Flag.isUndefined */, value); 6923 } 6924 bind() { 6925 this.bound = true; 6926 const path = getPathIfNotComputed(this); 6927 const baseVariable = path && this.scope.findVariable(path[0].key); 6928 if (baseVariable?.isNamespace) { 6929 const resolvedVariable = resolveNamespaceVariables(baseVariable, path.slice(1), this.scope.context); 6930 if (!resolvedVariable) { 6931 super.bind(); 6932 } 6933 else if (resolvedVariable === 'undefined') { 6934 this.isUndefined = true; 6935 } 6936 else { 6937 this.variable = resolvedVariable; 6938 this.scope.addNamespaceMemberAccess(getStringFromPath(path), resolvedVariable); 6939 } 6940 } 6941 else { 6942 super.bind(); 6943 } 6944 } 6945 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 6946 if (this.variable) { 6947 this.variable.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 6948 } 6949 else if (!this.isUndefined) { 6950 if (path.length < MAX_PATH_DEPTH) { 6951 this.object.deoptimizeArgumentsOnInteractionAtPath(interaction, [this.getPropertyKey(), ...path], recursionTracker); 6952 } 6953 else { 6954 deoptimizeInteraction(interaction); 6955 } 6956 } 6957 } 6958 deoptimizeCache() { 6959 const { expressionsToBeDeoptimized, object } = this; 6960 this.expressionsToBeDeoptimized = EMPTY_ARRAY; 6961 this.propertyKey = UnknownKey; 6962 object.deoptimizePath(UNKNOWN_PATH); 6963 for (const expression of expressionsToBeDeoptimized) { 6964 expression.deoptimizeCache(); 6965 } 6966 } 6967 deoptimizePath(path) { 6968 if (path.length === 0) 6969 this.disallowNamespaceReassignment(); 6970 if (this.variable) { 6971 this.variable.deoptimizePath(path); 6972 } 6973 else if (!this.isUndefined && path.length < MAX_PATH_DEPTH) { 6974 const propertyKey = this.getPropertyKey(); 6975 this.object.deoptimizePath([ 6976 propertyKey === UnknownKey ? UnknownNonAccessorKey : propertyKey, 6977 ...path 6978 ]); 6979 } 6980 } 6981 getLiteralValueAtPath(path, recursionTracker, origin) { 6982 if (this.variable) { 6983 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin); 6984 } 6985 if (this.isUndefined) { 6986 return undefined; 6987 } 6988 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) { 6989 this.expressionsToBeDeoptimized.push(origin); 6990 return this.object.getLiteralValueAtPath([this.getPropertyKey(), ...path], recursionTracker, origin); 6991 } 6992 return UnknownValue; 6993 } 6994 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) { 6995 if (this.variable) { 6996 return this.variable.getLiteralValueAtPath(path, recursionTracker, origin); 6997 } 6998 if (this.isUndefined) { 6999 return undefined; 7000 } 7001 return getChainElementLiteralValueAtPath(this, this.object, path, recursionTracker, origin); 7002 } 7003 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 7004 if (this.variable) { 7005 return this.variable.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 7006 } 7007 if (this.isUndefined) { 7008 return [UNDEFINED_EXPRESSION, false]; 7009 } 7010 if (this.propertyKey !== UnknownKey && path.length < MAX_PATH_DEPTH) { 7011 this.expressionsToBeDeoptimized.push(origin); 7012 return this.object.getReturnExpressionWhenCalledAtPath([this.getPropertyKey(), ...path], interaction, recursionTracker, origin); 7013 } 7014 return UNKNOWN_RETURN_EXPRESSION; 7015 } 7016 hasEffects(context) { 7017 if (!this.deoptimized) 7018 this.applyDeoptimizations(); 7019 return (this.property.hasEffects(context) || 7020 this.object.hasEffects(context) || 7021 this.hasAccessEffect(context)); 7022 } 7023 hasEffectsAsChainElement(context) { 7024 if (this.variable || this.isUndefined) 7025 return this.hasEffects(context); 7026 const objectHasEffects = 'hasEffectsAsChainElement' in this.object 7027 ? this.object.hasEffectsAsChainElement(context) 7028 : this.object.hasEffects(context); 7029 if (objectHasEffects === IS_SKIPPED_CHAIN) 7030 return IS_SKIPPED_CHAIN; 7031 if (this.optional && 7032 this.object.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) { 7033 return objectHasEffects || IS_SKIPPED_CHAIN; 7034 } 7035 // We only apply deoptimizations lazily once we know we are not skipping 7036 if (!this.deoptimized) 7037 this.applyDeoptimizations(); 7038 return objectHasEffects || this.property.hasEffects(context) || this.hasAccessEffect(context); 7039 } 7040 hasEffectsAsAssignmentTarget(context, checkAccess) { 7041 if (checkAccess && !this.deoptimized) 7042 this.applyDeoptimizations(); 7043 if (!this.assignmentDeoptimized) 7044 this.applyAssignmentDeoptimization(); 7045 return (this.property.hasEffects(context) || 7046 this.object.hasEffects(context) || 7047 (checkAccess && this.hasAccessEffect(context)) || 7048 this.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.assignmentInteraction, context)); 7049 } 7050 hasEffectsOnInteractionAtPath(path, interaction, context) { 7051 if (this.variable) { 7052 return this.variable.hasEffectsOnInteractionAtPath(path, interaction, context); 7053 } 7054 if (this.isUndefined) { 7055 return true; 7056 } 7057 if (path.length < MAX_PATH_DEPTH) { 7058 return this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey(), ...path], interaction, context); 7059 } 7060 return true; 7061 } 7062 include(context, includeChildrenRecursively) { 7063 if (!this.deoptimized) 7064 this.applyDeoptimizations(); 7065 this.includeProperties(context, includeChildrenRecursively); 7066 } 7067 includeAsAssignmentTarget(context, includeChildrenRecursively, deoptimizeAccess) { 7068 if (!this.assignmentDeoptimized) 7069 this.applyAssignmentDeoptimization(); 7070 if (deoptimizeAccess) { 7071 this.include(context, includeChildrenRecursively); 7072 } 7073 else { 7074 this.includeProperties(context, includeChildrenRecursively); 7075 } 7076 } 7077 includeCallArguments(context, parameters) { 7078 if (this.variable) { 7079 this.variable.includeCallArguments(context, parameters); 7080 } 7081 else { 7082 super.includeCallArguments(context, parameters); 7083 } 7084 } 7085 initialise() { 7086 super.initialise(); 7087 this.propertyKey = getResolvablePropertyKey(this); 7088 this.accessInteraction = { args: [this.object], type: INTERACTION_ACCESSED }; 7089 } 7090 render(code, options, { renderedParentType, isCalleeOfRenderedParent, renderedSurroundingElement } = BLANK) { 7091 if (this.variable || this.isUndefined) { 7092 const { snippets: { getPropertyAccess } } = options; 7093 let replacement = this.variable ? this.variable.getName(getPropertyAccess) : 'undefined'; 7094 if (renderedParentType && isCalleeOfRenderedParent) 7095 replacement = '0, ' + replacement; 7096 code.overwrite(this.start, this.end, replacement, { 7097 contentOnly: true, 7098 storeName: true 7099 }); 7100 } 7101 else { 7102 if (renderedParentType && isCalleeOfRenderedParent) { 7103 code.appendRight(this.start, '0, '); 7104 } 7105 this.object.render(code, options, { renderedSurroundingElement }); 7106 this.property.render(code, options); 7107 } 7108 } 7109 setAssignedValue(value) { 7110 this.assignmentInteraction = { 7111 args: [this.object, value], 7112 type: INTERACTION_ASSIGNED 7113 }; 7114 } 7115 applyDeoptimizations() { 7116 this.deoptimized = true; 7117 const { propertyReadSideEffects } = this.scope.context.options 7118 .treeshake; 7119 if ( 7120 // Namespaces are not bound and should not be deoptimized 7121 this.bound && 7122 propertyReadSideEffects && 7123 !(this.variable || this.isUndefined)) { 7124 const propertyKey = this.getPropertyKey(); 7125 this.object.deoptimizeArgumentsOnInteractionAtPath(this.accessInteraction, [propertyKey], SHARED_RECURSION_TRACKER); 7126 this.scope.context.requestTreeshakingPass(); 7127 } 7128 if (this.variable) { 7129 this.variable.addUsedPlace(this); 7130 this.scope.context.requestTreeshakingPass(); 7131 } 7132 } 7133 applyAssignmentDeoptimization() { 7134 this.assignmentDeoptimized = true; 7135 const { propertyReadSideEffects } = this.scope.context.options 7136 .treeshake; 7137 if ( 7138 // Namespaces are not bound and should not be deoptimized 7139 this.bound && 7140 propertyReadSideEffects && 7141 !(this.variable || this.isUndefined)) { 7142 this.object.deoptimizeArgumentsOnInteractionAtPath(this.assignmentInteraction, [this.getPropertyKey()], SHARED_RECURSION_TRACKER); 7143 this.scope.context.requestTreeshakingPass(); 7144 } 7145 } 7146 disallowNamespaceReassignment() { 7147 if (this.object instanceof Identifier) { 7148 const variable = this.scope.findVariable(this.object.name); 7149 if (variable.isNamespace) { 7150 if (this.variable) { 7151 this.scope.context.includeVariableInModule(this.variable); 7152 } 7153 this.scope.context.log(LOGLEVEL_WARN, logIllegalImportReassignment(this.object.name, this.scope.context.module.id), this.start); 7154 } 7155 } 7156 } 7157 getPropertyKey() { 7158 if (this.propertyKey === null) { 7159 this.propertyKey = UnknownKey; 7160 const value = this.property.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 7161 return (this.propertyKey = 7162 value === SymbolToStringTag 7163 ? value 7164 : typeof value === 'symbol' 7165 ? UnknownKey 7166 : String(value)); 7167 } 7168 return this.propertyKey; 7169 } 7170 hasAccessEffect(context) { 7171 const { propertyReadSideEffects } = this.scope.context.options 7172 .treeshake; 7173 return (!(this.variable || this.isUndefined) && 7174 propertyReadSideEffects && 7175 (propertyReadSideEffects === 'always' || 7176 this.object.hasEffectsOnInteractionAtPath([this.getPropertyKey()], this.accessInteraction, context))); 7177 } 7178 includeProperties(context, includeChildrenRecursively) { 7179 if (!this.included) { 7180 this.included = true; 7181 if (this.variable) { 7182 this.scope.context.includeVariableInModule(this.variable); 7183 } 7184 } 7185 this.object.include(context, includeChildrenRecursively); 7186 this.property.include(context, includeChildrenRecursively); 7187 } 7188 } 7189 function resolveNamespaceVariables(baseVariable, path, astContext) { 7190 if (path.length === 0) 7191 return baseVariable; 7192 if (!baseVariable.isNamespace || baseVariable instanceof ExternalVariable) 7193 return null; 7194 const exportName = path[0].key; 7195 const variable = baseVariable.context.traceExport(exportName); 7196 if (!variable) { 7197 if (path.length === 1) { 7198 const fileName = baseVariable.context.fileName; 7199 astContext.log(LOGLEVEL_WARN, logMissingExport(exportName, astContext.module.id, fileName), path[0].pos); 7200 return 'undefined'; 7201 } 7202 return null; 7203 } 7204 return resolveNamespaceVariables(variable, path.slice(1), astContext); 7205 } 7206 7207 const FILE_PREFIX = 'ROLLUP_FILE_URL_'; 7208 const IMPORT = 'import'; 7209 class MetaProperty extends NodeBase { 7210 constructor() { 7211 super(...arguments); 7212 this.metaProperty = null; 7213 this.preliminaryChunkId = null; 7214 this.referenceId = null; 7215 } 7216 getReferencedFileName(outputPluginDriver) { 7217 const { meta: { name }, metaProperty } = this; 7218 if (name === IMPORT && metaProperty?.startsWith(FILE_PREFIX)) { 7219 return outputPluginDriver.getFileName(metaProperty.slice(FILE_PREFIX.length)); 7220 } 7221 return null; 7222 } 7223 hasEffects() { 7224 return false; 7225 } 7226 hasEffectsOnInteractionAtPath(path, { type }) { 7227 return path.length > 1 || type !== INTERACTION_ACCESSED; 7228 } 7229 include() { 7230 if (!this.included) { 7231 this.included = true; 7232 if (this.meta.name === IMPORT) { 7233 this.scope.context.addImportMeta(this); 7234 const parent = this.parent; 7235 const metaProperty = (this.metaProperty = 7236 parent instanceof MemberExpression && typeof parent.propertyKey === 'string' 7237 ? parent.propertyKey 7238 : null); 7239 if (metaProperty?.startsWith(FILE_PREFIX)) { 7240 this.referenceId = metaProperty.slice(FILE_PREFIX.length); 7241 } 7242 } 7243 } 7244 } 7245 render(code, renderOptions) { 7246 const { format, pluginDriver, snippets } = renderOptions; 7247 const { scope: { context: { module } }, meta: { name }, metaProperty, parent, preliminaryChunkId, referenceId, start, end } = this; 7248 const { id: moduleId } = module; 7249 if (name !== IMPORT) 7250 return; 7251 const chunkId = preliminaryChunkId; 7252 if (referenceId) { 7253 const fileName = pluginDriver.getFileName(referenceId); 7254 const relativePath = normalize(relative(dirname(chunkId), fileName)); 7255 const replacement = pluginDriver.hookFirstSync('resolveFileUrl', [ 7256 { chunkId, fileName, format, moduleId, referenceId, relativePath } 7257 ]) || relativeUrlMechanisms[format](relativePath); 7258 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true }); 7259 return; 7260 } 7261 let replacement = pluginDriver.hookFirstSync('resolveImportMeta', [ 7262 metaProperty, 7263 { chunkId, format, moduleId } 7264 ]); 7265 if (!replacement) { 7266 replacement = importMetaMechanisms[format]?.(metaProperty, { chunkId, snippets }); 7267 renderOptions.accessedDocumentCurrentScript ||= 7268 formatsMaybeAccessDocumentCurrentScript.includes(format) && replacement !== 'undefined'; 7269 } 7270 if (typeof replacement === 'string') { 7271 if (parent instanceof MemberExpression) { 7272 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true }); 7273 } 7274 else { 7275 code.overwrite(start, end, replacement, { contentOnly: true }); 7276 } 7277 } 7278 } 7279 setResolution(format, accessedGlobalsByScope, preliminaryChunkId) { 7280 this.preliminaryChunkId = preliminaryChunkId; 7281 const accessedGlobals = (this.metaProperty?.startsWith(FILE_PREFIX) ? accessedFileUrlGlobals : accessedMetaUrlGlobals)[format]; 7282 if (accessedGlobals.length > 0) { 7283 this.scope.addAccessedGlobals(accessedGlobals, accessedGlobalsByScope); 7284 } 7285 } 7286 } 7287 const formatsMaybeAccessDocumentCurrentScript = ['cjs', 'iife', 'umd']; 7288 const accessedMetaUrlGlobals = { 7289 amd: ['document', 'module', 'URL'], 7290 cjs: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT], 7291 es: [], 7292 iife: ['document', 'URL', DOCUMENT_CURRENT_SCRIPT], 7293 system: ['module'], 7294 umd: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT] 7295 }; 7296 const accessedFileUrlGlobals = { 7297 amd: ['document', 'require', 'URL'], 7298 cjs: ['document', 'require', 'URL'], 7299 es: [], 7300 iife: ['document', 'URL'], 7301 system: ['module', 'URL'], 7302 umd: ['document', 'require', 'URL'] 7303 }; 7304 const getResolveUrl = (path, URL = 'URL') => `new ${URL}(${path}).href`; 7305 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`); 7306 const getGenericImportMetaMechanism = (getUrl) => (property, { chunkId }) => { 7307 const urlMechanism = getUrl(chunkId); 7308 return property === null 7309 ? `({ url: ${urlMechanism} })` 7310 : property === 'url' 7311 ? urlMechanism 7312 : 'undefined'; 7313 }; 7314 const getFileUrlFromFullPath = (path) => `require('u' + 'rl').pathToFileURL(${path}).href`; 7315 const getFileUrlFromRelativePath = (path) => getFileUrlFromFullPath(`__dirname + '/${escapeId(path)}'`); 7316 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)`; 7317 const relativeUrlMechanisms = { 7318 amd: relativePath => { 7319 if (relativePath[0] !== '.') 7320 relativePath = './' + relativePath; 7321 return getResolveUrl(`require.toUrl('${escapeId(relativePath)}'), document.baseURI`); 7322 }, 7323 cjs: relativePath => `(typeof document === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath)})`, 7324 es: relativePath => getResolveUrl(`'${escapeId(relativePath)}', import.meta.url`), 7325 iife: relativePath => getRelativeUrlFromDocument(relativePath), 7326 system: relativePath => getResolveUrl(`'${escapeId(relativePath)}', module.meta.url`), 7327 umd: relativePath => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath, true)})` 7328 }; 7329 const importMetaMechanisms = { 7330 amd: getGenericImportMetaMechanism(() => getResolveUrl(`module.uri, document.baseURI`)), 7331 cjs: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId)})`), 7332 iife: getGenericImportMetaMechanism(chunkId => getUrlFromDocument(chunkId)), 7333 system: (property, { snippets: { getPropertyAccess } }) => property === null ? `module.meta` : `module.meta${getPropertyAccess(property)}`, 7334 umd: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId, true)})`) 7335 }; 7336 7337 class UndefinedVariable extends Variable { 7338 constructor() { 7339 super('undefined'); 7340 } 7341 getLiteralValueAtPath() { 7342 return undefined; 7343 } 7344 } 7345 7346 class ExportDefaultVariable extends LocalVariable { 7347 constructor(name, exportDefaultDeclaration, context) { 7348 super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other'); 7349 this.hasId = false; 7350 this.originalId = null; 7351 this.originalVariable = null; 7352 const declaration = exportDefaultDeclaration.declaration; 7353 if ((declaration instanceof FunctionDeclaration || declaration instanceof ClassDeclaration) && 7354 declaration.id) { 7355 this.hasId = true; 7356 this.originalId = declaration.id; 7357 } 7358 else if (declaration instanceof Identifier) { 7359 this.originalId = declaration; 7360 } 7361 } 7362 addReference(identifier) { 7363 if (!this.hasId) { 7364 this.name = identifier.name; 7365 } 7366 } 7367 addUsedPlace(usedPlace) { 7368 const original = this.getOriginalVariable(); 7369 if (original === this) { 7370 super.addUsedPlace(usedPlace); 7371 } 7372 else { 7373 original.addUsedPlace(usedPlace); 7374 } 7375 } 7376 forbidName(name) { 7377 const original = this.getOriginalVariable(); 7378 if (original === this) { 7379 super.forbidName(name); 7380 } 7381 else { 7382 original.forbidName(name); 7383 } 7384 } 7385 getAssignedVariableName() { 7386 return (this.originalId && this.originalId.name) || null; 7387 } 7388 getBaseVariableName() { 7389 const original = this.getOriginalVariable(); 7390 return original === this ? super.getBaseVariableName() : original.getBaseVariableName(); 7391 } 7392 getDirectOriginalVariable() { 7393 return this.originalId && 7394 (this.hasId || 7395 !(this.originalId.isPossibleTDZ() || 7396 this.originalId.variable.isReassigned || 7397 this.originalId.variable instanceof UndefinedVariable || 7398 // this avoids a circular dependency 7399 'syntheticNamespace' in this.originalId.variable)) 7400 ? this.originalId.variable 7401 : null; 7402 } 7403 getName(getPropertyAccess) { 7404 const original = this.getOriginalVariable(); 7405 return original === this 7406 ? super.getName(getPropertyAccess) 7407 : original.getName(getPropertyAccess); 7408 } 7409 getOriginalVariable() { 7410 if (this.originalVariable) 7411 return this.originalVariable; 7412 // eslint-disable-next-line @typescript-eslint/no-this-alias 7413 let original = this; 7414 let currentVariable; 7415 const checkedVariables = new Set(); 7416 do { 7417 checkedVariables.add(original); 7418 currentVariable = original; 7419 original = currentVariable.getDirectOriginalVariable(); 7420 } while (original instanceof ExportDefaultVariable && !checkedVariables.has(original)); 7421 return (this.originalVariable = original || currentVariable); 7422 } 7423 } 7424 7425 class NamespaceVariable extends Variable { 7426 constructor(context) { 7427 super(context.getModuleName()); 7428 this.memberVariables = null; 7429 this.mergedNamespaces = []; 7430 this.referencedEarly = false; 7431 this.references = []; 7432 this.context = context; 7433 this.module = context.module; 7434 } 7435 addReference(identifier) { 7436 this.references.push(identifier); 7437 this.name = identifier.name; 7438 } 7439 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 7440 if (path.length > 1 || (path.length === 1 && interaction.type === INTERACTION_CALLED)) { 7441 const key = path[0]; 7442 if (typeof key === 'string') { 7443 this.getMemberVariables()[key]?.deoptimizeArgumentsOnInteractionAtPath(interaction, path.slice(1), recursionTracker); 7444 } 7445 else { 7446 deoptimizeInteraction(interaction); 7447 } 7448 } 7449 } 7450 deoptimizePath(path) { 7451 if (path.length > 1) { 7452 const key = path[0]; 7453 if (typeof key === 'string') { 7454 this.getMemberVariables()[key]?.deoptimizePath(path.slice(1)); 7455 } 7456 } 7457 } 7458 getLiteralValueAtPath(path) { 7459 if (path[0] === SymbolToStringTag) { 7460 return 'Module'; 7461 } 7462 return UnknownValue; 7463 } 7464 getMemberVariables() { 7465 if (this.memberVariables) { 7466 return this.memberVariables; 7467 } 7468 const memberVariables = Object.create(null); 7469 const sortedExports = [...this.context.getExports(), ...this.context.getReexports()].sort(); 7470 for (const name of sortedExports) { 7471 if (name[0] !== '*' && name !== this.module.info.syntheticNamedExports) { 7472 const exportedVariable = this.context.traceExport(name); 7473 if (exportedVariable) { 7474 memberVariables[name] = exportedVariable; 7475 } 7476 } 7477 } 7478 return (this.memberVariables = memberVariables); 7479 } 7480 hasEffectsOnInteractionAtPath(path, interaction, context) { 7481 const { type } = interaction; 7482 if (path.length === 0) { 7483 // This can only be a call anyway 7484 return true; 7485 } 7486 if (path.length === 1 && type !== INTERACTION_CALLED) { 7487 return type === INTERACTION_ASSIGNED; 7488 } 7489 const key = path[0]; 7490 if (typeof key !== 'string') { 7491 return true; 7492 } 7493 const memberVariable = this.getMemberVariables()[key]; 7494 return (!memberVariable || 7495 memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context)); 7496 } 7497 include() { 7498 super.include(); 7499 this.context.includeAllExports(); 7500 } 7501 prepare(accessedGlobalsByScope) { 7502 if (this.mergedNamespaces.length > 0) { 7503 this.module.scope.addAccessedGlobals([MERGE_NAMESPACES_VARIABLE], accessedGlobalsByScope); 7504 } 7505 } 7506 renderBlock(options) { 7507 const { exportNamesByVariable, format, freeze, indent: t, symbols, snippets: { _, cnst, getObject, getPropertyAccess, n, s } } = options; 7508 const memberVariables = this.getMemberVariables(); 7509 const members = Object.entries(memberVariables) 7510 .filter(([_, variable]) => variable.included) 7511 .map(([name, variable]) => { 7512 if (this.referencedEarly || variable.isReassigned || variable === this) { 7513 return [ 7514 null, 7515 `get ${stringifyObjectKeyIfNeeded(name)}${_}()${_}{${_}return ${variable.getName(getPropertyAccess)}${s}${_}}` 7516 ]; 7517 } 7518 return [name, variable.getName(getPropertyAccess)]; 7519 }); 7520 members.unshift([null, `__proto__:${_}null`]); 7521 let output = getObject(members, { lineBreakIndent: { base: '', t } }); 7522 if (this.mergedNamespaces.length > 0) { 7523 const assignmentArguments = this.mergedNamespaces.map(variable => variable.getName(getPropertyAccess)); 7524 output = `/*#__PURE__*/${MERGE_NAMESPACES_VARIABLE}(${output},${_}[${assignmentArguments.join(`,${_}`)}])`; 7525 } 7526 else { 7527 // The helper to merge namespaces will also take care of freezing and toStringTag 7528 if (symbols) { 7529 output = `/*#__PURE__*/Object.defineProperty(${output},${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)})`; 7530 } 7531 if (freeze) { 7532 output = `/*#__PURE__*/Object.freeze(${output})`; 7533 } 7534 } 7535 const name = this.getName(getPropertyAccess); 7536 output = `${cnst} ${name}${_}=${_}${output};`; 7537 if (format === 'system' && exportNamesByVariable.has(this)) { 7538 output += `${n}${getSystemExportStatement([this], options)};`; 7539 } 7540 return output; 7541 } 7542 renderFirst() { 7543 return this.referencedEarly; 7544 } 7545 setMergedNamespaces(mergedNamespaces) { 7546 this.mergedNamespaces = mergedNamespaces; 7547 const moduleExecIndex = this.context.getModuleExecIndex(); 7548 for (const identifier of this.references) { 7549 const { context } = identifier.scope; 7550 if (context.getModuleExecIndex() <= moduleExecIndex) { 7551 this.referencedEarly = true; 7552 break; 7553 } 7554 } 7555 } 7556 } 7557 NamespaceVariable.prototype.isNamespace = true; 7558 7559 class SyntheticNamedExportVariable extends Variable { 7560 constructor(context, name, syntheticNamespace) { 7561 super(name); 7562 this.baseVariable = null; 7563 this.context = context; 7564 this.module = context.module; 7565 this.syntheticNamespace = syntheticNamespace; 7566 } 7567 getBaseVariable() { 7568 if (this.baseVariable) 7569 return this.baseVariable; 7570 let baseVariable = this.syntheticNamespace; 7571 while (baseVariable instanceof ExportDefaultVariable || 7572 baseVariable instanceof SyntheticNamedExportVariable) { 7573 if (baseVariable instanceof ExportDefaultVariable) { 7574 const original = baseVariable.getOriginalVariable(); 7575 if (original === baseVariable) 7576 break; 7577 baseVariable = original; 7578 } 7579 if (baseVariable instanceof SyntheticNamedExportVariable) { 7580 baseVariable = baseVariable.syntheticNamespace; 7581 } 7582 } 7583 return (this.baseVariable = baseVariable); 7584 } 7585 getBaseVariableName() { 7586 return this.syntheticNamespace.getBaseVariableName(); 7587 } 7588 getName(getPropertyAccess) { 7589 return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`; 7590 } 7591 include() { 7592 super.include(); 7593 this.context.includeVariableInModule(this.syntheticNamespace); 7594 } 7595 setRenderNames(baseName, name) { 7596 super.setRenderNames(baseName, name); 7597 } 7598 } 7599 7600 class ExternalChunk { 7601 constructor(module, options, inputBase) { 7602 this.options = options; 7603 this.inputBase = inputBase; 7604 this.defaultVariableName = ''; 7605 this.namespaceVariableName = ''; 7606 this.variableName = ''; 7607 this.fileName = null; 7608 this.importAttributes = null; 7609 this.id = module.id; 7610 this.moduleInfo = module.info; 7611 this.renormalizeRenderPath = module.renormalizeRenderPath; 7612 this.suggestedVariableName = module.suggestedVariableName; 7613 } 7614 getFileName() { 7615 if (this.fileName) { 7616 return this.fileName; 7617 } 7618 const { paths } = this.options; 7619 return (this.fileName = 7620 (typeof paths === 'function' ? paths(this.id) : paths[this.id]) || 7621 (this.renormalizeRenderPath ? normalize(relative(this.inputBase, this.id)) : this.id)); 7622 } 7623 getImportAttributes(snippets) { 7624 return (this.importAttributes ||= formatAttributes(this.options.format === 'es' && 7625 this.options.externalImportAttributes && 7626 this.moduleInfo.attributes, snippets)); 7627 } 7628 getImportPath(importer) { 7629 return escapeId(this.renormalizeRenderPath 7630 ? getImportPath(importer, this.getFileName(), this.options.format === 'amd', false) 7631 : this.getFileName()); 7632 } 7633 } 7634 function formatAttributes(attributes, { getObject }) { 7635 if (!attributes) { 7636 return null; 7637 } 7638 const assertionEntries = Object.entries(attributes).map(([key, value]) => [key, `'${value}'`]); 7639 if (assertionEntries.length > 0) { 7640 return getObject(assertionEntries, { lineBreakIndent: null }); 7641 } 7642 return null; 7643 } 7644 7645 function removeJsExtension(name) { 7646 return name.endsWith('.js') ? name.slice(0, -3) : name; 7647 } 7648 7649 function getCompleteAmdId(options, chunkId) { 7650 if (options.autoId) { 7651 return `${options.basePath ? options.basePath + '/' : ''}${removeJsExtension(chunkId)}`; 7652 } 7653 return options.id ?? ''; 7654 } 7655 7656 function getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, mechanism = 'return ') { 7657 const { _, getDirectReturnFunction, getFunctionIntro, getPropertyAccess, n, s } = snippets; 7658 if (!namedExportsMode) { 7659 return `${n}${n}${mechanism}${getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess)};`; 7660 } 7661 let exportBlock = ''; 7662 if (namedExportsMode) { 7663 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) { 7664 if (!reexports) { 7665 continue; 7666 } 7667 for (const specifier of reexports) { 7668 if (specifier.reexported !== '*') { 7669 const importName = getReexportedImportName(name, specifier.imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess); 7670 if (exportBlock) 7671 exportBlock += n; 7672 if (specifier.imported !== '*' && specifier.needsLiveBinding) { 7673 const [left, right] = getDirectReturnFunction([], { 7674 functionReturn: true, 7675 lineBreakIndent: null, 7676 name: null 7677 }); 7678 exportBlock += 7679 `Object.defineProperty(exports,${_}${JSON.stringify(specifier.reexported)},${_}{${n}` + 7680 `${t}enumerable:${_}true,${n}` + 7681 `${t}get:${_}${left}${importName}${right}${n}});`; 7682 } 7683 else if (specifier.reexported === '__proto__') { 7684 exportBlock += 7685 `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` + 7686 `${t}enumerable:${_}true,${n}` + 7687 `${t}value:${_}${importName}${n}});`; 7688 } 7689 else { 7690 exportBlock += `exports${getPropertyAccess(specifier.reexported)}${_}=${_}${importName};`; 7691 } 7692 } 7693 } 7694 } 7695 } 7696 for (const { exported, local } of exports) { 7697 const lhs = `exports${getPropertyAccess(exported)}`; 7698 const rhs = local; 7699 if (lhs !== rhs) { 7700 if (exportBlock) 7701 exportBlock += n; 7702 exportBlock += 7703 exported === '__proto__' 7704 ? `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` + 7705 `${t}enumerable:${_}true,${n}` + 7706 `${t}value:${_}${rhs}${n}});` 7707 : `${lhs}${_}=${_}${rhs};`; 7708 } 7709 } 7710 if (namedExportsMode) { 7711 for (const { name, reexports } of dependencies) { 7712 if (!reexports) { 7713 continue; 7714 } 7715 for (const specifier of reexports) { 7716 if (specifier.reexported === '*') { 7717 if (exportBlock) 7718 exportBlock += n; 7719 if (!specifier.needsLiveBinding && reexportProtoFromExternal) { 7720 const protoString = "'__proto__'"; 7721 exportBlock += 7722 `Object.prototype.hasOwnProperty.call(${name},${_}${protoString})${_}&&${n}` + 7723 `${t}!Object.prototype.hasOwnProperty.call(exports,${_}${protoString})${_}&&${n}` + 7724 `${t}Object.defineProperty(exports,${_}${protoString},${_}{${n}` + 7725 `${t}${t}enumerable:${_}true,${n}` + 7726 `${t}${t}value:${_}${name}[${protoString}]${n}` + 7727 `${t}});${n}${n}`; 7728 } 7729 const copyPropertyIfNecessary = `{${n}${t}if${_}(k${_}!==${_}'default'${_}&&${_}!Object.prototype.hasOwnProperty.call(exports,${_}k))${_}${getDefineProperty(name, specifier.needsLiveBinding, t, snippets)}${s}${n}}`; 7730 exportBlock += `Object.keys(${name}).forEach(${getFunctionIntro(['k'], { 7731 isAsync: false, 7732 name: null 7733 })}${copyPropertyIfNecessary});`; 7734 } 7735 } 7736 } 7737 } 7738 if (exportBlock) { 7739 return `${n}${n}${exportBlock}`; 7740 } 7741 return ''; 7742 } 7743 function getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess) { 7744 if (exports.length > 0) { 7745 return exports[0].local; 7746 } 7747 else { 7748 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) { 7749 if (reexports) { 7750 return getReexportedImportName(name, reexports[0].imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess); 7751 } 7752 } 7753 } 7754 } 7755 function getReexportedImportName(moduleVariableName, imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, moduleId, externalLiveBindings, getPropertyAccess) { 7756 if (imported === 'default') { 7757 if (!isChunk) { 7758 const moduleInterop = interop(moduleId); 7759 const variableName = defaultInteropHelpersByInteropType[moduleInterop] 7760 ? defaultVariableName 7761 : moduleVariableName; 7762 return isDefaultAProperty(moduleInterop, externalLiveBindings) 7763 ? `${variableName}${getPropertyAccess('default')}` 7764 : variableName; 7765 } 7766 return depNamedExportsMode 7767 ? `${moduleVariableName}${getPropertyAccess('default')}` 7768 : moduleVariableName; 7769 } 7770 if (imported === '*') { 7771 return (isChunk ? !depNamedExportsMode : namespaceInteropHelpersByInteropType[interop(moduleId)]) 7772 ? namespaceVariableName 7773 : moduleVariableName; 7774 } 7775 return `${moduleVariableName}${getPropertyAccess(imported)}`; 7776 } 7777 function getEsModuleValue(getObject) { 7778 return getObject([['value', 'true']], { 7779 lineBreakIndent: null 7780 }); 7781 } 7782 function getNamespaceMarkers(hasNamedExports, addEsModule, addNamespaceToStringTag, { _, getObject }) { 7783 if (hasNamedExports) { 7784 if (addEsModule) { 7785 if (addNamespaceToStringTag) { 7786 return `Object.defineProperties(exports,${_}${getObject([ 7787 ['__esModule', getEsModuleValue(getObject)], 7788 [null, `[Symbol.toStringTag]:${_}${getToStringTagValue(getObject)}`] 7789 ], { 7790 lineBreakIndent: null 7791 })});`; 7792 } 7793 return `Object.defineProperty(exports,${_}'__esModule',${_}${getEsModuleValue(getObject)});`; 7794 } 7795 if (addNamespaceToStringTag) { 7796 return `Object.defineProperty(exports,${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)});`; 7797 } 7798 } 7799 return ''; 7800 } 7801 const getDefineProperty = (name, needsLiveBinding, t, { _, getDirectReturnFunction, n }) => { 7802 if (needsLiveBinding) { 7803 const [left, right] = getDirectReturnFunction([], { 7804 functionReturn: true, 7805 lineBreakIndent: null, 7806 name: null 7807 }); 7808 return (`Object.defineProperty(exports,${_}k,${_}{${n}` + 7809 `${t}${t}enumerable:${_}true,${n}` + 7810 `${t}${t}get:${_}${left}${name}[k]${right}${n}${t}})`); 7811 } 7812 return `exports[k]${_}=${_}${name}[k]`; 7813 }; 7814 7815 function getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, indent, snippets) { 7816 const { _, cnst, n } = snippets; 7817 const neededInteropHelpers = new Set(); 7818 const interopStatements = []; 7819 const addInteropStatement = (helperVariableName, helper, dependencyVariableName) => { 7820 neededInteropHelpers.add(helper); 7821 interopStatements.push(`${cnst} ${helperVariableName}${_}=${_}/*#__PURE__*/${helper}(${dependencyVariableName});`); 7822 }; 7823 for (const { defaultVariableName, imports, importPath, isChunk, name, namedExportsMode, namespaceVariableName, reexports } of dependencies) { 7824 if (isChunk) { 7825 for (const { imported, reexported } of [ 7826 ...(imports || []), 7827 ...(reexports || []) 7828 ]) { 7829 if (imported === '*' && reexported !== '*') { 7830 if (!namedExportsMode) { 7831 addInteropStatement(namespaceVariableName, INTEROP_NAMESPACE_DEFAULT_ONLY_VARIABLE, name); 7832 } 7833 break; 7834 } 7835 } 7836 } 7837 else { 7838 const moduleInterop = interop(importPath); 7839 let hasDefault = false; 7840 let hasNamespace = false; 7841 for (const { imported, reexported } of [ 7842 ...(imports || []), 7843 ...(reexports || []) 7844 ]) { 7845 let helper; 7846 let variableName; 7847 if (imported === 'default') { 7848 if (!hasDefault) { 7849 hasDefault = true; 7850 if (defaultVariableName !== namespaceVariableName) { 7851 variableName = defaultVariableName; 7852 helper = defaultInteropHelpersByInteropType[moduleInterop]; 7853 } 7854 } 7855 } 7856 else if (imported === '*' && reexported !== '*' && !hasNamespace) { 7857 hasNamespace = true; 7858 helper = namespaceInteropHelpersByInteropType[moduleInterop]; 7859 variableName = namespaceVariableName; 7860 } 7861 if (helper) { 7862 addInteropStatement(variableName, helper, name); 7863 } 7864 } 7865 } 7866 } 7867 return `${getHelpersBlock(neededInteropHelpers, accessedGlobals, indent, snippets, externalLiveBindings, freeze, symbols)}${interopStatements.length > 0 ? `${interopStatements.join(n)}${n}${n}` : ''}`; 7868 } 7869 7870 function addJsExtension(name) { 7871 return name.endsWith('.js') ? name : name + '.js'; 7872 } 7873 7874 // AMD resolution will only respect the AMD baseUrl if the .js extension is omitted. 7875 // The assumption is that this makes sense for all relative ids: 7876 // https://requirejs.org/docs/api.html#jsfiles 7877 function updateExtensionForRelativeAmdId(id, forceJsExtensionForImports) { 7878 if (id[0] !== '.') { 7879 return id; 7880 } 7881 return forceJsExtensionForImports ? addJsExtension(id) : removeJsExtension(id); 7882 } 7883 7884 const builtinModules = [ 7885 "assert", 7886 "assert/strict", 7887 "async_hooks", 7888 "buffer", 7889 "child_process", 7890 "cluster", 7891 "console", 7892 "constants", 7893 "crypto", 7894 "dgram", 7895 "diagnostics_channel", 7896 "dns", 7897 "dns/promises", 7898 "domain", 7899 "events", 7900 "fs", 7901 "fs/promises", 7902 "http", 7903 "http2", 7904 "https", 7905 "inspector", 7906 "inspector/promises", 7907 "module", 7908 "net", 7909 "os", 7910 "path", 7911 "path/posix", 7912 "path/win32", 7913 "perf_hooks", 7914 "process", 7915 "punycode", 7916 "querystring", 7917 "readline", 7918 "readline/promises", 7919 "repl", 7920 "stream", 7921 "stream/consumers", 7922 "stream/promises", 7923 "stream/web", 7924 "string_decoder", 7925 "timers", 7926 "timers/promises", 7927 "tls", 7928 "trace_events", 7929 "tty", 7930 "url", 7931 "util", 7932 "util/types", 7933 "v8", 7934 "vm", 7935 "wasi", 7936 "worker_threads", 7937 "zlib" 7938 ]; 7939 7940 const nodeBuiltins = new Set(builtinModules); 7941 function warnOnBuiltins(log, dependencies) { 7942 const externalBuiltins = dependencies 7943 .map(({ importPath }) => importPath) 7944 .filter(importPath => nodeBuiltins.has(importPath) || importPath.startsWith('node:')); 7945 if (externalBuiltins.length === 0) 7946 return; 7947 log(LOGLEVEL_WARN, logMissingNodeBuiltins(externalBuiltins)); 7948 } 7949 7950 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 }) { 7951 warnOnBuiltins(log, dependencies); 7952 const deps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); 7953 const parameters = dependencies.map(m => m.name); 7954 const { n, getNonArrowFunctionIntro, _ } = snippets; 7955 if (namedExportsMode && hasExports) { 7956 parameters.unshift(`exports`); 7957 deps.unshift(`'exports'`); 7958 } 7959 if (accessedGlobals.has('require')) { 7960 parameters.unshift('require'); 7961 deps.unshift(`'require'`); 7962 } 7963 if (accessedGlobals.has('module')) { 7964 parameters.unshift('module'); 7965 deps.unshift(`'module'`); 7966 } 7967 const completeAmdId = getCompleteAmdId(amd, id); 7968 const defineParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) + 7969 (deps.length > 0 ? `[${deps.join(`,${_}`)}],${_}` : ``); 7970 const useStrict = strict ? `${_}'use strict';` : ''; 7971 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`); 7972 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 7973 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets); 7974 if (namespaceMarkers) { 7975 namespaceMarkers = n + n + namespaceMarkers; 7976 } 7977 magicString 7978 .append(`${exportBlock}${namespaceMarkers}${outro}`) 7979 .indent(t) 7980 // factory function should be wrapped by parentheses to avoid lazy parsing, 7981 // cf. https://v8.dev/blog/preparser#pife 7982 .prepend(`${amd.define}(${defineParameters}(${getNonArrowFunctionIntro(parameters, { 7983 isAsync: false, 7984 name: null 7985 })}{${useStrict}${n}${n}`) 7986 .append(`${n}${n}}));`); 7987 } 7988 7989 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 }) { 7990 const { _, n } = snippets; 7991 const useStrict = strict ? `'use strict';${n}${n}` : ''; 7992 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets); 7993 if (namespaceMarkers) { 7994 namespaceMarkers += n + n; 7995 } 7996 const importBlock = getImportBlock$1(dependencies, snippets, compact); 7997 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets); 7998 magicString.prepend(`${useStrict}${intro}${namespaceMarkers}${importBlock}${interopBlock}`); 7999 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, `module.exports${_}=${_}`); 8000 magicString.append(`${exportBlock}${outro}`); 8001 } 8002 function getImportBlock$1(dependencies, { _, cnst, n }, compact) { 8003 let importBlock = ''; 8004 let definingVariable = false; 8005 for (const { importPath, name, reexports, imports } of dependencies) { 8006 if (!reexports && !imports) { 8007 if (importBlock) { 8008 importBlock += compact && !definingVariable ? ',' : `;${n}`; 8009 } 8010 definingVariable = false; 8011 importBlock += `require('${importPath}')`; 8012 } 8013 else { 8014 importBlock += compact && definingVariable ? ',' : `${importBlock ? `;${n}` : ''}${cnst} `; 8015 definingVariable = true; 8016 importBlock += `${name}${_}=${_}require('${importPath}')`; 8017 } 8018 } 8019 if (importBlock) { 8020 return `${importBlock};${n}${n}`; 8021 } 8022 return ''; 8023 } 8024 8025 function es(magicString, { accessedGlobals, indent: t, intro, outro, dependencies, exports, snippets }, { externalLiveBindings, freeze, generatedCode: { symbols }, importAttributesKey }) { 8026 const { n } = snippets; 8027 const importBlock = getImportBlock(dependencies, importAttributesKey, snippets); 8028 if (importBlock.length > 0) 8029 intro += importBlock.join(n) + n + n; 8030 intro += getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols); 8031 if (intro) 8032 magicString.prepend(intro); 8033 const exportBlock = getExportBlock(exports, snippets); 8034 if (exportBlock.length > 0) 8035 magicString.append(n + n + exportBlock.join(n).trim()); 8036 if (outro) 8037 magicString.append(outro); 8038 magicString.trim(); 8039 } 8040 function getImportBlock(dependencies, importAttributesKey, { _ }) { 8041 const importBlock = []; 8042 for (const { importPath, reexports, imports, name, attributes } of dependencies) { 8043 const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : ''; 8044 const pathWithAssertion = `'${importPath}'${assertion};`; 8045 if (!reexports && !imports) { 8046 importBlock.push(`import${_}${pathWithAssertion}`); 8047 continue; 8048 } 8049 if (imports) { 8050 let defaultImport = null; 8051 let starImport = null; 8052 const importedNames = []; 8053 for (const specifier of imports) { 8054 if (specifier.imported === 'default') { 8055 defaultImport = specifier; 8056 } 8057 else if (specifier.imported === '*') { 8058 starImport = specifier; 8059 } 8060 else { 8061 importedNames.push(specifier); 8062 } 8063 } 8064 if (starImport) { 8065 importBlock.push(`import${_}*${_}as ${starImport.local} from${_}${pathWithAssertion}`); 8066 } 8067 if (defaultImport && importedNames.length === 0) { 8068 importBlock.push(`import ${defaultImport.local} from${_}${pathWithAssertion}`); 8069 } 8070 else if (importedNames.length > 0) { 8071 importBlock.push(`import ${defaultImport ? `${defaultImport.local},${_}` : ''}{${_}${importedNames 8072 .map(specifier => specifier.imported === specifier.local 8073 ? specifier.imported 8074 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${specifier.local}`) 8075 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`); 8076 } 8077 } 8078 if (reexports) { 8079 let starExport = null; 8080 const namespaceReexports = []; 8081 const namedReexports = []; 8082 for (const specifier of reexports) { 8083 if (specifier.reexported === '*') { 8084 starExport = specifier; 8085 } 8086 else if (specifier.imported === '*') { 8087 namespaceReexports.push(specifier); 8088 } 8089 else { 8090 namedReexports.push(specifier); 8091 } 8092 } 8093 if (starExport) { 8094 importBlock.push(`export${_}*${_}from${_}${pathWithAssertion}`); 8095 } 8096 if (namespaceReexports.length > 0) { 8097 if (!imports || 8098 !imports.some(specifier => specifier.imported === '*' && specifier.local === name)) { 8099 importBlock.push(`import${_}*${_}as ${name} from${_}${pathWithAssertion}`); 8100 } 8101 for (const specifier of namespaceReexports) { 8102 importBlock.push(`export${_}{${_}${name === specifier.reexported 8103 ? name 8104 : `${name} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`} };`); 8105 } 8106 } 8107 if (namedReexports.length > 0) { 8108 importBlock.push(`export${_}{${_}${namedReexports 8109 .map(specifier => specifier.imported === specifier.reexported 8110 ? stringifyIdentifierIfNeeded(specifier.imported) 8111 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`) 8112 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`); 8113 } 8114 } 8115 } 8116 return importBlock; 8117 } 8118 function getExportBlock(exports, { _, cnst }) { 8119 const exportBlock = []; 8120 const exportDeclaration = new Array(exports.length); 8121 let index = 0; 8122 for (const specifier of exports) { 8123 if (specifier.expression) { 8124 exportBlock.push(`${cnst} ${specifier.local}${_}=${_}${specifier.expression};`); 8125 } 8126 exportDeclaration[index++] = 8127 specifier.exported === specifier.local 8128 ? specifier.local 8129 : `${specifier.local} as ${stringifyIdentifierIfNeeded(specifier.exported)}`; 8130 } 8131 if (exportDeclaration.length > 0) { 8132 exportBlock.push(`export${_}{${_}${exportDeclaration.join(`,${_}`)}${_}};`); 8133 } 8134 return exportBlock; 8135 } 8136 8137 const keypath = (keypath, getPropertyAccess) => keypath.split('.').map(getPropertyAccess).join(''); 8138 8139 function setupNamespace(name, root, globals, { _, getPropertyAccess, s }, compact, log) { 8140 const parts = name.split('.'); 8141 // Check if the key exists in the object's prototype. 8142 const isReserved = parts[0] in Object.prototype; 8143 if (log && isReserved) { 8144 log(LOGLEVEL_WARN, logReservedNamespace(parts[0])); 8145 } 8146 parts[0] = 8147 (typeof globals === 'function' 8148 ? globals(parts[0]) 8149 : isReserved 8150 ? parts[0] 8151 : globals[parts[0]]) || parts[0]; 8152 parts.pop(); 8153 let propertyPath = root; 8154 return (parts 8155 .map(part => { 8156 propertyPath += getPropertyAccess(part); 8157 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}${s}`; 8158 }) 8159 .join(compact ? ',' : '\n') + (compact && parts.length > 0 ? ';' : '\n')); 8160 } 8161 function assignToDeepVariable(deepName, root, globals, assignment, { _, getPropertyAccess }, log) { 8162 const parts = deepName.split('.'); 8163 // Check if the key exists in the object's prototype. 8164 const isReserved = parts[0] in Object.prototype; 8165 if (log && isReserved) { 8166 log(LOGLEVEL_WARN, logReservedNamespace(parts[0])); 8167 } 8168 parts[0] = 8169 (typeof globals === 'function' 8170 ? globals(parts[0]) 8171 : isReserved 8172 ? parts[0] 8173 : globals[parts[0]]) || parts[0]; 8174 const last = parts.pop(); 8175 let propertyPath = root; 8176 let deepAssignment = [ 8177 ...parts.map(part => { 8178 propertyPath += getPropertyAccess(part); 8179 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}`; 8180 }), 8181 `${propertyPath}${getPropertyAccess(last)}` 8182 ].join(`,${_}`) + `${_}=${_}${assignment}`; 8183 if (parts.length > 0) { 8184 deepAssignment = `(${deepAssignment})`; 8185 } 8186 return deepAssignment; 8187 } 8188 8189 function trimEmptyImports(dependencies) { 8190 let index = dependencies.length; 8191 while (index--) { 8192 const { imports, reexports } = dependencies[index]; 8193 if (imports || reexports) { 8194 return dependencies.slice(0, index + 1); 8195 } 8196 } 8197 return []; 8198 } 8199 8200 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 }) { 8201 const { _, getNonArrowFunctionIntro, getPropertyAccess, n } = snippets; 8202 const isNamespaced = name && name.includes('.'); 8203 const useVariableAssignment = !extend && !isNamespaced; 8204 if (name && useVariableAssignment && !isLegal(name)) { 8205 return error(logIllegalIdentifierAsName(name)); 8206 } 8207 warnOnBuiltins(log, dependencies); 8208 const external = trimEmptyImports(dependencies); 8209 const deps = external.map(dep => dep.globalName || 'null'); 8210 const parameters = external.map(m => m.name); 8211 if (hasExports && !name) { 8212 log(LOGLEVEL_WARN, logMissingNameOptionForIifeExport()); 8213 } 8214 if (namedExportsMode && hasExports) { 8215 if (extend) { 8216 deps.unshift(`this${keypath(name, getPropertyAccess)}${_}=${_}this${keypath(name, getPropertyAccess)}${_}||${_}{}`); 8217 parameters.unshift('exports'); 8218 } 8219 else { 8220 deps.unshift('{}'); 8221 parameters.unshift('exports'); 8222 } 8223 } 8224 const useStrict = strict ? `${t}'use strict';${n}` : ''; 8225 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets); 8226 magicString.prepend(`${intro}${interopBlock}`); 8227 let wrapperIntro = `(${getNonArrowFunctionIntro(parameters, { 8228 isAsync: false, 8229 name: null 8230 })}{${n}${useStrict}${n}`; 8231 if (hasExports) { 8232 if (name && !(extend && namedExportsMode)) { 8233 wrapperIntro = 8234 (useVariableAssignment ? `var ${name}` : `this${keypath(name, getPropertyAccess)}`) + 8235 `${_}=${_}${wrapperIntro}`; 8236 } 8237 if (isNamespaced) { 8238 wrapperIntro = setupNamespace(name, 'this', globals, snippets, compact, log) + wrapperIntro; 8239 } 8240 } 8241 let wrapperOutro = `${n}${n}})(${deps.join(`,${_}`)});`; 8242 if (hasExports && !extend && namedExportsMode) { 8243 wrapperOutro = `${n}${n}${t}return exports;${wrapperOutro}`; 8244 } 8245 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 8246 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets); 8247 if (namespaceMarkers) { 8248 namespaceMarkers = n + n + namespaceMarkers; 8249 } 8250 magicString 8251 .append(`${exportBlock}${namespaceMarkers}${outro}`) 8252 .indent(t) 8253 .prepend(wrapperIntro) 8254 .append(wrapperOutro); 8255 } 8256 8257 const MISSING_EXPORT_SHIM_VARIABLE = '_missingExportShim'; 8258 8259 function system(magicString, { accessedGlobals, dependencies, exports, hasExports, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) { 8260 const { _, getFunctionIntro, getNonArrowFunctionIntro, n, s } = snippets; 8261 const { importBindings, setters, starExcludes } = analyzeDependencies(dependencies, exports, t, snippets); 8262 const registeredName = name ? `'${name}',${_}` : ''; 8263 const wrapperParameters = accessedGlobals.has('module') 8264 ? ['exports', 'module'] 8265 : hasExports 8266 ? ['exports'] 8267 : []; 8268 // factory function should be wrapped by parentheses to avoid lazy parsing, 8269 // cf. https://v8.dev/blog/preparser#pife 8270 let wrapperStart = `System.register(${registeredName}[` + 8271 dependencies.map(({ importPath }) => `'${importPath}'`).join(`,${_}`) + 8272 `],${_}(${getNonArrowFunctionIntro(wrapperParameters, { 8273 isAsync: false, 8274 name: null 8275 })}{${n}${t}${strict ? "'use strict';" : ''}` + 8276 getStarExcludesBlock(starExcludes, t, snippets) + 8277 getImportBindingsBlock(importBindings, t, snippets) + 8278 `${n}${t}return${_}{${setters.length > 0 8279 ? `${n}${t}${t}setters:${_}[${setters 8280 .map(setter => setter 8281 ? `${getFunctionIntro(['module'], { 8282 isAsync: false, 8283 name: null 8284 })}{${n}${t}${t}${t}${setter}${n}${t}${t}}` 8285 : systemNullSetters 8286 ? `null` 8287 : `${getFunctionIntro([], { isAsync: false, name: null })}{}`) 8288 .join(`,${_}`)}],` 8289 : ''}${n}`; 8290 wrapperStart += `${t}${t}execute:${_}(${getNonArrowFunctionIntro([], { 8291 isAsync: usesTopLevelAwait, 8292 name: null 8293 })}{${n}${n}`; 8294 const wrapperEnd = `${t}${t}})${n}${t}}${s}${n}}));`; 8295 magicString 8296 .prepend(intro + 8297 getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols) + 8298 getHoistedExportsBlock(exports, t, snippets)) 8299 .append(`${outro}${n}${n}` + 8300 getSyntheticExportsBlock(exports, t, snippets) + 8301 getMissingExportsBlock(exports, t, snippets)) 8302 .indent(`${t}${t}${t}`) 8303 .append(wrapperEnd) 8304 .prepend(wrapperStart); 8305 } 8306 function analyzeDependencies(dependencies, exports, t, { _, cnst, getObject, getPropertyAccess, n }) { 8307 const importBindings = []; 8308 const setters = []; 8309 let starExcludes = null; 8310 for (const { imports, reexports } of dependencies) { 8311 const setter = []; 8312 if (imports) { 8313 for (const specifier of imports) { 8314 importBindings.push(specifier.local); 8315 if (specifier.imported === '*') { 8316 setter.push(`${specifier.local}${_}=${_}module;`); 8317 } 8318 else { 8319 setter.push(`${specifier.local}${_}=${_}module${getPropertyAccess(specifier.imported)};`); 8320 } 8321 } 8322 } 8323 if (reexports) { 8324 const reexportedNames = []; 8325 let hasStarReexport = false; 8326 for (const { imported, reexported } of reexports) { 8327 if (reexported === '*') { 8328 hasStarReexport = true; 8329 } 8330 else { 8331 reexportedNames.push([ 8332 reexported, 8333 imported === '*' ? 'module' : `module${getPropertyAccess(imported)}` 8334 ]); 8335 } 8336 } 8337 if (reexportedNames.length > 1 || hasStarReexport) { 8338 if (hasStarReexport) { 8339 if (!starExcludes) { 8340 starExcludes = getStarExcludes({ dependencies, exports }); 8341 } 8342 reexportedNames.unshift([null, `__proto__:${_}null`]); 8343 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null }); 8344 setter.push(`${cnst} setter${_}=${_}${exportMapping};`, `for${_}(${cnst} name in module)${_}{`, `${t}if${_}(!_starExcludes[name])${_}setter[name]${_}=${_}module[name];`, '}', 'exports(setter);'); 8345 } 8346 else { 8347 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null }); 8348 setter.push(`exports(${exportMapping});`); 8349 } 8350 } 8351 else { 8352 const [key, value] = reexportedNames[0]; 8353 setter.push(`exports(${JSON.stringify(key)},${_}${value});`); 8354 } 8355 } 8356 setters.push(setter.join(`${n}${t}${t}${t}`)); 8357 } 8358 return { importBindings, setters, starExcludes }; 8359 } 8360 const getStarExcludes = ({ dependencies, exports }) => { 8361 const starExcludes = new Set(exports.map(expt => expt.exported)); 8362 starExcludes.add('default'); 8363 for (const { reexports } of dependencies) { 8364 if (reexports) { 8365 for (const reexport of reexports) { 8366 if (reexport.reexported !== '*') 8367 starExcludes.add(reexport.reexported); 8368 } 8369 } 8370 } 8371 return starExcludes; 8372 }; 8373 const getStarExcludesBlock = (starExcludes, t, { _, cnst, getObject, n }) => { 8374 if (starExcludes) { 8375 const fields = [...starExcludes].map(property => [ 8376 property, 8377 '1' 8378 ]); 8379 fields.unshift([null, `__proto__:${_}null`]); 8380 return `${n}${t}${cnst} _starExcludes${_}=${_}${getObject(fields, { 8381 lineBreakIndent: { base: t, t } 8382 })};`; 8383 } 8384 return ''; 8385 }; 8386 const getImportBindingsBlock = (importBindings, t, { _, n }) => (importBindings.length > 0 ? `${n}${t}var ${importBindings.join(`,${_}`)};` : ''); 8387 const getHoistedExportsBlock = (exports, t, snippets) => getExportsBlock(exports.filter(expt => expt.hoisted).map(expt => ({ name: expt.exported, value: expt.local })), t, snippets); 8388 function getExportsBlock(exports, t, { _, n }) { 8389 if (exports.length === 0) { 8390 return ''; 8391 } 8392 if (exports.length === 1) { 8393 return `exports(${JSON.stringify(exports[0].name)},${_}${exports[0].value});${n}${n}`; 8394 } 8395 return (`exports({${n}` + 8396 exports 8397 .map(({ name, value }) => `${t}${stringifyObjectKeyIfNeeded(name)}:${_}${value}`) 8398 .join(`,${n}`) + 8399 `${n}});${n}${n}`); 8400 } 8401 const getSyntheticExportsBlock = (exports, t, snippets) => getExportsBlock(exports 8402 .filter(expt => expt.expression) 8403 .map(expt => ({ name: expt.exported, value: expt.local })), t, snippets); 8404 const getMissingExportsBlock = (exports, t, snippets) => getExportsBlock(exports 8405 .filter(expt => expt.local === MISSING_EXPORT_SHIM_VARIABLE) 8406 .map(expt => ({ name: expt.exported, value: MISSING_EXPORT_SHIM_VARIABLE })), t, snippets); 8407 8408 function globalProperty(name, globalVariable, getPropertyAccess) { 8409 if (!name) 8410 return 'null'; 8411 return `${globalVariable}${keypath(name, getPropertyAccess)}`; 8412 } 8413 function safeAccess(name, globalVariable, { _, getPropertyAccess }) { 8414 let propertyPath = globalVariable; 8415 return name 8416 .split('.') 8417 .map(part => (propertyPath += getPropertyAccess(part))) 8418 .join(`${_}&&${_}`); 8419 } 8420 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 }) { 8421 const { _, cnst, getFunctionIntro, getNonArrowFunctionIntro, getPropertyAccess, n, s } = snippets; 8422 const factoryVariable = compact ? 'f' : 'factory'; 8423 const globalVariable = compact ? 'g' : 'global'; 8424 if (hasExports && !name) { 8425 return error(logMissingNameOptionForUmdExport()); 8426 } 8427 warnOnBuiltins(log, dependencies); 8428 const amdDeps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`); 8429 const cjsDeps = dependencies.map(m => `require('${m.importPath}')`); 8430 const trimmedImports = trimEmptyImports(dependencies); 8431 const globalDeps = trimmedImports.map(module => globalProperty(module.globalName, globalVariable, getPropertyAccess)); 8432 const factoryParameters = trimmedImports.map(m => m.name); 8433 if (namedExportsMode && (hasExports || noConflict)) { 8434 amdDeps.unshift(`'exports'`); 8435 cjsDeps.unshift(`exports`); 8436 globalDeps.unshift(assignToDeepVariable(name, globalVariable, globals, `${extend ? `${globalProperty(name, globalVariable, getPropertyAccess)}${_}||${_}` : ''}{}`, snippets, log)); 8437 factoryParameters.unshift('exports'); 8438 } 8439 const completeAmdId = getCompleteAmdId(amd, id); 8440 const amdParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) + 8441 (amdDeps.length > 0 ? `[${amdDeps.join(`,${_}`)}],${_}` : ``); 8442 const define = amd.define; 8443 const cjsExport = !namedExportsMode && hasExports ? `module.exports${_}=${_}` : ``; 8444 const useStrict = strict ? `${_}'use strict';${n}` : ``; 8445 let iifeExport; 8446 if (noConflict) { 8447 const noConflictExportsVariable = compact ? 'e' : 'exports'; 8448 let factory; 8449 if (!namedExportsMode && hasExports) { 8450 factory = `${cnst} ${noConflictExportsVariable}${_}=${_}${assignToDeepVariable(name, globalVariable, globals, `${factoryVariable}(${globalDeps.join(`,${_}`)})`, snippets, log)};`; 8451 } 8452 else { 8453 const module = globalDeps.shift(); 8454 factory = 8455 `${cnst} ${noConflictExportsVariable}${_}=${_}${module};${n}` + 8456 `${t}${t}${factoryVariable}(${[noConflictExportsVariable, ...globalDeps].join(`,${_}`)});`; 8457 } 8458 iifeExport = 8459 `(${getFunctionIntro([], { isAsync: false, name: null })}{${n}` + 8460 `${t}${t}${cnst} current${_}=${_}${safeAccess(name, globalVariable, snippets)};${n}` + 8461 `${t}${t}${factory}${n}` + 8462 `${t}${t}${noConflictExportsVariable}.noConflict${_}=${_}${getFunctionIntro([], { 8463 isAsync: false, 8464 name: null 8465 })}{${_}` + 8466 `${globalProperty(name, globalVariable, getPropertyAccess)}${_}=${_}current;${_}return ${noConflictExportsVariable}${s}${_}};${n}` + 8467 `${t}})()`; 8468 } 8469 else { 8470 iifeExport = `${factoryVariable}(${globalDeps.join(`,${_}`)})`; 8471 if (!namedExportsMode && hasExports) { 8472 iifeExport = assignToDeepVariable(name, globalVariable, globals, iifeExport, snippets, log); 8473 } 8474 } 8475 const iifeNeedsGlobal = hasExports || (noConflict && namedExportsMode) || globalDeps.length > 0; 8476 const wrapperParameters = [factoryVariable]; 8477 if (iifeNeedsGlobal) { 8478 wrapperParameters.unshift(globalVariable); 8479 } 8480 const globalArgument = iifeNeedsGlobal ? `this,${_}` : ''; 8481 const iifeStart = iifeNeedsGlobal 8482 ? `(${globalVariable}${_}=${_}typeof globalThis${_}!==${_}'undefined'${_}?${_}globalThis${_}:${_}${globalVariable}${_}||${_}self,${_}` 8483 : ''; 8484 const iifeEnd = iifeNeedsGlobal ? ')' : ''; 8485 const cjsIntro = iifeNeedsGlobal 8486 ? `${t}typeof exports${_}===${_}'object'${_}&&${_}typeof module${_}!==${_}'undefined'${_}?` + 8487 `${_}${cjsExport}${factoryVariable}(${cjsDeps.join(`,${_}`)})${_}:${n}` 8488 : ''; 8489 const wrapperIntro = `(${getNonArrowFunctionIntro(wrapperParameters, { isAsync: false, name: null })}{${n}` + 8490 cjsIntro + 8491 `${t}typeof ${define}${_}===${_}'function'${_}&&${_}${define}.amd${_}?${_}${define}(${amdParameters}${factoryVariable})${_}:${n}` + 8492 `${t}${iifeStart}${iifeExport}${iifeEnd};${n}` + 8493 // factory function should be wrapped by parentheses to avoid lazy parsing, 8494 // cf. https://v8.dev/blog/preparser#pife 8495 `})(${globalArgument}(${getNonArrowFunctionIntro(factoryParameters, { 8496 isAsync: false, 8497 name: null 8498 })}{${useStrict}${n}`; 8499 const wrapperOutro = n + n + '}));'; 8500 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`); 8501 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal); 8502 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets); 8503 if (namespaceMarkers) { 8504 namespaceMarkers = n + n + namespaceMarkers; 8505 } 8506 magicString 8507 .append(`${exportBlock}${namespaceMarkers}${outro}`) 8508 .trim() 8509 .indent(t) 8510 .append(wrapperOutro) 8511 .prepend(wrapperIntro); 8512 } 8513 8514 const finalisers = { amd, cjs, es, iife, system, umd }; 8515 8516 function getDefaultExportFromCjs (x) { 8517 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; 8518 } 8519 8520 function getAugmentedNamespace(n) { 8521 if (n.__esModule) return n; 8522 var f = n.default; 8523 if (typeof f == "function") { 8524 var a = function a () { 8525 if (this instanceof a) { 8526 return Reflect.construct(f, arguments, this.constructor); 8527 } 8528 return f.apply(this, arguments); 8529 }; 8530 a.prototype = f.prototype; 8531 } else a = {}; 8532 Object.defineProperty(a, '__esModule', {value: true}); 8533 Object.keys(n).forEach(function (k) { 8534 var d = Object.getOwnPropertyDescriptor(n, k); 8535 Object.defineProperty(a, k, d.get ? d : { 8536 enumerable: true, 8537 get: function () { 8538 return n[k]; 8539 } 8540 }); 8541 }); 8542 return a; 8543 } 8544 8545 var utils = {}; 8546 8547 var constants; 8548 var hasRequiredConstants; 8549 8550 function requireConstants () { 8551 if (hasRequiredConstants) return constants; 8552 hasRequiredConstants = 1; 8553 8554 const WIN_SLASH = '\\\\/'; 8555 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 8556 8557 /** 8558 * Posix glob regex 8559 */ 8560 8561 const DOT_LITERAL = '\\.'; 8562 const PLUS_LITERAL = '\\+'; 8563 const QMARK_LITERAL = '\\?'; 8564 const SLASH_LITERAL = '\\/'; 8565 const ONE_CHAR = '(?=.)'; 8566 const QMARK = '[^/]'; 8567 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 8568 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 8569 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 8570 const NO_DOT = `(?!${DOT_LITERAL})`; 8571 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 8572 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 8573 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 8574 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 8575 const STAR = `${QMARK}*?`; 8576 const SEP = '/'; 8577 8578 const POSIX_CHARS = { 8579 DOT_LITERAL, 8580 PLUS_LITERAL, 8581 QMARK_LITERAL, 8582 SLASH_LITERAL, 8583 ONE_CHAR, 8584 QMARK, 8585 END_ANCHOR, 8586 DOTS_SLASH, 8587 NO_DOT, 8588 NO_DOTS, 8589 NO_DOT_SLASH, 8590 NO_DOTS_SLASH, 8591 QMARK_NO_DOT, 8592 STAR, 8593 START_ANCHOR, 8594 SEP 8595 }; 8596 8597 /** 8598 * Windows glob regex 8599 */ 8600 8601 const WINDOWS_CHARS = { 8602 ...POSIX_CHARS, 8603 8604 SLASH_LITERAL: `[${WIN_SLASH}]`, 8605 QMARK: WIN_NO_SLASH, 8606 STAR: `${WIN_NO_SLASH}*?`, 8607 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, 8608 NO_DOT: `(?!${DOT_LITERAL})`, 8609 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 8610 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, 8611 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 8612 QMARK_NO_DOT: `[^.${WIN_SLASH}]`, 8613 START_ANCHOR: `(?:^|[${WIN_SLASH}])`, 8614 END_ANCHOR: `(?:[${WIN_SLASH}]|$)`, 8615 SEP: '\\' 8616 }; 8617 8618 /** 8619 * POSIX Bracket Regex 8620 */ 8621 8622 const POSIX_REGEX_SOURCE = { 8623 alnum: 'a-zA-Z0-9', 8624 alpha: 'a-zA-Z', 8625 ascii: '\\x00-\\x7F', 8626 blank: ' \\t', 8627 cntrl: '\\x00-\\x1F\\x7F', 8628 digit: '0-9', 8629 graph: '\\x21-\\x7E', 8630 lower: 'a-z', 8631 print: '\\x20-\\x7E ', 8632 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', 8633 space: ' \\t\\r\\n\\v\\f', 8634 upper: 'A-Z', 8635 word: 'A-Za-z0-9_', 8636 xdigit: 'A-Fa-f0-9' 8637 }; 8638 8639 constants = { 8640 MAX_LENGTH: 1024 * 64, 8641 POSIX_REGEX_SOURCE, 8642 8643 // regular expressions 8644 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, 8645 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, 8646 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, 8647 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, 8648 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, 8649 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, 8650 8651 // Replace globs with equivalent patterns to reduce parsing time. 8652 REPLACEMENTS: { 8653 '***': '*', 8654 '**/**': '**', 8655 '**/**/**': '**' 8656 }, 8657 8658 // Digits 8659 CHAR_0: 48, /* 0 */ 8660 CHAR_9: 57, /* 9 */ 8661 8662 // Alphabet chars. 8663 CHAR_UPPERCASE_A: 65, /* A */ 8664 CHAR_LOWERCASE_A: 97, /* a */ 8665 CHAR_UPPERCASE_Z: 90, /* Z */ 8666 CHAR_LOWERCASE_Z: 122, /* z */ 8667 8668 CHAR_LEFT_PARENTHESES: 40, /* ( */ 8669 CHAR_RIGHT_PARENTHESES: 41, /* ) */ 8670 8671 CHAR_ASTERISK: 42, /* * */ 8672 8673 // Non-alphabetic chars. 8674 CHAR_AMPERSAND: 38, /* & */ 8675 CHAR_AT: 64, /* @ */ 8676 CHAR_BACKWARD_SLASH: 92, /* \ */ 8677 CHAR_CARRIAGE_RETURN: 13, /* \r */ 8678 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ 8679 CHAR_COLON: 58, /* : */ 8680 CHAR_COMMA: 44, /* , */ 8681 CHAR_DOT: 46, /* . */ 8682 CHAR_DOUBLE_QUOTE: 34, /* " */ 8683 CHAR_EQUAL: 61, /* = */ 8684 CHAR_EXCLAMATION_MARK: 33, /* ! */ 8685 CHAR_FORM_FEED: 12, /* \f */ 8686 CHAR_FORWARD_SLASH: 47, /* / */ 8687 CHAR_GRAVE_ACCENT: 96, /* ` */ 8688 CHAR_HASH: 35, /* # */ 8689 CHAR_HYPHEN_MINUS: 45, /* - */ 8690 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ 8691 CHAR_LEFT_CURLY_BRACE: 123, /* { */ 8692 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ 8693 CHAR_LINE_FEED: 10, /* \n */ 8694 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ 8695 CHAR_PERCENT: 37, /* % */ 8696 CHAR_PLUS: 43, /* + */ 8697 CHAR_QUESTION_MARK: 63, /* ? */ 8698 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ 8699 CHAR_RIGHT_CURLY_BRACE: 125, /* } */ 8700 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ 8701 CHAR_SEMICOLON: 59, /* ; */ 8702 CHAR_SINGLE_QUOTE: 39, /* ' */ 8703 CHAR_SPACE: 32, /* */ 8704 CHAR_TAB: 9, /* \t */ 8705 CHAR_UNDERSCORE: 95, /* _ */ 8706 CHAR_VERTICAL_LINE: 124, /* | */ 8707 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ 8708 8709 /** 8710 * Create EXTGLOB_CHARS 8711 */ 8712 8713 extglobChars(chars) { 8714 return { 8715 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, 8716 '?': { type: 'qmark', open: '(?:', close: ')?' }, 8717 '+': { type: 'plus', open: '(?:', close: ')+' }, 8718 '*': { type: 'star', open: '(?:', close: ')*' }, 8719 '@': { type: 'at', open: '(?:', close: ')' } 8720 }; 8721 }, 8722 8723 /** 8724 * Create GLOB_CHARS 8725 */ 8726 8727 globChars(win32) { 8728 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; 8729 } 8730 }; 8731 return constants; 8732 } 8733 8734 /*global navigator*/ 8735 8736 var hasRequiredUtils; 8737 8738 function requireUtils () { 8739 if (hasRequiredUtils) return utils; 8740 hasRequiredUtils = 1; 8741 (function (exports) { 8742 8743 const { 8744 REGEX_BACKSLASH, 8745 REGEX_REMOVE_BACKSLASH, 8746 REGEX_SPECIAL_CHARS, 8747 REGEX_SPECIAL_CHARS_GLOBAL 8748 } = /*@__PURE__*/ requireConstants(); 8749 8750 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 8751 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); 8752 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); 8753 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); 8754 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); 8755 8756 exports.isWindows = () => { 8757 if (typeof navigator !== 'undefined' && navigator.platform) { 8758 const platform = navigator.platform.toLowerCase(); 8759 return platform === 'win32' || platform === 'windows'; 8760 } 8761 8762 if (typeof process !== 'undefined' && process.platform) { 8763 return process.platform === 'win32'; 8764 } 8765 8766 return false; 8767 }; 8768 8769 exports.removeBackslashes = str => { 8770 return str.replace(REGEX_REMOVE_BACKSLASH, match => { 8771 return match === '\\' ? '' : match; 8772 }); 8773 }; 8774 8775 exports.escapeLast = (input, char, lastIdx) => { 8776 const idx = input.lastIndexOf(char, lastIdx); 8777 if (idx === -1) return input; 8778 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); 8779 return `${input.slice(0, idx)}\\${input.slice(idx)}`; 8780 }; 8781 8782 exports.removePrefix = (input, state = {}) => { 8783 let output = input; 8784 if (output.startsWith('./')) { 8785 output = output.slice(2); 8786 state.prefix = './'; 8787 } 8788 return output; 8789 }; 8790 8791 exports.wrapOutput = (input, state = {}, options = {}) => { 8792 const prepend = options.contains ? '' : '^'; 8793 const append = options.contains ? '' : '$'; 8794 8795 let output = `${prepend}(?:${input})${append}`; 8796 if (state.negated === true) { 8797 output = `(?:^(?!${output}).*$)`; 8798 } 8799 return output; 8800 }; 8801 8802 exports.basename = (path, { windows } = {}) => { 8803 const segs = path.split(windows ? /[\\/]/ : '/'); 8804 const last = segs[segs.length - 1]; 8805 8806 if (last === '') { 8807 return segs[segs.length - 2]; 8808 } 8809 8810 return last; 8811 }; 8812 } (utils)); 8813 return utils; 8814 } 8815 8816 var scan_1; 8817 var hasRequiredScan; 8818 8819 function requireScan () { 8820 if (hasRequiredScan) return scan_1; 8821 hasRequiredScan = 1; 8822 8823 const utils = /*@__PURE__*/ requireUtils(); 8824 const { 8825 CHAR_ASTERISK, /* * */ 8826 CHAR_AT, /* @ */ 8827 CHAR_BACKWARD_SLASH, /* \ */ 8828 CHAR_COMMA, /* , */ 8829 CHAR_DOT, /* . */ 8830 CHAR_EXCLAMATION_MARK, /* ! */ 8831 CHAR_FORWARD_SLASH, /* / */ 8832 CHAR_LEFT_CURLY_BRACE, /* { */ 8833 CHAR_LEFT_PARENTHESES, /* ( */ 8834 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 8835 CHAR_PLUS, /* + */ 8836 CHAR_QUESTION_MARK, /* ? */ 8837 CHAR_RIGHT_CURLY_BRACE, /* } */ 8838 CHAR_RIGHT_PARENTHESES, /* ) */ 8839 CHAR_RIGHT_SQUARE_BRACKET /* ] */ 8840 } = /*@__PURE__*/ requireConstants(); 8841 8842 const isPathSeparator = code => { 8843 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; 8844 }; 8845 8846 const depth = token => { 8847 if (token.isPrefix !== true) { 8848 token.depth = token.isGlobstar ? Infinity : 1; 8849 } 8850 }; 8851 8852 /** 8853 * Quickly scans a glob pattern and returns an object with a handful of 8854 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), 8855 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not 8856 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). 8857 * 8858 * ```js 8859 * const pm = require('picomatch'); 8860 * console.log(pm.scan('foo/bar/*.js')); 8861 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } 8862 * ``` 8863 * @param {String} `str` 8864 * @param {Object} `options` 8865 * @return {Object} Returns an object with tokens and regex source string. 8866 * @api public 8867 */ 8868 8869 const scan = (input, options) => { 8870 const opts = options || {}; 8871 8872 const length = input.length - 1; 8873 const scanToEnd = opts.parts === true || opts.scanToEnd === true; 8874 const slashes = []; 8875 const tokens = []; 8876 const parts = []; 8877 8878 let str = input; 8879 let index = -1; 8880 let start = 0; 8881 let lastIndex = 0; 8882 let isBrace = false; 8883 let isBracket = false; 8884 let isGlob = false; 8885 let isExtglob = false; 8886 let isGlobstar = false; 8887 let braceEscaped = false; 8888 let backslashes = false; 8889 let negated = false; 8890 let negatedExtglob = false; 8891 let finished = false; 8892 let braces = 0; 8893 let prev; 8894 let code; 8895 let token = { value: '', depth: 0, isGlob: false }; 8896 8897 const eos = () => index >= length; 8898 const peek = () => str.charCodeAt(index + 1); 8899 const advance = () => { 8900 prev = code; 8901 return str.charCodeAt(++index); 8902 }; 8903 8904 while (index < length) { 8905 code = advance(); 8906 let next; 8907 8908 if (code === CHAR_BACKWARD_SLASH) { 8909 backslashes = token.backslashes = true; 8910 code = advance(); 8911 8912 if (code === CHAR_LEFT_CURLY_BRACE) { 8913 braceEscaped = true; 8914 } 8915 continue; 8916 } 8917 8918 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { 8919 braces++; 8920 8921 while (eos() !== true && (code = advance())) { 8922 if (code === CHAR_BACKWARD_SLASH) { 8923 backslashes = token.backslashes = true; 8924 advance(); 8925 continue; 8926 } 8927 8928 if (code === CHAR_LEFT_CURLY_BRACE) { 8929 braces++; 8930 continue; 8931 } 8932 8933 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { 8934 isBrace = token.isBrace = true; 8935 isGlob = token.isGlob = true; 8936 finished = true; 8937 8938 if (scanToEnd === true) { 8939 continue; 8940 } 8941 8942 break; 8943 } 8944 8945 if (braceEscaped !== true && code === CHAR_COMMA) { 8946 isBrace = token.isBrace = true; 8947 isGlob = token.isGlob = true; 8948 finished = true; 8949 8950 if (scanToEnd === true) { 8951 continue; 8952 } 8953 8954 break; 8955 } 8956 8957 if (code === CHAR_RIGHT_CURLY_BRACE) { 8958 braces--; 8959 8960 if (braces === 0) { 8961 braceEscaped = false; 8962 isBrace = token.isBrace = true; 8963 finished = true; 8964 break; 8965 } 8966 } 8967 } 8968 8969 if (scanToEnd === true) { 8970 continue; 8971 } 8972 8973 break; 8974 } 8975 8976 if (code === CHAR_FORWARD_SLASH) { 8977 slashes.push(index); 8978 tokens.push(token); 8979 token = { value: '', depth: 0, isGlob: false }; 8980 8981 if (finished === true) continue; 8982 if (prev === CHAR_DOT && index === (start + 1)) { 8983 start += 2; 8984 continue; 8985 } 8986 8987 lastIndex = index + 1; 8988 continue; 8989 } 8990 8991 if (opts.noext !== true) { 8992 const isExtglobChar = code === CHAR_PLUS 8993 || code === CHAR_AT 8994 || code === CHAR_ASTERISK 8995 || code === CHAR_QUESTION_MARK 8996 || code === CHAR_EXCLAMATION_MARK; 8997 8998 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { 8999 isGlob = token.isGlob = true; 9000 isExtglob = token.isExtglob = true; 9001 finished = true; 9002 if (code === CHAR_EXCLAMATION_MARK && index === start) { 9003 negatedExtglob = true; 9004 } 9005 9006 if (scanToEnd === true) { 9007 while (eos() !== true && (code = advance())) { 9008 if (code === CHAR_BACKWARD_SLASH) { 9009 backslashes = token.backslashes = true; 9010 code = advance(); 9011 continue; 9012 } 9013 9014 if (code === CHAR_RIGHT_PARENTHESES) { 9015 isGlob = token.isGlob = true; 9016 finished = true; 9017 break; 9018 } 9019 } 9020 continue; 9021 } 9022 break; 9023 } 9024 } 9025 9026 if (code === CHAR_ASTERISK) { 9027 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; 9028 isGlob = token.isGlob = true; 9029 finished = true; 9030 9031 if (scanToEnd === true) { 9032 continue; 9033 } 9034 break; 9035 } 9036 9037 if (code === CHAR_QUESTION_MARK) { 9038 isGlob = token.isGlob = true; 9039 finished = true; 9040 9041 if (scanToEnd === true) { 9042 continue; 9043 } 9044 break; 9045 } 9046 9047 if (code === CHAR_LEFT_SQUARE_BRACKET) { 9048 while (eos() !== true && (next = advance())) { 9049 if (next === CHAR_BACKWARD_SLASH) { 9050 backslashes = token.backslashes = true; 9051 advance(); 9052 continue; 9053 } 9054 9055 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 9056 isBracket = token.isBracket = true; 9057 isGlob = token.isGlob = true; 9058 finished = true; 9059 break; 9060 } 9061 } 9062 9063 if (scanToEnd === true) { 9064 continue; 9065 } 9066 9067 break; 9068 } 9069 9070 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { 9071 negated = token.negated = true; 9072 start++; 9073 continue; 9074 } 9075 9076 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { 9077 isGlob = token.isGlob = true; 9078 9079 if (scanToEnd === true) { 9080 while (eos() !== true && (code = advance())) { 9081 if (code === CHAR_LEFT_PARENTHESES) { 9082 backslashes = token.backslashes = true; 9083 code = advance(); 9084 continue; 9085 } 9086 9087 if (code === CHAR_RIGHT_PARENTHESES) { 9088 finished = true; 9089 break; 9090 } 9091 } 9092 continue; 9093 } 9094 break; 9095 } 9096 9097 if (isGlob === true) { 9098 finished = true; 9099 9100 if (scanToEnd === true) { 9101 continue; 9102 } 9103 9104 break; 9105 } 9106 } 9107 9108 if (opts.noext === true) { 9109 isExtglob = false; 9110 isGlob = false; 9111 } 9112 9113 let base = str; 9114 let prefix = ''; 9115 let glob = ''; 9116 9117 if (start > 0) { 9118 prefix = str.slice(0, start); 9119 str = str.slice(start); 9120 lastIndex -= start; 9121 } 9122 9123 if (base && isGlob === true && lastIndex > 0) { 9124 base = str.slice(0, lastIndex); 9125 glob = str.slice(lastIndex); 9126 } else if (isGlob === true) { 9127 base = ''; 9128 glob = str; 9129 } else { 9130 base = str; 9131 } 9132 9133 if (base && base !== '' && base !== '/' && base !== str) { 9134 if (isPathSeparator(base.charCodeAt(base.length - 1))) { 9135 base = base.slice(0, -1); 9136 } 9137 } 9138 9139 if (opts.unescape === true) { 9140 if (glob) glob = utils.removeBackslashes(glob); 9141 9142 if (base && backslashes === true) { 9143 base = utils.removeBackslashes(base); 9144 } 9145 } 9146 9147 const state = { 9148 prefix, 9149 input, 9150 start, 9151 base, 9152 glob, 9153 isBrace, 9154 isBracket, 9155 isGlob, 9156 isExtglob, 9157 isGlobstar, 9158 negated, 9159 negatedExtglob 9160 }; 9161 9162 if (opts.tokens === true) { 9163 state.maxDepth = 0; 9164 if (!isPathSeparator(code)) { 9165 tokens.push(token); 9166 } 9167 state.tokens = tokens; 9168 } 9169 9170 if (opts.parts === true || opts.tokens === true) { 9171 let prevIndex; 9172 9173 for (let idx = 0; idx < slashes.length; idx++) { 9174 const n = prevIndex ? prevIndex + 1 : start; 9175 const i = slashes[idx]; 9176 const value = input.slice(n, i); 9177 if (opts.tokens) { 9178 if (idx === 0 && start !== 0) { 9179 tokens[idx].isPrefix = true; 9180 tokens[idx].value = prefix; 9181 } else { 9182 tokens[idx].value = value; 9183 } 9184 depth(tokens[idx]); 9185 state.maxDepth += tokens[idx].depth; 9186 } 9187 if (idx !== 0 || value !== '') { 9188 parts.push(value); 9189 } 9190 prevIndex = i; 9191 } 9192 9193 if (prevIndex && prevIndex + 1 < input.length) { 9194 const value = input.slice(prevIndex + 1); 9195 parts.push(value); 9196 9197 if (opts.tokens) { 9198 tokens[tokens.length - 1].value = value; 9199 depth(tokens[tokens.length - 1]); 9200 state.maxDepth += tokens[tokens.length - 1].depth; 9201 } 9202 } 9203 9204 state.slashes = slashes; 9205 state.parts = parts; 9206 } 9207 9208 return state; 9209 }; 9210 9211 scan_1 = scan; 9212 return scan_1; 9213 } 9214 9215 var parse_1; 9216 var hasRequiredParse; 9217 9218 function requireParse () { 9219 if (hasRequiredParse) return parse_1; 9220 hasRequiredParse = 1; 9221 9222 const constants = /*@__PURE__*/ requireConstants(); 9223 const utils = /*@__PURE__*/ requireUtils(); 9224 9225 /** 9226 * Constants 9227 */ 9228 9229 const { 9230 MAX_LENGTH, 9231 POSIX_REGEX_SOURCE, 9232 REGEX_NON_SPECIAL_CHARS, 9233 REGEX_SPECIAL_CHARS_BACKREF, 9234 REPLACEMENTS 9235 } = constants; 9236 9237 /** 9238 * Helpers 9239 */ 9240 9241 const expandRange = (args, options) => { 9242 if (typeof options.expandRange === 'function') { 9243 return options.expandRange(...args, options); 9244 } 9245 9246 args.sort(); 9247 const value = `[${args.join('-')}]`; 9248 9249 return value; 9250 }; 9251 9252 /** 9253 * Create the message for a syntax error 9254 */ 9255 9256 const syntaxError = (type, char) => { 9257 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; 9258 }; 9259 9260 /** 9261 * Parse the given input string. 9262 * @param {String} input 9263 * @param {Object} options 9264 * @return {Object} 9265 */ 9266 9267 const parse = (input, options) => { 9268 if (typeof input !== 'string') { 9269 throw new TypeError('Expected a string'); 9270 } 9271 9272 input = REPLACEMENTS[input] || input; 9273 9274 const opts = { ...options }; 9275 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 9276 9277 let len = input.length; 9278 if (len > max) { 9279 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 9280 } 9281 9282 const bos = { type: 'bos', value: '', output: opts.prepend || '' }; 9283 const tokens = [bos]; 9284 9285 const capture = opts.capture ? '' : '?:'; 9286 9287 // create constants based on platform, for windows or posix 9288 const PLATFORM_CHARS = constants.globChars(opts.windows); 9289 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); 9290 9291 const { 9292 DOT_LITERAL, 9293 PLUS_LITERAL, 9294 SLASH_LITERAL, 9295 ONE_CHAR, 9296 DOTS_SLASH, 9297 NO_DOT, 9298 NO_DOT_SLASH, 9299 NO_DOTS_SLASH, 9300 QMARK, 9301 QMARK_NO_DOT, 9302 STAR, 9303 START_ANCHOR 9304 } = PLATFORM_CHARS; 9305 9306 const globstar = opts => { 9307 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 9308 }; 9309 9310 const nodot = opts.dot ? '' : NO_DOT; 9311 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; 9312 let star = opts.bash === true ? globstar(opts) : STAR; 9313 9314 if (opts.capture) { 9315 star = `(${star})`; 9316 } 9317 9318 // minimatch options support 9319 if (typeof opts.noext === 'boolean') { 9320 opts.noextglob = opts.noext; 9321 } 9322 9323 const state = { 9324 input, 9325 index: -1, 9326 start: 0, 9327 dot: opts.dot === true, 9328 consumed: '', 9329 output: '', 9330 prefix: '', 9331 backtrack: false, 9332 negated: false, 9333 brackets: 0, 9334 braces: 0, 9335 parens: 0, 9336 quotes: 0, 9337 globstar: false, 9338 tokens 9339 }; 9340 9341 input = utils.removePrefix(input, state); 9342 len = input.length; 9343 9344 const extglobs = []; 9345 const braces = []; 9346 const stack = []; 9347 let prev = bos; 9348 let value; 9349 9350 /** 9351 * Tokenizing helpers 9352 */ 9353 9354 const eos = () => state.index === len - 1; 9355 const peek = state.peek = (n = 1) => input[state.index + n]; 9356 const advance = state.advance = () => input[++state.index] || ''; 9357 const remaining = () => input.slice(state.index + 1); 9358 const consume = (value = '', num = 0) => { 9359 state.consumed += value; 9360 state.index += num; 9361 }; 9362 9363 const append = token => { 9364 state.output += token.output != null ? token.output : token.value; 9365 consume(token.value); 9366 }; 9367 9368 const negate = () => { 9369 let count = 1; 9370 9371 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { 9372 advance(); 9373 state.start++; 9374 count++; 9375 } 9376 9377 if (count % 2 === 0) { 9378 return false; 9379 } 9380 9381 state.negated = true; 9382 state.start++; 9383 return true; 9384 }; 9385 9386 const increment = type => { 9387 state[type]++; 9388 stack.push(type); 9389 }; 9390 9391 const decrement = type => { 9392 state[type]--; 9393 stack.pop(); 9394 }; 9395 9396 /** 9397 * Push tokens onto the tokens array. This helper speeds up 9398 * tokenizing by 1) helping us avoid backtracking as much as possible, 9399 * and 2) helping us avoid creating extra tokens when consecutive 9400 * characters are plain text. This improves performance and simplifies 9401 * lookbehinds. 9402 */ 9403 9404 const push = tok => { 9405 if (prev.type === 'globstar') { 9406 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); 9407 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); 9408 9409 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { 9410 state.output = state.output.slice(0, -prev.output.length); 9411 prev.type = 'star'; 9412 prev.value = '*'; 9413 prev.output = star; 9414 state.output += prev.output; 9415 } 9416 } 9417 9418 if (extglobs.length && tok.type !== 'paren') { 9419 extglobs[extglobs.length - 1].inner += tok.value; 9420 } 9421 9422 if (tok.value || tok.output) append(tok); 9423 if (prev && prev.type === 'text' && tok.type === 'text') { 9424 prev.output = (prev.output || prev.value) + tok.value; 9425 prev.value += tok.value; 9426 return; 9427 } 9428 9429 tok.prev = prev; 9430 tokens.push(tok); 9431 prev = tok; 9432 }; 9433 9434 const extglobOpen = (type, value) => { 9435 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; 9436 9437 token.prev = prev; 9438 token.parens = state.parens; 9439 token.output = state.output; 9440 const output = (opts.capture ? '(' : '') + token.open; 9441 9442 increment('parens'); 9443 push({ type, value, output: state.output ? '' : ONE_CHAR }); 9444 push({ type: 'paren', extglob: true, value: advance(), output }); 9445 extglobs.push(token); 9446 }; 9447 9448 const extglobClose = token => { 9449 let output = token.close + (opts.capture ? ')' : ''); 9450 let rest; 9451 9452 if (token.type === 'negate') { 9453 let extglobStar = star; 9454 9455 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { 9456 extglobStar = globstar(opts); 9457 } 9458 9459 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { 9460 output = token.close = `)$))${extglobStar}`; 9461 } 9462 9463 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { 9464 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. 9465 // In this case, we need to parse the string and use it in the output of the original pattern. 9466 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. 9467 // 9468 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. 9469 const expression = parse(rest, { ...options, fastpaths: false }).output; 9470 9471 output = token.close = `)${expression})${extglobStar})`; 9472 } 9473 9474 if (token.prev.type === 'bos') { 9475 state.negatedExtglob = true; 9476 } 9477 } 9478 9479 push({ type: 'paren', extglob: true, value, output }); 9480 decrement('parens'); 9481 }; 9482 9483 /** 9484 * Fast paths 9485 */ 9486 9487 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { 9488 let backslashes = false; 9489 9490 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { 9491 if (first === '\\') { 9492 backslashes = true; 9493 return m; 9494 } 9495 9496 if (first === '?') { 9497 if (esc) { 9498 return esc + first + (rest ? QMARK.repeat(rest.length) : ''); 9499 } 9500 if (index === 0) { 9501 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); 9502 } 9503 return QMARK.repeat(chars.length); 9504 } 9505 9506 if (first === '.') { 9507 return DOT_LITERAL.repeat(chars.length); 9508 } 9509 9510 if (first === '*') { 9511 if (esc) { 9512 return esc + first + (rest ? star : ''); 9513 } 9514 return star; 9515 } 9516 return esc ? m : `\\${m}`; 9517 }); 9518 9519 if (backslashes === true) { 9520 if (opts.unescape === true) { 9521 output = output.replace(/\\/g, ''); 9522 } else { 9523 output = output.replace(/\\+/g, m => { 9524 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); 9525 }); 9526 } 9527 } 9528 9529 if (output === input && opts.contains === true) { 9530 state.output = input; 9531 return state; 9532 } 9533 9534 state.output = utils.wrapOutput(output, state, options); 9535 return state; 9536 } 9537 9538 /** 9539 * Tokenize input until we reach end-of-string 9540 */ 9541 9542 while (!eos()) { 9543 value = advance(); 9544 9545 if (value === '\u0000') { 9546 continue; 9547 } 9548 9549 /** 9550 * Escaped characters 9551 */ 9552 9553 if (value === '\\') { 9554 const next = peek(); 9555 9556 if (next === '/' && opts.bash !== true) { 9557 continue; 9558 } 9559 9560 if (next === '.' || next === ';') { 9561 continue; 9562 } 9563 9564 if (!next) { 9565 value += '\\'; 9566 push({ type: 'text', value }); 9567 continue; 9568 } 9569 9570 // collapse slashes to reduce potential for exploits 9571 const match = /^\\+/.exec(remaining()); 9572 let slashes = 0; 9573 9574 if (match && match[0].length > 2) { 9575 slashes = match[0].length; 9576 state.index += slashes; 9577 if (slashes % 2 !== 0) { 9578 value += '\\'; 9579 } 9580 } 9581 9582 if (opts.unescape === true) { 9583 value = advance(); 9584 } else { 9585 value += advance(); 9586 } 9587 9588 if (state.brackets === 0) { 9589 push({ type: 'text', value }); 9590 continue; 9591 } 9592 } 9593 9594 /** 9595 * If we're inside a regex character class, continue 9596 * until we reach the closing bracket. 9597 */ 9598 9599 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { 9600 if (opts.posix !== false && value === ':') { 9601 const inner = prev.value.slice(1); 9602 if (inner.includes('[')) { 9603 prev.posix = true; 9604 9605 if (inner.includes(':')) { 9606 const idx = prev.value.lastIndexOf('['); 9607 const pre = prev.value.slice(0, idx); 9608 const rest = prev.value.slice(idx + 2); 9609 const posix = POSIX_REGEX_SOURCE[rest]; 9610 if (posix) { 9611 prev.value = pre + posix; 9612 state.backtrack = true; 9613 advance(); 9614 9615 if (!bos.output && tokens.indexOf(prev) === 1) { 9616 bos.output = ONE_CHAR; 9617 } 9618 continue; 9619 } 9620 } 9621 } 9622 } 9623 9624 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { 9625 value = `\\${value}`; 9626 } 9627 9628 if (value === ']' && (prev.value === '[' || prev.value === '[^')) { 9629 value = `\\${value}`; 9630 } 9631 9632 if (opts.posix === true && value === '!' && prev.value === '[') { 9633 value = '^'; 9634 } 9635 9636 prev.value += value; 9637 append({ value }); 9638 continue; 9639 } 9640 9641 /** 9642 * If we're inside a quoted string, continue 9643 * until we reach the closing double quote. 9644 */ 9645 9646 if (state.quotes === 1 && value !== '"') { 9647 value = utils.escapeRegex(value); 9648 prev.value += value; 9649 append({ value }); 9650 continue; 9651 } 9652 9653 /** 9654 * Double quotes 9655 */ 9656 9657 if (value === '"') { 9658 state.quotes = state.quotes === 1 ? 0 : 1; 9659 if (opts.keepQuotes === true) { 9660 push({ type: 'text', value }); 9661 } 9662 continue; 9663 } 9664 9665 /** 9666 * Parentheses 9667 */ 9668 9669 if (value === '(') { 9670 increment('parens'); 9671 push({ type: 'paren', value }); 9672 continue; 9673 } 9674 9675 if (value === ')') { 9676 if (state.parens === 0 && opts.strictBrackets === true) { 9677 throw new SyntaxError(syntaxError('opening', '(')); 9678 } 9679 9680 const extglob = extglobs[extglobs.length - 1]; 9681 if (extglob && state.parens === extglob.parens + 1) { 9682 extglobClose(extglobs.pop()); 9683 continue; 9684 } 9685 9686 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); 9687 decrement('parens'); 9688 continue; 9689 } 9690 9691 /** 9692 * Square brackets 9693 */ 9694 9695 if (value === '[') { 9696 if (opts.nobracket === true || !remaining().includes(']')) { 9697 if (opts.nobracket !== true && opts.strictBrackets === true) { 9698 throw new SyntaxError(syntaxError('closing', ']')); 9699 } 9700 9701 value = `\\${value}`; 9702 } else { 9703 increment('brackets'); 9704 } 9705 9706 push({ type: 'bracket', value }); 9707 continue; 9708 } 9709 9710 if (value === ']') { 9711 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { 9712 push({ type: 'text', value, output: `\\${value}` }); 9713 continue; 9714 } 9715 9716 if (state.brackets === 0) { 9717 if (opts.strictBrackets === true) { 9718 throw new SyntaxError(syntaxError('opening', '[')); 9719 } 9720 9721 push({ type: 'text', value, output: `\\${value}` }); 9722 continue; 9723 } 9724 9725 decrement('brackets'); 9726 9727 const prevValue = prev.value.slice(1); 9728 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { 9729 value = `/${value}`; 9730 } 9731 9732 prev.value += value; 9733 append({ value }); 9734 9735 // when literal brackets are explicitly disabled 9736 // assume we should match with a regex character class 9737 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { 9738 continue; 9739 } 9740 9741 const escaped = utils.escapeRegex(prev.value); 9742 state.output = state.output.slice(0, -prev.value.length); 9743 9744 // when literal brackets are explicitly enabled 9745 // assume we should escape the brackets to match literal characters 9746 if (opts.literalBrackets === true) { 9747 state.output += escaped; 9748 prev.value = escaped; 9749 continue; 9750 } 9751 9752 // when the user specifies nothing, try to match both 9753 prev.value = `(${capture}${escaped}|${prev.value})`; 9754 state.output += prev.value; 9755 continue; 9756 } 9757 9758 /** 9759 * Braces 9760 */ 9761 9762 if (value === '{' && opts.nobrace !== true) { 9763 increment('braces'); 9764 9765 const open = { 9766 type: 'brace', 9767 value, 9768 output: '(', 9769 outputIndex: state.output.length, 9770 tokensIndex: state.tokens.length 9771 }; 9772 9773 braces.push(open); 9774 push(open); 9775 continue; 9776 } 9777 9778 if (value === '}') { 9779 const brace = braces[braces.length - 1]; 9780 9781 if (opts.nobrace === true || !brace) { 9782 push({ type: 'text', value, output: value }); 9783 continue; 9784 } 9785 9786 let output = ')'; 9787 9788 if (brace.dots === true) { 9789 const arr = tokens.slice(); 9790 const range = []; 9791 9792 for (let i = arr.length - 1; i >= 0; i--) { 9793 tokens.pop(); 9794 if (arr[i].type === 'brace') { 9795 break; 9796 } 9797 if (arr[i].type !== 'dots') { 9798 range.unshift(arr[i].value); 9799 } 9800 } 9801 9802 output = expandRange(range, opts); 9803 state.backtrack = true; 9804 } 9805 9806 if (brace.comma !== true && brace.dots !== true) { 9807 const out = state.output.slice(0, brace.outputIndex); 9808 const toks = state.tokens.slice(brace.tokensIndex); 9809 brace.value = brace.output = '\\{'; 9810 value = output = '\\}'; 9811 state.output = out; 9812 for (const t of toks) { 9813 state.output += (t.output || t.value); 9814 } 9815 } 9816 9817 push({ type: 'brace', value, output }); 9818 decrement('braces'); 9819 braces.pop(); 9820 continue; 9821 } 9822 9823 /** 9824 * Pipes 9825 */ 9826 9827 if (value === '|') { 9828 if (extglobs.length > 0) { 9829 extglobs[extglobs.length - 1].conditions++; 9830 } 9831 push({ type: 'text', value }); 9832 continue; 9833 } 9834 9835 /** 9836 * Commas 9837 */ 9838 9839 if (value === ',') { 9840 let output = value; 9841 9842 const brace = braces[braces.length - 1]; 9843 if (brace && stack[stack.length - 1] === 'braces') { 9844 brace.comma = true; 9845 output = '|'; 9846 } 9847 9848 push({ type: 'comma', value, output }); 9849 continue; 9850 } 9851 9852 /** 9853 * Slashes 9854 */ 9855 9856 if (value === '/') { 9857 // if the beginning of the glob is "./", advance the start 9858 // to the current index, and don't add the "./" characters 9859 // to the state. This greatly simplifies lookbehinds when 9860 // checking for BOS characters like "!" and "." (not "./") 9861 if (prev.type === 'dot' && state.index === state.start + 1) { 9862 state.start = state.index + 1; 9863 state.consumed = ''; 9864 state.output = ''; 9865 tokens.pop(); 9866 prev = bos; // reset "prev" to the first token 9867 continue; 9868 } 9869 9870 push({ type: 'slash', value, output: SLASH_LITERAL }); 9871 continue; 9872 } 9873 9874 /** 9875 * Dots 9876 */ 9877 9878 if (value === '.') { 9879 if (state.braces > 0 && prev.type === 'dot') { 9880 if (prev.value === '.') prev.output = DOT_LITERAL; 9881 const brace = braces[braces.length - 1]; 9882 prev.type = 'dots'; 9883 prev.output += value; 9884 prev.value += value; 9885 brace.dots = true; 9886 continue; 9887 } 9888 9889 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { 9890 push({ type: 'text', value, output: DOT_LITERAL }); 9891 continue; 9892 } 9893 9894 push({ type: 'dot', value, output: DOT_LITERAL }); 9895 continue; 9896 } 9897 9898 /** 9899 * Question marks 9900 */ 9901 9902 if (value === '?') { 9903 const isGroup = prev && prev.value === '('; 9904 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 9905 extglobOpen('qmark', value); 9906 continue; 9907 } 9908 9909 if (prev && prev.type === 'paren') { 9910 const next = peek(); 9911 let output = value; 9912 9913 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { 9914 output = `\\${value}`; 9915 } 9916 9917 push({ type: 'text', value, output }); 9918 continue; 9919 } 9920 9921 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { 9922 push({ type: 'qmark', value, output: QMARK_NO_DOT }); 9923 continue; 9924 } 9925 9926 push({ type: 'qmark', value, output: QMARK }); 9927 continue; 9928 } 9929 9930 /** 9931 * Exclamation 9932 */ 9933 9934 if (value === '!') { 9935 if (opts.noextglob !== true && peek() === '(') { 9936 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { 9937 extglobOpen('negate', value); 9938 continue; 9939 } 9940 } 9941 9942 if (opts.nonegate !== true && state.index === 0) { 9943 negate(); 9944 continue; 9945 } 9946 } 9947 9948 /** 9949 * Plus 9950 */ 9951 9952 if (value === '+') { 9953 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 9954 extglobOpen('plus', value); 9955 continue; 9956 } 9957 9958 if ((prev && prev.value === '(') || opts.regex === false) { 9959 push({ type: 'plus', value, output: PLUS_LITERAL }); 9960 continue; 9961 } 9962 9963 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { 9964 push({ type: 'plus', value }); 9965 continue; 9966 } 9967 9968 push({ type: 'plus', value: PLUS_LITERAL }); 9969 continue; 9970 } 9971 9972 /** 9973 * Plain text 9974 */ 9975 9976 if (value === '@') { 9977 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 9978 push({ type: 'at', extglob: true, value, output: '' }); 9979 continue; 9980 } 9981 9982 push({ type: 'text', value }); 9983 continue; 9984 } 9985 9986 /** 9987 * Plain text 9988 */ 9989 9990 if (value !== '*') { 9991 if (value === '$' || value === '^') { 9992 value = `\\${value}`; 9993 } 9994 9995 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); 9996 if (match) { 9997 value += match[0]; 9998 state.index += match[0].length; 9999 } 10000 10001 push({ type: 'text', value }); 10002 continue; 10003 } 10004 10005 /** 10006 * Stars 10007 */ 10008 10009 if (prev && (prev.type === 'globstar' || prev.star === true)) { 10010 prev.type = 'star'; 10011 prev.star = true; 10012 prev.value += value; 10013 prev.output = star; 10014 state.backtrack = true; 10015 state.globstar = true; 10016 consume(value); 10017 continue; 10018 } 10019 10020 let rest = remaining(); 10021 if (opts.noextglob !== true && /^\([^?]/.test(rest)) { 10022 extglobOpen('star', value); 10023 continue; 10024 } 10025 10026 if (prev.type === 'star') { 10027 if (opts.noglobstar === true) { 10028 consume(value); 10029 continue; 10030 } 10031 10032 const prior = prev.prev; 10033 const before = prior.prev; 10034 const isStart = prior.type === 'slash' || prior.type === 'bos'; 10035 const afterStar = before && (before.type === 'star' || before.type === 'globstar'); 10036 10037 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { 10038 push({ type: 'star', value, output: '' }); 10039 continue; 10040 } 10041 10042 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); 10043 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); 10044 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { 10045 push({ type: 'star', value, output: '' }); 10046 continue; 10047 } 10048 10049 // strip consecutive `/**/` 10050 while (rest.slice(0, 3) === '/**') { 10051 const after = input[state.index + 4]; 10052 if (after && after !== '/') { 10053 break; 10054 } 10055 rest = rest.slice(3); 10056 consume('/**', 3); 10057 } 10058 10059 if (prior.type === 'bos' && eos()) { 10060 prev.type = 'globstar'; 10061 prev.value += value; 10062 prev.output = globstar(opts); 10063 state.output = prev.output; 10064 state.globstar = true; 10065 consume(value); 10066 continue; 10067 } 10068 10069 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { 10070 state.output = state.output.slice(0, -(prior.output + prev.output).length); 10071 prior.output = `(?:${prior.output}`; 10072 10073 prev.type = 'globstar'; 10074 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); 10075 prev.value += value; 10076 state.globstar = true; 10077 state.output += prior.output + prev.output; 10078 consume(value); 10079 continue; 10080 } 10081 10082 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { 10083 const end = rest[1] !== void 0 ? '|$' : ''; 10084 10085 state.output = state.output.slice(0, -(prior.output + prev.output).length); 10086 prior.output = `(?:${prior.output}`; 10087 10088 prev.type = 'globstar'; 10089 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; 10090 prev.value += value; 10091 10092 state.output += prior.output + prev.output; 10093 state.globstar = true; 10094 10095 consume(value + advance()); 10096 10097 push({ type: 'slash', value: '/', output: '' }); 10098 continue; 10099 } 10100 10101 if (prior.type === 'bos' && rest[0] === '/') { 10102 prev.type = 'globstar'; 10103 prev.value += value; 10104 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; 10105 state.output = prev.output; 10106 state.globstar = true; 10107 consume(value + advance()); 10108 push({ type: 'slash', value: '/', output: '' }); 10109 continue; 10110 } 10111 10112 // remove single star from output 10113 state.output = state.output.slice(0, -prev.output.length); 10114 10115 // reset previous token to globstar 10116 prev.type = 'globstar'; 10117 prev.output = globstar(opts); 10118 prev.value += value; 10119 10120 // reset output with globstar 10121 state.output += prev.output; 10122 state.globstar = true; 10123 consume(value); 10124 continue; 10125 } 10126 10127 const token = { type: 'star', value, output: star }; 10128 10129 if (opts.bash === true) { 10130 token.output = '.*?'; 10131 if (prev.type === 'bos' || prev.type === 'slash') { 10132 token.output = nodot + token.output; 10133 } 10134 push(token); 10135 continue; 10136 } 10137 10138 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { 10139 token.output = value; 10140 push(token); 10141 continue; 10142 } 10143 10144 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { 10145 if (prev.type === 'dot') { 10146 state.output += NO_DOT_SLASH; 10147 prev.output += NO_DOT_SLASH; 10148 10149 } else if (opts.dot === true) { 10150 state.output += NO_DOTS_SLASH; 10151 prev.output += NO_DOTS_SLASH; 10152 10153 } else { 10154 state.output += nodot; 10155 prev.output += nodot; 10156 } 10157 10158 if (peek() !== '*') { 10159 state.output += ONE_CHAR; 10160 prev.output += ONE_CHAR; 10161 } 10162 } 10163 10164 push(token); 10165 } 10166 10167 while (state.brackets > 0) { 10168 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); 10169 state.output = utils.escapeLast(state.output, '['); 10170 decrement('brackets'); 10171 } 10172 10173 while (state.parens > 0) { 10174 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); 10175 state.output = utils.escapeLast(state.output, '('); 10176 decrement('parens'); 10177 } 10178 10179 while (state.braces > 0) { 10180 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); 10181 state.output = utils.escapeLast(state.output, '{'); 10182 decrement('braces'); 10183 } 10184 10185 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { 10186 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); 10187 } 10188 10189 // rebuild the output if we had to backtrack at any point 10190 if (state.backtrack === true) { 10191 state.output = ''; 10192 10193 for (const token of state.tokens) { 10194 state.output += token.output != null ? token.output : token.value; 10195 10196 if (token.suffix) { 10197 state.output += token.suffix; 10198 } 10199 } 10200 } 10201 10202 return state; 10203 }; 10204 10205 /** 10206 * Fast paths for creating regular expressions for common glob patterns. 10207 * This can significantly speed up processing and has very little downside 10208 * impact when none of the fast paths match. 10209 */ 10210 10211 parse.fastpaths = (input, options) => { 10212 const opts = { ...options }; 10213 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 10214 const len = input.length; 10215 if (len > max) { 10216 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 10217 } 10218 10219 input = REPLACEMENTS[input] || input; 10220 10221 // create constants based on platform, for windows or posix 10222 const { 10223 DOT_LITERAL, 10224 SLASH_LITERAL, 10225 ONE_CHAR, 10226 DOTS_SLASH, 10227 NO_DOT, 10228 NO_DOTS, 10229 NO_DOTS_SLASH, 10230 STAR, 10231 START_ANCHOR 10232 } = constants.globChars(opts.windows); 10233 10234 const nodot = opts.dot ? NO_DOTS : NO_DOT; 10235 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; 10236 const capture = opts.capture ? '' : '?:'; 10237 const state = { negated: false, prefix: '' }; 10238 let star = opts.bash === true ? '.*?' : STAR; 10239 10240 if (opts.capture) { 10241 star = `(${star})`; 10242 } 10243 10244 const globstar = opts => { 10245 if (opts.noglobstar === true) return star; 10246 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 10247 }; 10248 10249 const create = str => { 10250 switch (str) { 10251 case '*': 10252 return `${nodot}${ONE_CHAR}${star}`; 10253 10254 case '.*': 10255 return `${DOT_LITERAL}${ONE_CHAR}${star}`; 10256 10257 case '*.*': 10258 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 10259 10260 case '*/*': 10261 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; 10262 10263 case '**': 10264 return nodot + globstar(opts); 10265 10266 case '**/*': 10267 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; 10268 10269 case '**/*.*': 10270 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 10271 10272 case '**/.*': 10273 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; 10274 10275 default: { 10276 const match = /^(.*?)\.(\w+)$/.exec(str); 10277 if (!match) return; 10278 10279 const source = create(match[1]); 10280 if (!source) return; 10281 10282 return source + DOT_LITERAL + match[2]; 10283 } 10284 } 10285 }; 10286 10287 const output = utils.removePrefix(input, state); 10288 let source = create(output); 10289 10290 if (source && opts.strictSlashes !== true) { 10291 source += `${SLASH_LITERAL}?`; 10292 } 10293 10294 return source; 10295 }; 10296 10297 parse_1 = parse; 10298 return parse_1; 10299 } 10300 10301 var picomatch_1$1; 10302 var hasRequiredPicomatch$1; 10303 10304 function requirePicomatch$1 () { 10305 if (hasRequiredPicomatch$1) return picomatch_1$1; 10306 hasRequiredPicomatch$1 = 1; 10307 10308 const scan = /*@__PURE__*/ requireScan(); 10309 const parse = /*@__PURE__*/ requireParse(); 10310 const utils = /*@__PURE__*/ requireUtils(); 10311 const constants = /*@__PURE__*/ requireConstants(); 10312 const isObject = val => val && typeof val === 'object' && !Array.isArray(val); 10313 10314 /** 10315 * Creates a matcher function from one or more glob patterns. The 10316 * returned function takes a string to match as its first argument, 10317 * and returns true if the string is a match. The returned matcher 10318 * function also takes a boolean as the second argument that, when true, 10319 * returns an object with additional information. 10320 * 10321 * ```js 10322 * const picomatch = require('picomatch'); 10323 * // picomatch(glob[, options]); 10324 * 10325 * const isMatch = picomatch('*.!(*a)'); 10326 * console.log(isMatch('a.a')); //=> false 10327 * console.log(isMatch('a.b')); //=> true 10328 * ``` 10329 * @name picomatch 10330 * @param {String|Array} `globs` One or more glob patterns. 10331 * @param {Object=} `options` 10332 * @return {Function=} Returns a matcher function. 10333 * @api public 10334 */ 10335 10336 const picomatch = (glob, options, returnState = false) => { 10337 if (Array.isArray(glob)) { 10338 const fns = glob.map(input => picomatch(input, options, returnState)); 10339 const arrayMatcher = str => { 10340 for (const isMatch of fns) { 10341 const state = isMatch(str); 10342 if (state) return state; 10343 } 10344 return false; 10345 }; 10346 return arrayMatcher; 10347 } 10348 10349 const isState = isObject(glob) && glob.tokens && glob.input; 10350 10351 if (glob === '' || (typeof glob !== 'string' && !isState)) { 10352 throw new TypeError('Expected pattern to be a non-empty string'); 10353 } 10354 10355 const opts = options || {}; 10356 const posix = opts.windows; 10357 const regex = isState 10358 ? picomatch.compileRe(glob, options) 10359 : picomatch.makeRe(glob, options, false, true); 10360 10361 const state = regex.state; 10362 delete regex.state; 10363 10364 let isIgnored = () => false; 10365 if (opts.ignore) { 10366 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; 10367 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); 10368 } 10369 10370 const matcher = (input, returnObject = false) => { 10371 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); 10372 const result = { glob, state, regex, posix, input, output, match, isMatch }; 10373 10374 if (typeof opts.onResult === 'function') { 10375 opts.onResult(result); 10376 } 10377 10378 if (isMatch === false) { 10379 result.isMatch = false; 10380 return returnObject ? result : false; 10381 } 10382 10383 if (isIgnored(input)) { 10384 if (typeof opts.onIgnore === 'function') { 10385 opts.onIgnore(result); 10386 } 10387 result.isMatch = false; 10388 return returnObject ? result : false; 10389 } 10390 10391 if (typeof opts.onMatch === 'function') { 10392 opts.onMatch(result); 10393 } 10394 return returnObject ? result : true; 10395 }; 10396 10397 if (returnState) { 10398 matcher.state = state; 10399 } 10400 10401 return matcher; 10402 }; 10403 10404 /** 10405 * Test `input` with the given `regex`. This is used by the main 10406 * `picomatch()` function to test the input string. 10407 * 10408 * ```js 10409 * const picomatch = require('picomatch'); 10410 * // picomatch.test(input, regex[, options]); 10411 * 10412 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); 10413 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } 10414 * ``` 10415 * @param {String} `input` String to test. 10416 * @param {RegExp} `regex` 10417 * @return {Object} Returns an object with matching info. 10418 * @api public 10419 */ 10420 10421 picomatch.test = (input, regex, options, { glob, posix } = {}) => { 10422 if (typeof input !== 'string') { 10423 throw new TypeError('Expected input to be a string'); 10424 } 10425 10426 if (input === '') { 10427 return { isMatch: false, output: '' }; 10428 } 10429 10430 const opts = options || {}; 10431 const format = opts.format || (posix ? utils.toPosixSlashes : null); 10432 let match = input === glob; 10433 let output = (match && format) ? format(input) : input; 10434 10435 if (match === false) { 10436 output = format ? format(input) : input; 10437 match = output === glob; 10438 } 10439 10440 if (match === false || opts.capture === true) { 10441 if (opts.matchBase === true || opts.basename === true) { 10442 match = picomatch.matchBase(input, regex, options, posix); 10443 } else { 10444 match = regex.exec(output); 10445 } 10446 } 10447 10448 return { isMatch: Boolean(match), match, output }; 10449 }; 10450 10451 /** 10452 * Match the basename of a filepath. 10453 * 10454 * ```js 10455 * const picomatch = require('picomatch'); 10456 * // picomatch.matchBase(input, glob[, options]); 10457 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true 10458 * ``` 10459 * @param {String} `input` String to test. 10460 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). 10461 * @return {Boolean} 10462 * @api public 10463 */ 10464 10465 picomatch.matchBase = (input, glob, options) => { 10466 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); 10467 return regex.test(utils.basename(input)); 10468 }; 10469 10470 /** 10471 * Returns true if **any** of the given glob `patterns` match the specified `string`. 10472 * 10473 * ```js 10474 * const picomatch = require('picomatch'); 10475 * // picomatch.isMatch(string, patterns[, options]); 10476 * 10477 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true 10478 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false 10479 * ``` 10480 * @param {String|Array} str The string to test. 10481 * @param {String|Array} patterns One or more glob patterns to use for matching. 10482 * @param {Object} [options] See available [options](#options). 10483 * @return {Boolean} Returns true if any patterns match `str` 10484 * @api public 10485 */ 10486 10487 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); 10488 10489 /** 10490 * Parse a glob pattern to create the source string for a regular 10491 * expression. 10492 * 10493 * ```js 10494 * const picomatch = require('picomatch'); 10495 * const result = picomatch.parse(pattern[, options]); 10496 * ``` 10497 * @param {String} `pattern` 10498 * @param {Object} `options` 10499 * @return {Object} Returns an object with useful properties and output to be used as a regex source string. 10500 * @api public 10501 */ 10502 10503 picomatch.parse = (pattern, options) => { 10504 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); 10505 return parse(pattern, { ...options, fastpaths: false }); 10506 }; 10507 10508 /** 10509 * Scan a glob pattern to separate the pattern into segments. 10510 * 10511 * ```js 10512 * const picomatch = require('picomatch'); 10513 * // picomatch.scan(input[, options]); 10514 * 10515 * const result = picomatch.scan('!./foo/*.js'); 10516 * console.log(result); 10517 * { prefix: '!./', 10518 * input: '!./foo/*.js', 10519 * start: 3, 10520 * base: 'foo', 10521 * glob: '*.js', 10522 * isBrace: false, 10523 * isBracket: false, 10524 * isGlob: true, 10525 * isExtglob: false, 10526 * isGlobstar: false, 10527 * negated: true } 10528 * ``` 10529 * @param {String} `input` Glob pattern to scan. 10530 * @param {Object} `options` 10531 * @return {Object} Returns an object with 10532 * @api public 10533 */ 10534 10535 picomatch.scan = (input, options) => scan(input, options); 10536 10537 /** 10538 * Compile a regular expression from the `state` object returned by the 10539 * [parse()](#parse) method. 10540 * 10541 * @param {Object} `state` 10542 * @param {Object} `options` 10543 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. 10544 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. 10545 * @return {RegExp} 10546 * @api public 10547 */ 10548 10549 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { 10550 if (returnOutput === true) { 10551 return state.output; 10552 } 10553 10554 const opts = options || {}; 10555 const prepend = opts.contains ? '' : '^'; 10556 const append = opts.contains ? '' : '$'; 10557 10558 let source = `${prepend}(?:${state.output})${append}`; 10559 if (state && state.negated === true) { 10560 source = `^(?!${source}).*$`; 10561 } 10562 10563 const regex = picomatch.toRegex(source, options); 10564 if (returnState === true) { 10565 regex.state = state; 10566 } 10567 10568 return regex; 10569 }; 10570 10571 /** 10572 * Create a regular expression from a parsed glob pattern. 10573 * 10574 * ```js 10575 * const picomatch = require('picomatch'); 10576 * const state = picomatch.parse('*.js'); 10577 * // picomatch.compileRe(state[, options]); 10578 * 10579 * console.log(picomatch.compileRe(state)); 10580 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 10581 * ``` 10582 * @param {String} `state` The object returned from the `.parse` method. 10583 * @param {Object} `options` 10584 * @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. 10585 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. 10586 * @return {RegExp} Returns a regex created from the given pattern. 10587 * @api public 10588 */ 10589 10590 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { 10591 if (!input || typeof input !== 'string') { 10592 throw new TypeError('Expected a non-empty string'); 10593 } 10594 10595 let parsed = { negated: false, fastpaths: true }; 10596 10597 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { 10598 parsed.output = parse.fastpaths(input, options); 10599 } 10600 10601 if (!parsed.output) { 10602 parsed = parse(input, options); 10603 } 10604 10605 return picomatch.compileRe(parsed, options, returnOutput, returnState); 10606 }; 10607 10608 /** 10609 * Create a regular expression from the given regex source string. 10610 * 10611 * ```js 10612 * const picomatch = require('picomatch'); 10613 * // picomatch.toRegex(source[, options]); 10614 * 10615 * const { output } = picomatch.parse('*.js'); 10616 * console.log(picomatch.toRegex(output)); 10617 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 10618 * ``` 10619 * @param {String} `source` Regular expression source string. 10620 * @param {Object} `options` 10621 * @return {RegExp} 10622 * @api public 10623 */ 10624 10625 picomatch.toRegex = (source, options) => { 10626 try { 10627 const opts = options || {}; 10628 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); 10629 } catch (err) { 10630 if (options && options.debug === true) throw err; 10631 return /$^/; 10632 } 10633 }; 10634 10635 /** 10636 * Picomatch constants. 10637 * @return {Object} 10638 */ 10639 10640 picomatch.constants = constants; 10641 10642 /** 10643 * Expose "picomatch" 10644 */ 10645 10646 picomatch_1$1 = picomatch; 10647 return picomatch_1$1; 10648 } 10649 10650 var picomatch_1; 10651 var hasRequiredPicomatch; 10652 10653 function requirePicomatch () { 10654 if (hasRequiredPicomatch) return picomatch_1; 10655 hasRequiredPicomatch = 1; 10656 10657 const pico = /*@__PURE__*/ requirePicomatch$1(); 10658 const utils = /*@__PURE__*/ requireUtils(); 10659 10660 function picomatch(glob, options, returnState = false) { 10661 // default to os.platform() 10662 if (options && (options.windows === null || options.windows === undefined)) { 10663 // don't mutate the original options object 10664 options = { ...options, windows: utils.isWindows() }; 10665 } 10666 10667 return pico(glob, options, returnState); 10668 } 10669 10670 Object.assign(picomatch, pico); 10671 picomatch_1 = picomatch; 10672 return picomatch_1; 10673 } 10674 10675 var picomatchExports = /*@__PURE__*/ requirePicomatch(); 10676 const pm = /*@__PURE__*/getDefaultExportFromCjs(picomatchExports); 10677 10678 const extractors = { 10679 ArrayPattern(names, param) { 10680 for (const element of param.elements) { 10681 if (element) 10682 extractors[element.type](names, element); 10683 } 10684 }, 10685 AssignmentPattern(names, param) { 10686 extractors[param.left.type](names, param.left); 10687 }, 10688 Identifier(names, param) { 10689 names.push(param.name); 10690 }, 10691 MemberExpression() { }, 10692 ObjectPattern(names, param) { 10693 for (const prop of param.properties) { 10694 // @ts-ignore Typescript reports that this is not a valid type 10695 if (prop.type === 'RestElement') { 10696 extractors.RestElement(names, prop); 10697 } 10698 else { 10699 extractors[prop.value.type](names, prop.value); 10700 } 10701 } 10702 }, 10703 RestElement(names, param) { 10704 extractors[param.argument.type](names, param.argument); 10705 } 10706 }; 10707 const extractAssignedNames = function extractAssignedNames(param) { 10708 const names = []; 10709 extractors[param.type](names, param); 10710 return names; 10711 }; 10712 10713 // Helper since Typescript can't detect readonly arrays with Array.isArray 10714 function isArray(arg) { 10715 return Array.isArray(arg); 10716 } 10717 function ensureArray$1(thing) { 10718 if (isArray(thing)) 10719 return thing; 10720 if (thing == null) 10721 return []; 10722 return [thing]; 10723 } 10724 10725 const normalizePathRegExp = new RegExp(`\\${win32.sep}`, 'g'); 10726 const normalizePath = function normalizePath(filename) { 10727 return filename.replace(normalizePathRegExp, posix.sep); 10728 }; 10729 10730 function getMatcherString(id, resolutionBase) { 10731 if (resolutionBase === false || isAbsolute(id) || id.startsWith('**')) { 10732 return normalizePath(id); 10733 } 10734 // resolve('') is valid and will default to process.cwd() 10735 const basePath = normalizePath(resolve(resolutionBase || '')) 10736 // escape all possible (posix + win) path characters that might interfere with regex 10737 .replace(/[-^$*+?.()|[\]{}]/g, '\\$&'); 10738 // Note that we use posix.join because: 10739 // 1. the basePath has been normalized to use / 10740 // 2. the incoming glob (id) matcher, also uses / 10741 // otherwise Node will force backslash (\) on windows 10742 return posix.join(basePath, normalizePath(id)); 10743 } 10744 const createFilter = function createFilter(include, exclude, options) { 10745 const resolutionBase = options && options.resolve; 10746 const getMatcher = (id) => id instanceof RegExp 10747 ? id 10748 : { 10749 test: (what) => { 10750 // this refactor is a tad overly verbose but makes for easy debugging 10751 const pattern = getMatcherString(id, resolutionBase); 10752 const fn = pm(pattern, { dot: true }); 10753 const result = fn(what); 10754 return result; 10755 } 10756 }; 10757 const includeMatchers = ensureArray$1(include).map(getMatcher); 10758 const excludeMatchers = ensureArray$1(exclude).map(getMatcher); 10759 if (!includeMatchers.length && !excludeMatchers.length) 10760 return (id) => typeof id === 'string' && !id.includes('\0'); 10761 return function result(id) { 10762 if (typeof id !== 'string') 10763 return false; 10764 if (id.includes('\0')) 10765 return false; 10766 const pathId = normalizePath(id); 10767 for (let i = 0; i < excludeMatchers.length; ++i) { 10768 const matcher = excludeMatchers[i]; 10769 if (matcher.test(pathId)) 10770 return false; 10771 } 10772 for (let i = 0; i < includeMatchers.length; ++i) { 10773 const matcher = includeMatchers[i]; 10774 if (matcher.test(pathId)) 10775 return true; 10776 } 10777 return !includeMatchers.length; 10778 }; 10779 }; 10780 10781 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'; 10782 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'; 10783 const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' ')); 10784 forbiddenIdentifiers.add(''); 10785 10786 class ArrayPattern extends NodeBase { 10787 addExportedVariables(variables, exportNamesByVariable) { 10788 for (const element of this.elements) { 10789 element?.addExportedVariables(variables, exportNamesByVariable); 10790 } 10791 } 10792 declare(kind) { 10793 const variables = []; 10794 for (const element of this.elements) { 10795 if (element !== null) { 10796 variables.push(...element.declare(kind, UNKNOWN_EXPRESSION)); 10797 } 10798 } 10799 return variables; 10800 } 10801 // Patterns can only be deoptimized at the empty path at the moment 10802 deoptimizePath() { 10803 for (const element of this.elements) { 10804 element?.deoptimizePath(EMPTY_PATH); 10805 } 10806 } 10807 // Patterns are only checked at the empty path at the moment 10808 hasEffectsOnInteractionAtPath(_path, interaction, context) { 10809 for (const element of this.elements) { 10810 if (element?.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)) 10811 return true; 10812 } 10813 return false; 10814 } 10815 markDeclarationReached() { 10816 for (const element of this.elements) { 10817 element?.markDeclarationReached(); 10818 } 10819 } 10820 } 10821 10822 class ArrowFunctionExpression extends FunctionBase { 10823 constructor() { 10824 super(...arguments); 10825 this.objectEntity = null; 10826 } 10827 get expression() { 10828 return isFlagSet(this.flags, 8388608 /* Flag.expression */); 10829 } 10830 set expression(value) { 10831 this.flags = setFlag(this.flags, 8388608 /* Flag.expression */, value); 10832 } 10833 createScope(parentScope) { 10834 this.scope = new ReturnValueScope(parentScope, false); 10835 } 10836 hasEffects() { 10837 if (!this.deoptimized) 10838 this.applyDeoptimizations(); 10839 return false; 10840 } 10841 hasEffectsOnInteractionAtPath(path, interaction, context) { 10842 if (super.hasEffectsOnInteractionAtPath(path, interaction, context)) { 10843 return true; 10844 } 10845 if (this.annotationNoSideEffects) { 10846 return false; 10847 } 10848 if (interaction.type === INTERACTION_CALLED) { 10849 const { ignore, brokenFlow } = context; 10850 context.ignore = { 10851 breaks: false, 10852 continues: false, 10853 labels: new Set(), 10854 returnYield: true, 10855 this: false 10856 }; 10857 if (this.body.hasEffects(context)) 10858 return true; 10859 context.ignore = ignore; 10860 context.brokenFlow = brokenFlow; 10861 } 10862 return false; 10863 } 10864 onlyFunctionCallUsed() { 10865 const isIIFE = this.parent.type === CallExpression$1 && 10866 this.parent.callee === this; 10867 return isIIFE || super.onlyFunctionCallUsed(); 10868 } 10869 include(context, includeChildrenRecursively) { 10870 super.include(context, includeChildrenRecursively); 10871 for (const parameter of this.params) { 10872 if (!(parameter instanceof Identifier)) { 10873 parameter.include(context, includeChildrenRecursively); 10874 } 10875 } 10876 } 10877 getObjectEntity() { 10878 if (this.objectEntity !== null) { 10879 return this.objectEntity; 10880 } 10881 return (this.objectEntity = new ObjectEntity([], OBJECT_PROTOTYPE)); 10882 } 10883 } 10884 10885 class ObjectPattern extends NodeBase { 10886 addExportedVariables(variables, exportNamesByVariable) { 10887 for (const property of this.properties) { 10888 if (property.type === Property$1) { 10889 property.value.addExportedVariables(variables, exportNamesByVariable); 10890 } 10891 else { 10892 property.argument.addExportedVariables(variables, exportNamesByVariable); 10893 } 10894 } 10895 } 10896 declare(kind, init) { 10897 const variables = []; 10898 for (const property of this.properties) { 10899 variables.push(...property.declare(kind, init)); 10900 } 10901 return variables; 10902 } 10903 deoptimizePath(path) { 10904 if (path.length === 0) { 10905 for (const property of this.properties) { 10906 property.deoptimizePath(path); 10907 } 10908 } 10909 } 10910 hasEffectsOnInteractionAtPath( 10911 // At the moment, this is only triggered for assignment left-hand sides, 10912 // where the path is empty 10913 _path, interaction, context) { 10914 for (const property of this.properties) { 10915 if (property.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)) 10916 return true; 10917 } 10918 return false; 10919 } 10920 markDeclarationReached() { 10921 for (const property of this.properties) { 10922 property.markDeclarationReached(); 10923 } 10924 } 10925 } 10926 10927 class AssignmentExpression extends NodeBase { 10928 hasEffects(context) { 10929 const { deoptimized, left, operator, right } = this; 10930 if (!deoptimized) 10931 this.applyDeoptimizations(); 10932 // MemberExpressions do not access the property before assignments if the 10933 // operator is '='. 10934 return (right.hasEffects(context) || left.hasEffectsAsAssignmentTarget(context, operator !== '=')); 10935 } 10936 hasEffectsOnInteractionAtPath(path, interaction, context) { 10937 return this.right.hasEffectsOnInteractionAtPath(path, interaction, context); 10938 } 10939 include(context, includeChildrenRecursively) { 10940 const { deoptimized, left, right, operator } = this; 10941 if (!deoptimized) 10942 this.applyDeoptimizations(); 10943 this.included = true; 10944 if (includeChildrenRecursively || 10945 operator !== '=' || 10946 left.included || 10947 left.hasEffectsAsAssignmentTarget(createHasEffectsContext(), false)) { 10948 left.includeAsAssignmentTarget(context, includeChildrenRecursively, operator !== '='); 10949 } 10950 right.include(context, includeChildrenRecursively); 10951 } 10952 initialise() { 10953 super.initialise(); 10954 if (this.left instanceof Identifier) { 10955 const variable = this.scope.variables.get(this.left.name); 10956 if (variable?.kind === 'const') { 10957 this.scope.context.error(logConstVariableReassignError(), this.left.start); 10958 } 10959 } 10960 this.left.setAssignedValue(this.right); 10961 } 10962 render(code, options, { preventASI, renderedParentType, renderedSurroundingElement } = BLANK) { 10963 const { left, right, start, end, parent } = this; 10964 if (left.included) { 10965 left.render(code, options); 10966 right.render(code, options); 10967 } 10968 else { 10969 const inclusionStart = findNonWhiteSpace(code.original, findFirstOccurrenceOutsideComment(code.original, '=', left.end) + 1); 10970 code.remove(start, inclusionStart); 10971 if (preventASI) { 10972 removeLineBreaks(code, inclusionStart, right.start); 10973 } 10974 right.render(code, options, { 10975 renderedParentType: renderedParentType || parent.type, 10976 renderedSurroundingElement: renderedSurroundingElement || parent.type 10977 }); 10978 } 10979 if (options.format === 'system') { 10980 if (left instanceof Identifier) { 10981 const variable = left.variable; 10982 const exportNames = options.exportNamesByVariable.get(variable); 10983 if (exportNames) { 10984 if (exportNames.length === 1) { 10985 renderSystemExportExpression(variable, start, end, code, options); 10986 } 10987 else { 10988 renderSystemExportSequenceAfterExpression(variable, start, end, parent.type !== ExpressionStatement$1, code, options); 10989 } 10990 return; 10991 } 10992 } 10993 else { 10994 const systemPatternExports = []; 10995 left.addExportedVariables(systemPatternExports, options.exportNamesByVariable); 10996 if (systemPatternExports.length > 0) { 10997 renderSystemExportFunction(systemPatternExports, start, end, renderedSurroundingElement === ExpressionStatement$1, code, options); 10998 return; 10999 } 11000 } 11001 } 11002 if (left.included && 11003 left instanceof ObjectPattern && 11004 (renderedSurroundingElement === ExpressionStatement$1 || 11005 renderedSurroundingElement === ArrowFunctionExpression$1)) { 11006 code.appendRight(start, '('); 11007 code.prependLeft(end, ')'); 11008 } 11009 } 11010 applyDeoptimizations() { 11011 this.deoptimized = true; 11012 this.left.deoptimizePath(EMPTY_PATH); 11013 this.right.deoptimizePath(UNKNOWN_PATH); 11014 this.scope.context.requestTreeshakingPass(); 11015 } 11016 } 11017 11018 class AssignmentPattern extends NodeBase { 11019 addExportedVariables(variables, exportNamesByVariable) { 11020 this.left.addExportedVariables(variables, exportNamesByVariable); 11021 } 11022 declare(kind, init) { 11023 return this.left.declare(kind, init); 11024 } 11025 deoptimizePath(path) { 11026 if (path.length === 0) { 11027 this.left.deoptimizePath(path); 11028 } 11029 } 11030 hasEffectsOnInteractionAtPath(path, interaction, context) { 11031 return (path.length > 0 || this.left.hasEffectsOnInteractionAtPath(EMPTY_PATH, interaction, context)); 11032 } 11033 markDeclarationReached() { 11034 this.left.markDeclarationReached(); 11035 } 11036 render(code, options, { isShorthandProperty } = BLANK) { 11037 this.left.render(code, options, { isShorthandProperty }); 11038 this.right.render(code, options); 11039 } 11040 applyDeoptimizations() { 11041 this.deoptimized = true; 11042 this.left.deoptimizePath(EMPTY_PATH); 11043 this.right.deoptimizePath(UNKNOWN_PATH); 11044 this.scope.context.requestTreeshakingPass(); 11045 } 11046 } 11047 11048 class AwaitExpression extends NodeBase { 11049 hasEffects() { 11050 if (!this.deoptimized) 11051 this.applyDeoptimizations(); 11052 return true; 11053 } 11054 include(context, includeChildrenRecursively) { 11055 if (!this.deoptimized) 11056 this.applyDeoptimizations(); 11057 if (!this.included) { 11058 this.included = true; 11059 checkTopLevelAwait: if (!this.scope.context.usesTopLevelAwait) { 11060 let parent = this.parent; 11061 do { 11062 if (parent instanceof FunctionNode || parent instanceof ArrowFunctionExpression) 11063 break checkTopLevelAwait; 11064 } while ((parent = parent.parent)); 11065 this.scope.context.usesTopLevelAwait = true; 11066 } 11067 } 11068 this.argument.include(context, includeChildrenRecursively); 11069 } 11070 } 11071 11072 const binaryOperators = { 11073 '!=': (left, right) => left != right, 11074 '!==': (left, right) => left !== right, 11075 '%': (left, right) => left % right, 11076 '&': (left, right) => left & right, 11077 '*': (left, right) => left * right, 11078 // At the moment, "**" will be transpiled to Math.pow 11079 '**': (left, right) => left ** right, 11080 '+': (left, right) => left + right, 11081 '-': (left, right) => left - right, 11082 '/': (left, right) => left / right, 11083 '<': (left, right) => left < right, 11084 '<<': (left, right) => left << right, 11085 '<=': (left, right) => left <= right, 11086 '==': (left, right) => left == right, 11087 '===': (left, right) => left === right, 11088 '>': (left, right) => left > right, 11089 '>=': (left, right) => left >= right, 11090 '>>': (left, right) => left >> right, 11091 '>>>': (left, right) => left >>> right, 11092 '^': (left, right) => left ^ right, 11093 '|': (left, right) => left | right 11094 // We use the fallback for cases where we return something unknown 11095 // in: () => UnknownValue, 11096 // instanceof: () => UnknownValue, 11097 }; 11098 class BinaryExpression extends NodeBase { 11099 deoptimizeCache() { } 11100 getLiteralValueAtPath(path, recursionTracker, origin) { 11101 if (path.length > 0) 11102 return UnknownValue; 11103 const leftValue = this.left.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin); 11104 if (typeof leftValue === 'symbol') 11105 return UnknownValue; 11106 const rightValue = this.right.getLiteralValueAtPath(EMPTY_PATH, recursionTracker, origin); 11107 if (typeof rightValue === 'symbol') 11108 return UnknownValue; 11109 const operatorFunction = binaryOperators[this.operator]; 11110 if (!operatorFunction) 11111 return UnknownValue; 11112 return operatorFunction(leftValue, rightValue); 11113 } 11114 hasEffects(context) { 11115 // support some implicit type coercion runtime errors 11116 if (this.operator === '+' && 11117 this.parent instanceof ExpressionStatement && 11118 this.left.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) === '') { 11119 return true; 11120 } 11121 return super.hasEffects(context); 11122 } 11123 hasEffectsOnInteractionAtPath(path, { type }) { 11124 return type !== INTERACTION_ACCESSED || path.length > 1; 11125 } 11126 removeAnnotations(code) { 11127 this.left.removeAnnotations(code); 11128 } 11129 render(code, options, { renderedSurroundingElement } = BLANK) { 11130 this.left.render(code, options, { renderedSurroundingElement }); 11131 this.right.render(code, options); 11132 } 11133 } 11134 11135 class BreakStatement extends NodeBase { 11136 hasEffects(context) { 11137 if (this.label) { 11138 if (!context.ignore.labels.has(this.label.name)) 11139 return true; 11140 context.includedLabels.add(this.label.name); 11141 } 11142 else { 11143 if (!context.ignore.breaks) 11144 return true; 11145 context.hasBreak = true; 11146 } 11147 context.brokenFlow = true; 11148 return false; 11149 } 11150 include(context) { 11151 this.included = true; 11152 if (this.label) { 11153 this.label.include(); 11154 context.includedLabels.add(this.label.name); 11155 } 11156 else { 11157 context.hasBreak = true; 11158 } 11159 context.brokenFlow = true; 11160 } 11161 } 11162 11163 function renderCallArguments(code, options, node) { 11164 if (node.arguments.length > 0) { 11165 if (node.arguments[node.arguments.length - 1].included) { 11166 for (const argument of node.arguments) { 11167 argument.render(code, options); 11168 } 11169 } 11170 else { 11171 let lastIncludedIndex = node.arguments.length - 2; 11172 while (lastIncludedIndex >= 0 && !node.arguments[lastIncludedIndex].included) { 11173 lastIncludedIndex--; 11174 } 11175 if (lastIncludedIndex >= 0) { 11176 for (let index = 0; index <= lastIncludedIndex; index++) { 11177 node.arguments[index].render(code, options); 11178 } 11179 code.remove(findFirstOccurrenceOutsideComment(code.original, ',', node.arguments[lastIncludedIndex].end), node.end - 1); 11180 } 11181 else { 11182 code.remove(findFirstOccurrenceOutsideComment(code.original, '(', node.callee.end) + 1, node.end - 1); 11183 } 11184 } 11185 } 11186 } 11187 11188 class CallExpressionBase extends NodeBase { 11189 constructor() { 11190 super(...arguments); 11191 this.returnExpression = null; 11192 this.deoptimizableDependentExpressions = []; 11193 this.expressionsToBeDeoptimized = new Set(); 11194 } 11195 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 11196 const { args } = interaction; 11197 const [returnExpression, isPure] = this.getReturnExpression(recursionTracker); 11198 if (isPure) 11199 return; 11200 const deoptimizedExpressions = args.filter(expression => !!expression && expression !== UNKNOWN_EXPRESSION); 11201 if (deoptimizedExpressions.length === 0) 11202 return; 11203 if (returnExpression === UNKNOWN_EXPRESSION) { 11204 for (const expression of deoptimizedExpressions) { 11205 expression.deoptimizePath(UNKNOWN_PATH); 11206 } 11207 } 11208 else { 11209 recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 11210 for (const expression of deoptimizedExpressions) { 11211 this.expressionsToBeDeoptimized.add(expression); 11212 } 11213 returnExpression.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 11214 }, null); 11215 } 11216 } 11217 deoptimizeCache() { 11218 if (this.returnExpression?.[0] !== UNKNOWN_EXPRESSION) { 11219 this.returnExpression = UNKNOWN_RETURN_EXPRESSION; 11220 const { deoptimizableDependentExpressions, expressionsToBeDeoptimized } = this; 11221 this.expressionsToBeDeoptimized = EMPTY_SET; 11222 this.deoptimizableDependentExpressions = EMPTY_ARRAY; 11223 for (const expression of deoptimizableDependentExpressions) { 11224 expression.deoptimizeCache(); 11225 } 11226 for (const expression of expressionsToBeDeoptimized) { 11227 expression.deoptimizePath(UNKNOWN_PATH); 11228 } 11229 } 11230 } 11231 deoptimizePath(path) { 11232 if (path.length === 0 || 11233 this.scope.context.deoptimizationTracker.trackEntityAtPathAndGetIfTracked(path, this)) { 11234 return; 11235 } 11236 const [returnExpression] = this.getReturnExpression(); 11237 if (returnExpression !== UNKNOWN_EXPRESSION) { 11238 returnExpression.deoptimizePath(path); 11239 } 11240 } 11241 getLiteralValueAtPath(path, recursionTracker, origin) { 11242 const [returnExpression] = this.getReturnExpression(recursionTracker); 11243 if (returnExpression === UNKNOWN_EXPRESSION) { 11244 return UnknownValue; 11245 } 11246 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 11247 this.deoptimizableDependentExpressions.push(origin); 11248 return returnExpression.getLiteralValueAtPath(path, recursionTracker, origin); 11249 }, UnknownValue); 11250 } 11251 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 11252 const returnExpression = this.getReturnExpression(recursionTracker); 11253 if (returnExpression[0] === UNKNOWN_EXPRESSION) { 11254 return returnExpression; 11255 } 11256 return recursionTracker.withTrackedEntityAtPath(path, returnExpression, () => { 11257 this.deoptimizableDependentExpressions.push(origin); 11258 const [expression, isPure] = returnExpression[0].getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 11259 return [expression, isPure || returnExpression[1]]; 11260 }, UNKNOWN_RETURN_EXPRESSION); 11261 } 11262 hasEffectsOnInteractionAtPath(path, interaction, context) { 11263 const { type } = interaction; 11264 if (type === INTERACTION_CALLED) { 11265 const { args, withNew } = interaction; 11266 if ((withNew ? context.instantiated : context.called).trackEntityAtPathAndGetIfTracked(path, args, this)) { 11267 return false; 11268 } 11269 } 11270 else if ((type === INTERACTION_ASSIGNED 11271 ? context.assigned 11272 : context.accessed).trackEntityAtPathAndGetIfTracked(path, this)) { 11273 return false; 11274 } 11275 const [returnExpression, isPure] = this.getReturnExpression(); 11276 return ((type === INTERACTION_ASSIGNED || !isPure) && 11277 returnExpression.hasEffectsOnInteractionAtPath(path, interaction, context)); 11278 } 11279 } 11280 11281 class CallExpression extends CallExpressionBase { 11282 get optional() { 11283 return isFlagSet(this.flags, 128 /* Flag.optional */); 11284 } 11285 set optional(value) { 11286 this.flags = setFlag(this.flags, 128 /* Flag.optional */, value); 11287 } 11288 bind() { 11289 super.bind(); 11290 if (this.callee instanceof Identifier) { 11291 const variable = this.scope.findVariable(this.callee.name); 11292 if (variable.isNamespace) { 11293 this.scope.context.log(LOGLEVEL_WARN, logCannotCallNamespace(this.callee.name), this.start); 11294 } 11295 if (this.callee.name === 'eval') { 11296 this.scope.context.log(LOGLEVEL_WARN, logEval(this.scope.context.module.id), this.start); 11297 } 11298 } 11299 this.interaction = { 11300 args: [ 11301 this.callee instanceof MemberExpression && !this.callee.variable 11302 ? this.callee.object 11303 : null, 11304 ...this.arguments 11305 ], 11306 type: INTERACTION_CALLED, 11307 withNew: false 11308 }; 11309 } 11310 getLiteralValueAtPathAsChainElement(path, recursionTracker, origin) { 11311 return getChainElementLiteralValueAtPath(this, this.callee, path, recursionTracker, origin); 11312 } 11313 hasEffects(context) { 11314 if (!this.deoptimized) 11315 this.applyDeoptimizations(); 11316 for (const argument of this.arguments) { 11317 if (argument.hasEffects(context)) 11318 return true; 11319 } 11320 if (this.annotationPure) { 11321 return false; 11322 } 11323 return (this.callee.hasEffects(context) || 11324 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context)); 11325 } 11326 hasEffectsAsChainElement(context) { 11327 const calleeHasEffects = 'hasEffectsAsChainElement' in this.callee 11328 ? this.callee.hasEffectsAsChainElement(context) 11329 : this.callee.hasEffects(context); 11330 if (calleeHasEffects === IS_SKIPPED_CHAIN) 11331 return IS_SKIPPED_CHAIN; 11332 if (this.optional && 11333 this.callee.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this) == null) { 11334 return (!this.annotationPure && calleeHasEffects) || IS_SKIPPED_CHAIN; 11335 } 11336 // We only apply deoptimizations lazily once we know we are not skipping 11337 if (!this.deoptimized) 11338 this.applyDeoptimizations(); 11339 for (const argument of this.arguments) { 11340 if (argument.hasEffects(context)) 11341 return true; 11342 } 11343 return (!this.annotationPure && 11344 (calleeHasEffects || 11345 this.callee.hasEffectsOnInteractionAtPath(EMPTY_PATH, this.interaction, context))); 11346 } 11347 include(context, includeChildrenRecursively) { 11348 if (!this.deoptimized) 11349 this.applyDeoptimizations(); 11350 if (includeChildrenRecursively) { 11351 super.include(context, includeChildrenRecursively); 11352 if (includeChildrenRecursively === INCLUDE_PARAMETERS && 11353 this.callee instanceof Identifier && 11354 this.callee.variable) { 11355 this.callee.variable.markCalledFromTryStatement(); 11356 } 11357 } 11358 else { 11359 this.included = true; 11360 this.callee.include(context, false); 11361 } 11362 this.callee.includeCallArguments(context, this.arguments); 11363 } 11364 initialise() { 11365 super.initialise(); 11366 if (this.annotations && 11367 this.scope.context.options.treeshake.annotations) { 11368 this.annotationPure = this.annotations.some(comment => comment.type === 'pure'); 11369 } 11370 } 11371 render(code, options, { renderedSurroundingElement } = BLANK) { 11372 this.callee.render(code, options, { 11373 isCalleeOfRenderedParent: true, 11374 renderedSurroundingElement 11375 }); 11376 renderCallArguments(code, options, this); 11377 } 11378 applyDeoptimizations() { 11379 this.deoptimized = true; 11380 this.callee.deoptimizeArgumentsOnInteractionAtPath(this.interaction, EMPTY_PATH, SHARED_RECURSION_TRACKER); 11381 this.scope.context.requestTreeshakingPass(); 11382 } 11383 getReturnExpression(recursionTracker = SHARED_RECURSION_TRACKER) { 11384 if (this.returnExpression === null) { 11385 this.returnExpression = UNKNOWN_RETURN_EXPRESSION; 11386 return (this.returnExpression = this.callee.getReturnExpressionWhenCalledAtPath(EMPTY_PATH, this.interaction, recursionTracker, this)); 11387 } 11388 return this.returnExpression; 11389 } 11390 } 11391 11392 class CatchClause extends NodeBase { 11393 createScope(parentScope) { 11394 this.scope = new ParameterScope(parentScope, true); 11395 } 11396 parseNode(esTreeNode) { 11397 const { body, param, type } = esTreeNode; 11398 this.type = type; 11399 if (param) { 11400 this.param = new (this.scope.context.getNodeConstructor(param.type))(this, this.scope).parseNode(param); 11401 this.param.declare('parameter', UNKNOWN_EXPRESSION); 11402 } 11403 this.body = new BlockStatement(this, this.scope.bodyScope).parseNode(body); 11404 return super.parseNode(esTreeNode); 11405 } 11406 } 11407 CatchClause.prototype.preventChildBlockScope = true; 11408 11409 class ChainExpression extends NodeBase { 11410 // deoptimizations are not relevant as we are not caching values 11411 deoptimizeCache() { } 11412 getLiteralValueAtPath(path, recursionTracker, origin) { 11413 const literalValue = this.expression.getLiteralValueAtPathAsChainElement(path, recursionTracker, origin); 11414 return literalValue === IS_SKIPPED_CHAIN ? undefined : literalValue; 11415 } 11416 hasEffects(context) { 11417 return this.expression.hasEffectsAsChainElement(context) === true; 11418 } 11419 removeAnnotations(code) { 11420 this.expression.removeAnnotations(code); 11421 } 11422 applyDeoptimizations() { } 11423 } 11424 11425 class ClassBodyScope extends ChildScope { 11426 constructor(parent, classNode) { 11427 const { context } = parent; 11428 super(parent, context); 11429 this.variables.set('this', (this.thisVariable = new LocalVariable('this', null, classNode, context, 'other'))); 11430 this.instanceScope = new ChildScope(this, context); 11431 this.instanceScope.variables.set('this', new ThisVariable(context)); 11432 } 11433 findLexicalBoundary() { 11434 return this; 11435 } 11436 } 11437 11438 class ClassBody extends NodeBase { 11439 createScope(parentScope) { 11440 this.scope = new ClassBodyScope(parentScope, this.parent); 11441 } 11442 include(context, includeChildrenRecursively) { 11443 this.included = true; 11444 this.scope.context.includeVariableInModule(this.scope.thisVariable); 11445 for (const definition of this.body) { 11446 definition.include(context, includeChildrenRecursively); 11447 } 11448 } 11449 parseNode(esTreeNode) { 11450 const body = (this.body = new Array(esTreeNode.body.length)); 11451 let index = 0; 11452 for (const definition of esTreeNode.body) { 11453 body[index++] = new (this.scope.context.getNodeConstructor(definition.type))(this, definition.static ? this.scope : this.scope.instanceScope).parseNode(definition); 11454 } 11455 return super.parseNode(esTreeNode); 11456 } 11457 applyDeoptimizations() { } 11458 } 11459 11460 class ClassExpression extends ClassNode { 11461 render(code, options, { renderedSurroundingElement } = BLANK) { 11462 super.render(code, options); 11463 if (renderedSurroundingElement === ExpressionStatement$1) { 11464 code.appendRight(this.start, '('); 11465 code.prependLeft(this.end, ')'); 11466 } 11467 } 11468 } 11469 11470 class MultiExpression extends ExpressionEntity { 11471 constructor(expressions) { 11472 super(); 11473 this.expressions = expressions; 11474 } 11475 deoptimizePath(path) { 11476 for (const expression of this.expressions) { 11477 expression.deoptimizePath(path); 11478 } 11479 } 11480 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 11481 return [ 11482 new MultiExpression(this.expressions.map(expression => expression.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0])), 11483 false 11484 ]; 11485 } 11486 hasEffectsOnInteractionAtPath(path, interaction, context) { 11487 for (const expression of this.expressions) { 11488 if (expression.hasEffectsOnInteractionAtPath(path, interaction, context)) 11489 return true; 11490 } 11491 return false; 11492 } 11493 } 11494 11495 class ConditionalExpression extends NodeBase { 11496 constructor() { 11497 super(...arguments); 11498 this.expressionsToBeDeoptimized = []; 11499 this.usedBranch = null; 11500 } 11501 get isBranchResolutionAnalysed() { 11502 return isFlagSet(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */); 11503 } 11504 set isBranchResolutionAnalysed(value) { 11505 this.flags = setFlag(this.flags, 65536 /* Flag.isBranchResolutionAnalysed */, value); 11506 } 11507 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) { 11508 this.consequent.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 11509 this.alternate.deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker); 11510 } 11511 deoptimizeCache() { 11512 if (this.usedBranch !== null) { 11513 const unusedBranch = this.usedBranch === this.consequent ? this.alternate : this.consequent; 11514 this.usedBranch = null; 11515 unusedBranch.deoptimizePath(UNKNOWN_PATH); 11516 const { expressionsToBeDeoptimized } = this; 11517 this.expressionsToBeDeoptimized = EMPTY_ARRAY; 11518 for (const expression of expressionsToBeDeoptimized) { 11519 expression.deoptimizeCache(); 11520 } 11521 } 11522 } 11523 deoptimizePath(path) { 11524 const usedBranch = this.getUsedBranch(); 11525 if (usedBranch) { 11526 usedBranch.deoptimizePath(path); 11527 } 11528 else { 11529 this.consequent.deoptimizePath(path); 11530 this.alternate.deoptimizePath(path); 11531 } 11532 } 11533 getLiteralValueAtPath(path, recursionTracker, origin) { 11534 const usedBranch = this.getUsedBranch(); 11535 if (!usedBranch) 11536 return UnknownValue; 11537 this.expressionsToBeDeoptimized.push(origin); 11538 return usedBranch.getLiteralValueAtPath(path, recursionTracker, origin); 11539 } 11540 getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin) { 11541 const usedBranch = this.getUsedBranch(); 11542 if (!usedBranch) 11543 return [ 11544 new MultiExpression([ 11545 this.consequent.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0], 11546 this.alternate.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin)[0] 11547 ]), 11548 false 11549 ]; 11550 this.expressionsToBeDeoptimized.push(origin); 11551 return usedBranch.getReturnExpressionWhenCalledAtPath(path, interaction, recursionTracker, origin); 11552 } 11553 hasEffects(context) { 11554 if (this.test.hasEffects(context)) 11555 return true; 11556 const usedBranch = this.getUsedBranch(); 11557 if (!usedBranch) { 11558 return this.consequent.hasEffects(context) || this.alternate.hasEffects(context); 11559 } 11560 return usedBranch.hasEffects(context); 11561 } 11562 hasEffectsOnInteractionAtPath(path, interaction, context) { 11563 const usedBranch = this.getUsedBranch(); 11564 if (!usedBranch) { 11565 return (this.consequent.hasEffectsOnInteractionAtPath(path, interaction, context) || 11566 this.alternate.hasEffectsOnInteractionAtPath(path, interaction, context)); 11567 } 11568 return usedBranch.hasEffectsOnInteractionAtPath(path, interaction, context); 11569 } 11570 include(context, includeChildrenRecursively) { 11571 this.included = true; 11572 const usedBranch = this.getUsedBranch(); 11573 if (includeChildrenRecursively || this.test.shouldBeIncluded(context) || usedBranch === null) { 11574 this.test.include(context, includeChildrenRecursively); 11575 this.consequent.include(context, includeChildrenRecursively); 11576 this.alternate.include(context, includeChildrenRecursively); 11577 } 11578 else { 11579 usedBranch.include(context, includeChildrenRecursively); 11580 } 11581 } 11582 includeCallArguments(context, parameters) { 11583 const usedBranch = this.getUsedBranch(); 11584 if (usedBranch) { 11585 usedBranch.includeCallArguments(context, parameters); 11586 } 11587 else { 11588 this.consequent.includeCallArguments(context, parameters); 11589 this.alternate.includeCallArguments(context, parameters); 11590 } 11591 } 11592 removeAnnotations(code) { 11593 this.test.removeAnnotations(code); 11594 } 11595 render(code, options, { isCalleeOfRenderedParent, preventASI, renderedParentType, renderedSurroundingElement } = BLANK) { 11596 const usedBranch = this.getUsedBranch(); 11597 if (this.test.included) { 11598 this.test.render(code, options, { renderedSurroundingElement }); 11599 this.consequent.render(code, options); 11600 this.alternate.render(code, options); 11601 } 11602 else { 11603 const colonPos = findFirstOccurrenceOutsideComment(code.original, ':', this.consequent.end); 11604 const inclusionStart = findNonWhiteSpace(code.original, (this.consequent.included 11605 ? findFirstOccurrenceOutsideComment(code.original, '?', this.test.end) 11606 : colonPos) + 1); 11607 if (preventASI) { 11608 removeLineBreaks(code, inclusionStart, usedBranch.start); 11609 } 11610 code.remove(this.start, inclusionStart); 11611 if (this.consequent.included) { 11612 code.remove(colonPos, this.end); 11613 } 11614 this.test.removeAnnotations(code); 11615 usedBranch.render(code, options, { 11616 isCalleeOfRenderedParent, 11617 preventASI: true, 11618 renderedParentType: renderedParentType || this.parent.type, 11619 renderedSurroundingElement: renderedSurroundingElement || this.parent.type 11620 }); 11621 } 11622 } 11623 getUsedBranch() { 11624 if (this.isBranchResolutionAnalysed) { 11625 return this.usedBranch; 11626 } 11627 this.isBranchResolutionAnalysed = true; 11628 const testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this); 11629 return typeof testValue === 'symbol' 11630 ? null 11631 : (this.usedBranch = testValue ? this.consequent : this.alternate); 11632 } 11633 } 11634 11635 class ContinueStatement extends NodeBase { 11636 hasEffects(context) { 11637 if (this.label) { 11638 if (!context.ignore.labels.has(this.label.name)) 11639 return true; 11640 context.includedLabels.add(this.label.name); 11641 } 11642 else { 11643 if (!context.ignore.continues) 11644 return true; 11645 context.hasContinue = true; 11646 } 11647 context.brokenFlow = true; 11648 return false; 11649 } 11650 include(context) { 11651 this.included = true; 11652 if (this.label) { 11653 this.label.include(); 11654 context.includedLabels.add(this.label.name); 11655 } 11656 else { 11657 context.hasContinue = true; 11658 } 11659 context.brokenFlow = true; 11660 } 11661 } 11662 11663 class DebuggerStatement extends NodeBase { 11664 hasEffects() { 11665 return true; 11666 } 11667 } 11668 11669 class Decorator extends NodeBase { 11670 hasEffects(context) { 11671 return (this.expression.hasEffects(context) || 11672 this.expression.hasEffectsOnInteractionAtPath(EMPTY_PATH, NODE_INTERACTION_UNKNOWN_CALL, context)); 11673 } 11674 } 11675 11676 function hasLoopBodyEffects(context, body) { 11677 const { brokenFlow, hasBreak, hasContinue, ignore } = context; 11678 const { breaks, continues } = ignore; 11679 ignore.breaks = true; 11680 ignore.continues = true; 11681 context.hasBreak = false; 11682 context.hasContinue = false; 11683 if (body.hasEffects(context)) 11684 return true; 11685 ignore.breaks = breaks; 11686 ignore.continues = continues; 11687 context.hasBreak = hasBreak; 11688 context.hasContinue = hasContinue; 11689 context.brokenFlow = brokenFlow; 11690 return false; 11691 } 11692 function includeLoopBody(context, body, includeChildrenRecursively) { 11693 const { brokenFlow, hasBreak, hasContinue } = context; 11694 context.hasBreak = false; 11695 context.hasContinue = false; 11696 body.include(context, includeChildrenRecursively, { asSingleStatement: true }); 11697 context.hasBreak = hasBreak; 11698 context.hasContinue = hasContinue; 11699 context.brokenFlow = brokenFlow; 11700 } 11701 11702 class DoWhileStatement extends NodeBase { 11703 hasEffects(context) { 11704 if (this.test.hasEffects(context)) 11705 return true; 11706 return hasLoopBodyEffects(context, this.body); 11707 } 11708 include(context, includeChildrenRecursively) { 11709 this.included = true; 11710 this.test.include(context, includeChildrenRecursively); 11711 includeLoopBody(context, this.body, includeChildrenRecursively); 11712 } 11713 } 11714 11715 class EmptyStatement extends NodeBase { 11716 hasEffects() { 11717 return false; 11718 } 11719 } 11720 11721 class ExportAllDeclaration extends NodeBase { 11722 hasEffects() { 11723 return false; 11724 } 11725 initialise() { 11726 super.initialise(); 11727 this.scope.context.addExport(this); 11728 } 11729 render(code, _options, nodeRenderOptions) { 11730 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 11731 } 11732 applyDeoptimizations() { } 11733 } 11734 ExportAllDeclaration.prototype.needsBoundaries = true; 11735 11736 class ExportNamedDeclaration extends NodeBase { 11737 bind() { 11738 // Do not bind specifiers 11739 this.declaration?.bind(); 11740 } 11741 hasEffects(context) { 11742 return !!this.declaration?.hasEffects(context); 11743 } 11744 initialise() { 11745 super.initialise(); 11746 this.scope.context.addExport(this); 11747 } 11748 removeAnnotations(code) { 11749 this.declaration?.removeAnnotations(code); 11750 } 11751 render(code, options, nodeRenderOptions) { 11752 const { start, end } = nodeRenderOptions; 11753 if (this.declaration === null) { 11754 code.remove(start, end); 11755 } 11756 else { 11757 code.remove(this.start, this.declaration.start); 11758 this.declaration.render(code, options, { end, start }); 11759 } 11760 } 11761 applyDeoptimizations() { } 11762 } 11763 ExportNamedDeclaration.prototype.needsBoundaries = true; 11764 11765 class ExportSpecifier extends NodeBase { 11766 applyDeoptimizations() { } 11767 } 11768 11769 class ForInStatement extends NodeBase { 11770 createScope(parentScope) { 11771 this.scope = new BlockScope(parentScope); 11772 } 11773 hasEffects(context) { 11774 const { body, deoptimized, left, right } = this; 11775 if (!deoptimized) 11776 this.applyDeoptimizations(); 11777 if (left.hasEffectsAsAssignmentTarget(context, false) || right.hasEffects(context)) 11778 return true; 11779 return hasLoopBodyEffects(context, body); 11780 } 11781 include(context, includeChildrenRecursively) { 11782 const { body, deoptimized, left, right } = this; 11783 if (!deoptimized) 11784 this.applyDeoptimizations(); 11785 this.included = true; 11786 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 11787 right.include(context, includeChildrenRecursively); 11788 includeLoopBody(context, body, includeChildrenRecursively); 11789 } 11790 initialise() { 11791 super.initialise(); 11792 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 11793 } 11794 render(code, options) { 11795 this.left.render(code, options, NO_SEMICOLON); 11796 this.right.render(code, options, NO_SEMICOLON); 11797 // handle no space between "in" and the right side 11798 if (code.original.charCodeAt(this.right.start - 1) === 110 /* n */) { 11799 code.prependLeft(this.right.start, ' '); 11800 } 11801 this.body.render(code, options); 11802 } 11803 applyDeoptimizations() { 11804 this.deoptimized = true; 11805 this.left.deoptimizePath(EMPTY_PATH); 11806 this.scope.context.requestTreeshakingPass(); 11807 } 11808 } 11809 11810 class ForOfStatement extends NodeBase { 11811 get await() { 11812 return isFlagSet(this.flags, 131072 /* Flag.await */); 11813 } 11814 set await(value) { 11815 this.flags = setFlag(this.flags, 131072 /* Flag.await */, value); 11816 } 11817 createScope(parentScope) { 11818 this.scope = new BlockScope(parentScope); 11819 } 11820 hasEffects() { 11821 if (!this.deoptimized) 11822 this.applyDeoptimizations(); 11823 // Placeholder until proper Symbol.Iterator support 11824 return true; 11825 } 11826 include(context, includeChildrenRecursively) { 11827 const { body, deoptimized, left, right } = this; 11828 if (!deoptimized) 11829 this.applyDeoptimizations(); 11830 this.included = true; 11831 left.includeAsAssignmentTarget(context, includeChildrenRecursively || true, false); 11832 right.include(context, includeChildrenRecursively); 11833 includeLoopBody(context, body, includeChildrenRecursively); 11834 } 11835 initialise() { 11836 super.initialise(); 11837 this.left.setAssignedValue(UNKNOWN_EXPRESSION); 11838 } 11839 render(code, options) { 11840 this.left.render(code, options, NO_SEMICOLON); 11841 this.right.render(code, options, NO_SEMICOLON); 11842 // handle no space between "of" and the right side 11843 if (code.original.charCodeAt(this.right.start - 1) === 102 /* f */) { 11844 code.prependLeft(this.right.start, ' '); 11845 } 11846 this.body.render(code, options); 11847 } 11848 applyDeoptimizations() { 11849 this.deoptimized = true; 11850 this.left.deoptimizePath(EMPTY_PATH); 11851 this.right.deoptimizePath(UNKNOWN_PATH); 11852 this.scope.context.requestTreeshakingPass(); 11853 } 11854 } 11855 11856 class ForStatement extends NodeBase { 11857 createScope(parentScope) { 11858 this.scope = new BlockScope(parentScope); 11859 } 11860 hasEffects(context) { 11861 if (this.init?.hasEffects(context) || 11862 this.test?.hasEffects(context) || 11863 this.update?.hasEffects(context)) { 11864 return true; 11865 } 11866 return hasLoopBodyEffects(context, this.body); 11867 } 11868 include(context, includeChildrenRecursively) { 11869 this.included = true; 11870 this.init?.include(context, includeChildrenRecursively, { asSingleStatement: true }); 11871 this.test?.include(context, includeChildrenRecursively); 11872 this.update?.include(context, includeChildrenRecursively); 11873 includeLoopBody(context, this.body, includeChildrenRecursively); 11874 } 11875 render(code, options) { 11876 this.init?.render(code, options, NO_SEMICOLON); 11877 this.test?.render(code, options, NO_SEMICOLON); 11878 this.update?.render(code, options, NO_SEMICOLON); 11879 this.body.render(code, options); 11880 } 11881 } 11882 11883 class FunctionExpression extends FunctionNode { 11884 createScope(parentScope) { 11885 super.createScope((this.idScope = new ChildScope(parentScope, parentScope.context))); 11886 } 11887 parseNode(esTreeNode) { 11888 if (esTreeNode.id !== null) { 11889 this.id = new Identifier(this, this.idScope).parseNode(esTreeNode.id); 11890 } 11891 return super.parseNode(esTreeNode); 11892 } 11893 onlyFunctionCallUsed() { 11894 const isIIFE = this.parent.type === CallExpression$1 && 11895 this.parent.callee === this && 11896 (this.id === null || this.id.variable.getOnlyFunctionCallUsed()); 11897 return isIIFE || super.onlyFunctionCallUsed(); 11898 } 11899 render(code, options, { renderedSurroundingElement } = BLANK) { 11900 super.render(code, options); 11901 if (renderedSurroundingElement === ExpressionStatement$1) { 11902 code.appendRight(this.start, '('); 11903 code.prependLeft(this.end, ')'); 11904 } 11905 } 11906 } 11907 11908 class TrackingScope extends BlockScope { 11909 constructor() { 11910 super(...arguments); 11911 this.hoistedDeclarations = []; 11912 } 11913 addDeclaration(identifier, context, init, kind) { 11914 this.hoistedDeclarations.push(identifier); 11915 return super.addDeclaration(identifier, context, init, kind); 11916 } 11917 } 11918 11919 const unset = Symbol('unset'); 11920 class IfStatement extends NodeBase { 11921 constructor() { 11922 super(...arguments); 11923 this.testValue = unset; 11924 } 11925 deoptimizeCache() { 11926 this.testValue = UnknownValue; 11927 } 11928 hasEffects(context) { 11929 if (this.test.hasEffects(context)) { 11930 return true; 11931 } 11932 const testValue = this.getTestValue(); 11933 if (typeof testValue === 'symbol') { 11934 const { brokenFlow } = context; 11935 if (this.consequent.hasEffects(context)) 11936 return true; 11937 const consequentBrokenFlow = context.brokenFlow; 11938 context.brokenFlow = brokenFlow; 11939 if (this.alternate === null) 11940 return false; 11941 if (this.alternate.hasEffects(context)) 11942 return true; 11943 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 11944 return false; 11945 } 11946 return testValue ? this.consequent.hasEffects(context) : !!this.alternate?.hasEffects(context); 11947 } 11948 include(context, includeChildrenRecursively) { 11949 this.included = true; 11950 if (includeChildrenRecursively) { 11951 this.includeRecursively(includeChildrenRecursively, context); 11952 } 11953 else { 11954 const testValue = this.getTestValue(); 11955 if (typeof testValue === 'symbol') { 11956 this.includeUnknownTest(context); 11957 } 11958 else { 11959 this.includeKnownTest(context, testValue); 11960 } 11961 } 11962 } 11963 parseNode(esTreeNode) { 11964 this.consequent = new (this.scope.context.getNodeConstructor(esTreeNode.consequent.type))(this, (this.consequentScope = new TrackingScope(this.scope))).parseNode(esTreeNode.consequent); 11965 if (esTreeNode.alternate) { 11966 this.alternate = new (this.scope.context.getNodeConstructor(esTreeNode.alternate.type))(this, (this.alternateScope = new TrackingScope(this.scope))).parseNode(esTreeNode.alternate); 11967 } 11968 return super.parseNode(esTreeNode); 11969 } 11970 render(code, options) { 11971 const { snippets: { getPropertyAccess } } = options; 11972 // Note that unknown test values are always included 11973 const testValue = this.getTestValue(); 11974 const hoistedDeclarations = []; 11975 const includesIfElse = this.test.included; 11976 const noTreeshake = !this.scope.context.options.treeshake; 11977 if (includesIfElse) { 11978 this.test.render(code, options); 11979 } 11980 else { 11981 code.remove(this.start, this.consequent.start); 11982 } 11983 if (this.consequent.included && (noTreeshake || typeof testValue === 'symbol' || testValue)) { 11984 this.consequent.render(code, options); 11985 } 11986 else { 11987 code.overwrite(this.consequent.start, this.consequent.end, includesIfElse ? ';' : ''); 11988 hoistedDeclarations.push(...this.consequentScope.hoistedDeclarations); 11989 } 11990 if (this.alternate) { 11991 if (this.alternate.included && (noTreeshake || typeof testValue === 'symbol' || !testValue)) { 11992 if (includesIfElse) { 11993 if (code.original.charCodeAt(this.alternate.start - 1) === 101) { 11994 code.prependLeft(this.alternate.start, ' '); 11995 } 11996 } 11997 else { 11998 code.remove(this.consequent.end, this.alternate.start); 11999 } 12000 this.alternate.render(code, options); 12001 } 12002 else { 12003 if (includesIfElse && this.shouldKeepAlternateBranch()) { 12004 code.overwrite(this.alternate.start, this.end, ';'); 12005 } 12006 else { 12007 code.remove(this.consequent.end, this.end); 12008 } 12009 hoistedDeclarations.push(...this.alternateScope.hoistedDeclarations); 12010 } 12011 } 12012 this.renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess); 12013 } 12014 applyDeoptimizations() { } 12015 getTestValue() { 12016 if (this.testValue === unset) { 12017 return (this.testValue = this.test.getLiteralValueAtPath(EMPTY_PATH, SHARED_RECURSION_TRACKER, this)); 12018 } 12019 return this.testValue; 12020 } 12021 includeKnownTest(context, testValue) { 12022 if (this.test.shouldBeIncluded(context)) { 12023 this.test.include(context, false); 12024 } 12025 if (testValue && this.consequent.shouldBeIncluded(context)) { 12026 this.consequent.include(context, false, { asSingleStatement: true }); 12027 } 12028 if (!testValue && this.alternate?.shouldBeIncluded(context)) { 12029 this.alternate.include(context, false, { asSingleStatement: true }); 12030 } 12031 } 12032 includeRecursively(includeChildrenRecursively, context) { 12033 this.test.include(context, includeChildrenRecursively); 12034 this.consequent.include(context, includeChildrenRecursively); 12035 this.alternate?.include(context, includeChildrenRecursively); 12036 } 12037 includeUnknownTest(context) { 12038 this.test.include(context, false); 12039 const { brokenFlow } = context; 12040 let consequentBrokenFlow = false; 12041 if (this.consequent.shouldBeIncluded(context)) { 12042 this.consequent.include(context, false, { asSingleStatement: true }); 12043 consequentBrokenFlow = context.brokenFlow; 12044 context.brokenFlow = brokenFlow; 12045 } 12046 if (this.alternate?.shouldBeIncluded(context)) { 12047 this.alternate.include(context, false, { asSingleStatement: true }); 12048 context.brokenFlow = context.brokenFlow && consequentBrokenFlow; 12049 } 12050 } 12051 renderHoistedDeclarations(hoistedDeclarations, code, getPropertyAccess) { 12052 const hoistedVariables = [ 12053 ...new Set(hoistedDeclarations.map(identifier => { 12054 const variable = identifier.variable; 12055 return variable.included ? variable.getName(getPropertyAccess) : ''; 12056 })) 12057 ] 12058 .filter(Boolean) 12059 .join(', '); 12060 if (hoistedVariables) { 12061 const parentType = this.parent.type; 12062 const needsBraces = parentType !== Program$1 && parentType !== BlockStatement$1; 12063 code.prependRight(this.start, `${needsBraces ? '{ ' : ''}var ${hoistedVariables}; `); 12064 if (needsBraces) { 12065 code.appendLeft(this.end, ` }`); 12066 } 12067 } 12068 } 12069 shouldKeepAlternateBranch() { 12070 let currentParent = this.parent; 12071 do { 12072 if (currentParent instanceof IfStatement && currentParent.alternate) { 12073 return true; 12074 } 12075 if (currentParent instanceof BlockStatement) { 12076 return false; 12077 } 12078 currentParent = currentParent.parent; 12079 } while (currentParent); 12080 return false; 12081 } 12082 } 12083 12084 class ImportAttribute extends NodeBase { 12085 } 12086 12087 class ImportDeclaration extends NodeBase { 12088 // Do not bind specifiers or attributes 12089 bind() { } 12090 hasEffects() { 12091 return false; 12092 } 12093 initialise() { 12094 super.initialise(); 12095 this.scope.context.addImport(this); 12096 } 12097 render(code, _options, nodeRenderOptions) { 12098 code.remove(nodeRenderOptions.start, nodeRenderOptions.end); 12099 } 12100 applyDeoptimizations() { } 12101 } 12102 ImportDeclaration.prototype.needsBoundaries = true; 12103 12104 class ImportDefaultSpecifier extends NodeBase { 12105 applyDeoptimizations() { } 12106 } 12107 10668 12108 function isReassignedExportsMember(variable, exportNamesByVariable) { 10669 12109 return (variable.renderBaseName !== null && exportNamesByVariable.has(variable) && variable.isReassigned); … … 11024 12464 } 11025 12465 12466 class JSXIdentifier extends IdentifierBase { 12467 constructor() { 12468 super(...arguments); 12469 this.isNativeElement = false; 12470 } 12471 bind() { 12472 const type = this.getType(); 12473 if (type === 0 /* IdentifierType.Reference */) { 12474 this.variable = this.scope.findVariable(this.name); 12475 this.variable.addReference(this); 12476 } 12477 else if (type === 1 /* IdentifierType.NativeElementName */) { 12478 this.isNativeElement = true; 12479 } 12480 } 12481 render(code, { snippets: { getPropertyAccess }, useOriginalName }) { 12482 if (this.variable) { 12483 const name = this.variable.getName(getPropertyAccess, useOriginalName); 12484 if (name !== this.name) { 12485 code.overwrite(this.start, this.end, name, { 12486 contentOnly: true, 12487 storeName: true 12488 }); 12489 } 12490 } 12491 else if (this.isNativeElement && 12492 this.scope.context.options.jsx.mode !== 'preserve') { 12493 code.update(this.start, this.end, JSON.stringify(this.name)); 12494 } 12495 } 12496 getType() { 12497 switch (this.parent.type) { 12498 case 'JSXOpeningElement': 12499 case 'JSXClosingElement': { 12500 return this.name.startsWith(this.name.charAt(0).toUpperCase()) 12501 ? 0 /* IdentifierType.Reference */ 12502 : 1 /* IdentifierType.NativeElementName */; 12503 } 12504 case 'JSXMemberExpression': { 12505 return this.parent.object === this 12506 ? 0 /* IdentifierType.Reference */ 12507 : 2 /* IdentifierType.Other */; 12508 } 12509 case 'JSXAttribute': 12510 case 'JSXNamespacedName': { 12511 return 2 /* IdentifierType.Other */; 12512 } 12513 default: { 12514 /* istanbul ignore next */ 12515 throw new Error(`Unexpected parent node type for JSXIdentifier: ${this.parent.type}`); 12516 } 12517 } 12518 } 12519 } 12520 12521 class JSXAttribute extends NodeBase { 12522 render(code, options, { jsxMode } = BLANK) { 12523 super.render(code, options); 12524 if (['classic', 'automatic'].includes(jsxMode)) { 12525 const { name, value } = this; 12526 const key = name instanceof JSXIdentifier ? name.name : `${name.namespace.name}:${name.name.name}`; 12527 if (!(jsxMode === 'automatic' && key === 'key')) { 12528 const safeKey = stringifyObjectKeyIfNeeded(key); 12529 if (key !== safeKey) { 12530 code.overwrite(name.start, name.end, safeKey, { contentOnly: true }); 12531 } 12532 if (value) { 12533 code.overwrite(name.end, value.start, ': ', { contentOnly: true }); 12534 } 12535 else { 12536 code.appendLeft(name.end, ': true'); 12537 } 12538 } 12539 } 12540 } 12541 } 12542 12543 class JSXClosingBase extends NodeBase { 12544 render(code, options) { 12545 const { mode } = this.scope.context.options.jsx; 12546 if (mode !== 'preserve') { 12547 code.overwrite(this.start, this.end, ')', { contentOnly: true }); 12548 } 12549 else { 12550 super.render(code, options); 12551 } 12552 } 12553 } 12554 12555 class JSXClosingElement extends JSXClosingBase { 12556 } 12557 12558 class JSXClosingFragment extends JSXClosingBase { 12559 } 12560 12561 class JSXSpreadAttribute extends NodeBase { 12562 render(code, options) { 12563 this.argument.render(code, options); 12564 const { mode } = this.scope.context.options.jsx; 12565 if (mode !== 'preserve') { 12566 code.overwrite(this.start, this.argument.start, '', { contentOnly: true }); 12567 code.overwrite(this.argument.end, this.end, '', { contentOnly: true }); 12568 } 12569 } 12570 } 12571 12572 class JSXEmptyExpression extends NodeBase { 12573 } 12574 12575 class JSXExpressionContainer extends NodeBase { 12576 render(code, options) { 12577 const { mode } = this.scope.context.options.jsx; 12578 if (mode !== 'preserve') { 12579 code.remove(this.start, this.expression.start); 12580 code.remove(this.expression.end, this.end); 12581 } 12582 this.expression.render(code, options); 12583 } 12584 } 12585 12586 function getRenderedJsxChildren(children) { 12587 let renderedChildren = 0; 12588 for (const child of children) { 12589 if (!(child instanceof JSXExpressionContainer && child.expression instanceof JSXEmptyExpression)) { 12590 renderedChildren++; 12591 } 12592 } 12593 return renderedChildren; 12594 } 12595 12596 function getAndIncludeFactoryVariable(factory, preserve, importSource, node) { 12597 const [baseName, nestedName] = factory.split('.'); 12598 let factoryVariable; 12599 if (importSource) { 12600 factoryVariable = node.scope.context.getImportedJsxFactoryVariable(nestedName ? 'default' : baseName, node.start, importSource); 12601 if (preserve) { 12602 // This pretends we are accessing an included global variable of the same name 12603 const globalVariable = node.scope.findGlobal(baseName); 12604 globalVariable.include(); 12605 // This excludes this variable from renaming 12606 factoryVariable.globalName = baseName; 12607 } 12608 } 12609 else { 12610 factoryVariable = node.scope.findGlobal(baseName); 12611 } 12612 node.scope.context.includeVariableInModule(factoryVariable); 12613 if (factoryVariable instanceof LocalVariable) { 12614 factoryVariable.consolidateInitializers(); 12615 factoryVariable.addUsedPlace(node); 12616 node.scope.context.requestTreeshakingPass(); 12617 } 12618 return factoryVariable; 12619 } 12620 12621 class JSXElementBase extends NodeBase { 12622 constructor() { 12623 super(...arguments); 12624 this.factoryVariable = null; 12625 this.factory = null; 12626 } 12627 initialise() { 12628 super.initialise(); 12629 const { importSource } = (this.jsxMode = this.getRenderingMode()); 12630 if (importSource) { 12631 this.scope.context.addImportSource(importSource); 12632 } 12633 } 12634 include(context, includeChildrenRecursively) { 12635 if (!this.included) { 12636 const { factory, importSource, mode } = this.jsxMode; 12637 if (factory) { 12638 this.factory = factory; 12639 this.factoryVariable = getAndIncludeFactoryVariable(factory, mode === 'preserve', importSource, this); 12640 } 12641 } 12642 super.include(context, includeChildrenRecursively); 12643 } 12644 applyDeoptimizations() { } 12645 getRenderingMode() { 12646 const jsx = this.scope.context.options.jsx; 12647 const { mode, factory, importSource } = jsx; 12648 if (mode === 'automatic') { 12649 return { 12650 factory: getRenderedJsxChildren(this.children) > 1 ? 'jsxs' : 'jsx', 12651 importSource: jsx.jsxImportSource, 12652 mode 12653 }; 12654 } 12655 return { factory, importSource, mode }; 12656 } 12657 renderChildren(code, options, openingEnd) { 12658 const { children } = this; 12659 let hasMultipleChildren = false; 12660 let childrenEnd = openingEnd; 12661 let firstChild = null; 12662 for (const child of children) { 12663 if (child instanceof JSXExpressionContainer && 12664 child.expression instanceof JSXEmptyExpression) { 12665 code.remove(childrenEnd, child.end); 12666 } 12667 else { 12668 code.appendLeft(childrenEnd, ', '); 12669 child.render(code, options); 12670 if (firstChild) { 12671 hasMultipleChildren = true; 12672 } 12673 else { 12674 firstChild = child; 12675 } 12676 } 12677 childrenEnd = child.end; 12678 } 12679 return { childrenEnd, firstChild, hasMultipleChildren }; 12680 } 12681 } 12682 12683 class JSXElement extends JSXElementBase { 12684 render(code, options) { 12685 switch (this.jsxMode.mode) { 12686 case 'classic': { 12687 this.renderClassicMode(code, options); 12688 break; 12689 } 12690 case 'automatic': { 12691 this.renderAutomaticMode(code, options); 12692 break; 12693 } 12694 default: { 12695 super.render(code, options); 12696 } 12697 } 12698 } 12699 getRenderingMode() { 12700 const jsx = this.scope.context.options.jsx; 12701 const { mode, factory, importSource } = jsx; 12702 if (mode === 'automatic') { 12703 // In the case there is a key after a spread attribute, we fall back to 12704 // classic mode, see https://github.com/facebook/react/issues/20031#issuecomment-710346866 12705 // for reasoning. 12706 let hasSpread = false; 12707 for (const attribute of this.openingElement.attributes) { 12708 if (attribute instanceof JSXSpreadAttribute) { 12709 hasSpread = true; 12710 } 12711 else if (hasSpread && attribute.name.name === 'key') { 12712 return { factory, importSource, mode: 'classic' }; 12713 } 12714 } 12715 } 12716 return super.getRenderingMode(); 12717 } 12718 renderClassicMode(code, options) { 12719 const { snippets: { getPropertyAccess }, useOriginalName } = options; 12720 const { closingElement, end, factory, factoryVariable, openingElement: { end: openingEnd, selfClosing } } = this; 12721 const [, ...nestedName] = factory.split('.'); 12722 const { firstAttribute, hasAttributes, hasSpread, inObject, previousEnd } = this.renderAttributes(code, options, [factoryVariable.getName(getPropertyAccess, useOriginalName), ...nestedName].join('.'), false); 12723 this.wrapAttributes(code, inObject, hasAttributes, hasSpread, firstAttribute, 'null', previousEnd); 12724 this.renderChildren(code, options, openingEnd); 12725 if (selfClosing) { 12726 code.appendLeft(end, ')'); 12727 } 12728 else { 12729 closingElement.render(code, options); 12730 } 12731 } 12732 renderAutomaticMode(code, options) { 12733 const { snippets: { getPropertyAccess }, useOriginalName } = options; 12734 const { closingElement, end, factoryVariable, openingElement: { end: openindEnd, selfClosing } } = this; 12735 let { firstAttribute, hasAttributes, hasSpread, inObject, keyAttribute, previousEnd } = this.renderAttributes(code, options, factoryVariable.getName(getPropertyAccess, useOriginalName), true); 12736 const { firstChild, hasMultipleChildren, childrenEnd } = this.renderChildren(code, options, openindEnd); 12737 if (firstChild) { 12738 code.prependRight(firstChild.start, `children: ${hasMultipleChildren ? '[' : ''}`); 12739 if (!inObject) { 12740 code.prependRight(firstChild.start, '{ '); 12741 inObject = true; 12742 } 12743 previousEnd = closingElement.start; 12744 if (hasMultipleChildren) { 12745 code.appendLeft(previousEnd, ']'); 12746 } 12747 } 12748 this.wrapAttributes(code, inObject, hasAttributes || !!firstChild, hasSpread, firstAttribute || firstChild, '{}', childrenEnd); 12749 if (keyAttribute) { 12750 const { value } = keyAttribute; 12751 // This will appear to the left of the moved code... 12752 code.appendLeft(childrenEnd, ', '); 12753 if (value) { 12754 code.move(value.start, value.end, childrenEnd); 12755 } 12756 else { 12757 code.appendLeft(childrenEnd, 'true'); 12758 } 12759 } 12760 if (selfClosing) { 12761 // Moving the key attribute will also move the parenthesis to the right position 12762 code.appendLeft(keyAttribute?.value?.end || end, ')'); 12763 } 12764 else { 12765 closingElement.render(code, options); 12766 } 12767 } 12768 renderAttributes(code, options, factoryName, extractKeyAttribute) { 12769 const { jsxMode: { mode }, openingElement } = this; 12770 const { attributes, end: openingEnd, start: openingStart, name: { start: nameStart, end: nameEnd } } = openingElement; 12771 code.update(openingStart, nameStart, `/*#__PURE__*/${factoryName}(`); 12772 openingElement.render(code, options, { jsxMode: mode }); 12773 let keyAttribute = null; 12774 let hasSpread = false; 12775 let inObject = false; 12776 let previousEnd = nameEnd; 12777 let hasAttributes = false; 12778 let firstAttribute = null; 12779 for (const attribute of attributes) { 12780 if (attribute instanceof JSXAttribute) { 12781 if (extractKeyAttribute && attribute.name.name === 'key') { 12782 keyAttribute = attribute; 12783 code.remove(previousEnd, attribute.value?.start || attribute.end); 12784 continue; 12785 } 12786 code.appendLeft(previousEnd, ','); 12787 if (!inObject) { 12788 code.prependRight(attribute.start, '{ '); 12789 inObject = true; 12790 } 12791 hasAttributes = true; 12792 } 12793 else { 12794 if (inObject) { 12795 if (hasAttributes) { 12796 code.appendLeft(previousEnd, ' '); 12797 } 12798 code.appendLeft(previousEnd, '},'); 12799 inObject = false; 12800 } 12801 else { 12802 code.appendLeft(previousEnd, ','); 12803 } 12804 hasSpread = true; 12805 } 12806 previousEnd = attribute.end; 12807 if (!firstAttribute) { 12808 firstAttribute = attribute; 12809 } 12810 } 12811 code.remove(attributes.at(-1)?.end || previousEnd, openingEnd); 12812 return { firstAttribute, hasAttributes, hasSpread, inObject, keyAttribute, previousEnd }; 12813 } 12814 wrapAttributes(code, inObject, hasAttributes, hasSpread, firstAttribute, missingAttributesFallback, attributesEnd) { 12815 if (inObject) { 12816 code.appendLeft(attributesEnd, ' }'); 12817 } 12818 if (hasSpread) { 12819 if (hasAttributes) { 12820 const { start } = firstAttribute; 12821 if (firstAttribute instanceof JSXSpreadAttribute) { 12822 code.prependRight(start, '{}, '); 12823 } 12824 code.prependRight(start, 'Object.assign('); 12825 code.appendLeft(attributesEnd, ')'); 12826 } 12827 } 12828 else if (!hasAttributes) { 12829 code.appendLeft(attributesEnd, `, ${missingAttributesFallback}`); 12830 } 12831 } 12832 } 12833 12834 class JSXFragment extends JSXElementBase { 12835 render(code, options) { 12836 switch (this.jsxMode.mode) { 12837 case 'classic': { 12838 this.renderClassicMode(code, options); 12839 break; 12840 } 12841 case 'automatic': { 12842 this.renderAutomaticMode(code, options); 12843 break; 12844 } 12845 default: { 12846 super.render(code, options); 12847 } 12848 } 12849 } 12850 renderClassicMode(code, options) { 12851 const { snippets: { getPropertyAccess }, useOriginalName } = options; 12852 const { closingFragment, factory, factoryVariable, openingFragment, start } = this; 12853 const [, ...nestedName] = factory.split('.'); 12854 openingFragment.render(code, options); 12855 code.prependRight(start, `/*#__PURE__*/${[ 12856 factoryVariable.getName(getPropertyAccess, useOriginalName), 12857 ...nestedName 12858 ].join('.')}(`); 12859 code.appendLeft(openingFragment.end, ', null'); 12860 this.renderChildren(code, options, openingFragment.end); 12861 closingFragment.render(code, options); 12862 } 12863 renderAutomaticMode(code, options) { 12864 const { snippets: { getPropertyAccess }, useOriginalName } = options; 12865 const { closingFragment, factoryVariable, openingFragment, start } = this; 12866 openingFragment.render(code, options); 12867 code.prependRight(start, `/*#__PURE__*/${factoryVariable.getName(getPropertyAccess, useOriginalName)}(`); 12868 const { firstChild, hasMultipleChildren, childrenEnd } = this.renderChildren(code, options, openingFragment.end); 12869 if (firstChild) { 12870 code.prependRight(firstChild.start, `{ children: ${hasMultipleChildren ? '[' : ''}`); 12871 if (hasMultipleChildren) { 12872 code.appendLeft(closingFragment.start, ']'); 12873 } 12874 code.appendLeft(childrenEnd, ' }'); 12875 } 12876 else { 12877 code.appendLeft(openingFragment.end, ', {}'); 12878 } 12879 closingFragment.render(code, options); 12880 } 12881 } 12882 12883 class JSXMemberExpression extends NodeBase { 12884 } 12885 12886 class JSXNamespacedName extends NodeBase { 12887 } 12888 12889 class JSXOpeningElement extends NodeBase { 12890 render(code, options, { jsxMode = this.scope.context.options.jsx.mode } = {}) { 12891 this.name.render(code, options); 12892 for (const attribute of this.attributes) { 12893 attribute.render(code, options, { jsxMode }); 12894 } 12895 } 12896 } 12897 12898 class JSXOpeningFragment extends NodeBase { 12899 constructor() { 12900 super(...arguments); 12901 this.fragment = null; 12902 this.fragmentVariable = null; 12903 } 12904 include(context, includeChildrenRecursively) { 12905 if (!this.included) { 12906 const jsx = this.scope.context.options.jsx; 12907 if (jsx.mode === 'automatic') { 12908 this.fragment = 'Fragment'; 12909 this.fragmentVariable = getAndIncludeFactoryVariable('Fragment', false, jsx.jsxImportSource, this); 12910 } 12911 else { 12912 const { fragment, importSource, mode } = jsx; 12913 if (fragment != null) { 12914 this.fragment = fragment; 12915 this.fragmentVariable = getAndIncludeFactoryVariable(fragment, mode === 'preserve', importSource, this); 12916 } 12917 } 12918 } 12919 super.include(context, includeChildrenRecursively); 12920 } 12921 render(code, options) { 12922 const { mode } = this.scope.context.options.jsx; 12923 if (mode !== 'preserve') { 12924 const { snippets: { getPropertyAccess }, useOriginalName } = options; 12925 const [, ...nestedFragment] = this.fragment.split('.'); 12926 const fragment = [ 12927 this.fragmentVariable.getName(getPropertyAccess, useOriginalName), 12928 ...nestedFragment 12929 ].join('.'); 12930 code.update(this.start, this.end, fragment); 12931 } 12932 } 12933 } 12934 12935 class JSXSpreadChild extends NodeBase { 12936 render(code, options) { 12937 super.render(code, options); 12938 const { mode } = this.scope.context.options.jsx; 12939 if (mode !== 'preserve') { 12940 code.overwrite(this.start, this.expression.start, '...', { contentOnly: true }); 12941 code.overwrite(this.expression.end, this.end, '', { contentOnly: true }); 12942 } 12943 } 12944 } 12945 12946 class JSXText extends NodeBase { 12947 render(code) { 12948 const { mode } = this.scope.context.options.jsx; 12949 if (mode !== 'preserve') { 12950 code.overwrite(this.start, this.end, JSON.stringify(this.value), { 12951 contentOnly: true 12952 }); 12953 } 12954 } 12955 } 12956 11026 12957 class LabeledStatement extends NodeBase { 11027 12958 hasEffects(context) { … … 11211 13142 } 11212 13143 11213 const FILE_PREFIX = 'ROLLUP_FILE_URL_';11214 const IMPORT = 'import';11215 class MetaProperty extends NodeBase {11216 constructor() {11217 super(...arguments);11218 this.metaProperty = null;11219 this.preliminaryChunkId = null;11220 this.referenceId = null;11221 }11222 getReferencedFileName(outputPluginDriver) {11223 const { meta: { name }, metaProperty } = this;11224 if (name === IMPORT && metaProperty?.startsWith(FILE_PREFIX)) {11225 return outputPluginDriver.getFileName(metaProperty.slice(FILE_PREFIX.length));11226 }11227 return null;11228 }11229 hasEffects() {11230 return false;11231 }11232 hasEffectsOnInteractionAtPath(path, { type }) {11233 return path.length > 1 || type !== INTERACTION_ACCESSED;11234 }11235 include() {11236 if (!this.included) {11237 this.included = true;11238 if (this.meta.name === IMPORT) {11239 this.scope.context.addImportMeta(this);11240 const parent = this.parent;11241 const metaProperty = (this.metaProperty =11242 parent instanceof MemberExpression && typeof parent.propertyKey === 'string'11243 ? parent.propertyKey11244 : null);11245 if (metaProperty?.startsWith(FILE_PREFIX)) {11246 this.referenceId = metaProperty.slice(FILE_PREFIX.length);11247 }11248 }11249 }11250 }11251 render(code, renderOptions) {11252 const { format, pluginDriver, snippets } = renderOptions;11253 const { scope: { context: { module } }, meta: { name }, metaProperty, parent, preliminaryChunkId, referenceId, start, end } = this;11254 const { id: moduleId } = module;11255 if (name !== IMPORT)11256 return;11257 const chunkId = preliminaryChunkId;11258 if (referenceId) {11259 const fileName = pluginDriver.getFileName(referenceId);11260 const relativePath = normalize(relative(dirname(chunkId), fileName));11261 const replacement = pluginDriver.hookFirstSync('resolveFileUrl', [11262 { chunkId, fileName, format, moduleId, referenceId, relativePath }11263 ]) || relativeUrlMechanisms[format](relativePath);11264 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true });11265 return;11266 }11267 let replacement = pluginDriver.hookFirstSync('resolveImportMeta', [11268 metaProperty,11269 { chunkId, format, moduleId }11270 ]);11271 if (!replacement) {11272 replacement = importMetaMechanisms[format]?.(metaProperty, { chunkId, snippets });11273 renderOptions.accessedDocumentCurrentScript ||=11274 formatsMaybeAccessDocumentCurrentScript.includes(format) && replacement !== 'undefined';11275 }11276 if (typeof replacement === 'string') {11277 if (parent instanceof MemberExpression) {11278 code.overwrite(parent.start, parent.end, replacement, { contentOnly: true });11279 }11280 else {11281 code.overwrite(start, end, replacement, { contentOnly: true });11282 }11283 }11284 }11285 setResolution(format, accessedGlobalsByScope, preliminaryChunkId) {11286 this.preliminaryChunkId = preliminaryChunkId;11287 const accessedGlobals = (this.metaProperty?.startsWith(FILE_PREFIX) ? accessedFileUrlGlobals : accessedMetaUrlGlobals)[format];11288 if (accessedGlobals.length > 0) {11289 this.scope.addAccessedGlobals(accessedGlobals, accessedGlobalsByScope);11290 }11291 }11292 }11293 const formatsMaybeAccessDocumentCurrentScript = ['cjs', 'iife', 'umd'];11294 const accessedMetaUrlGlobals = {11295 amd: ['document', 'module', 'URL'],11296 cjs: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT],11297 es: [],11298 iife: ['document', 'URL', DOCUMENT_CURRENT_SCRIPT],11299 system: ['module'],11300 umd: ['document', 'require', 'URL', DOCUMENT_CURRENT_SCRIPT]11301 };11302 const accessedFileUrlGlobals = {11303 amd: ['document', 'require', 'URL'],11304 cjs: ['document', 'require', 'URL'],11305 es: [],11306 iife: ['document', 'URL'],11307 system: ['module', 'URL'],11308 umd: ['document', 'require', 'URL']11309 };11310 const getResolveUrl = (path, URL = 'URL') => `new ${URL}(${path}).href`;11311 const getRelativeUrlFromDocument = (relativePath, umd = false) => getResolveUrl(`'${escapeId(relativePath)}', ${umd ? `typeof document === 'undefined' ? location.href : ` : ''}document.currentScript && document.currentScript.src || document.baseURI`);11312 const getGenericImportMetaMechanism = (getUrl) => (property, { chunkId }) => {11313 const urlMechanism = getUrl(chunkId);11314 return property === null11315 ? `({ url: ${urlMechanism} })`11316 : property === 'url'11317 ? urlMechanism11318 : 'undefined';11319 };11320 const getFileUrlFromFullPath = (path) => `require('u' + 'rl').pathToFileURL(${path}).href`;11321 const getFileUrlFromRelativePath = (path) => getFileUrlFromFullPath(`__dirname + '/${escapeId(path)}'`);11322 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)`;11323 const relativeUrlMechanisms = {11324 amd: relativePath => {11325 if (relativePath[0] !== '.')11326 relativePath = './' + relativePath;11327 return getResolveUrl(`require.toUrl('${escapeId(relativePath)}'), document.baseURI`);11328 },11329 cjs: relativePath => `(typeof document === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath)})`,11330 es: relativePath => getResolveUrl(`'${escapeId(relativePath)}', import.meta.url`),11331 iife: relativePath => getRelativeUrlFromDocument(relativePath),11332 system: relativePath => getResolveUrl(`'${escapeId(relativePath)}', module.meta.url`),11333 umd: relativePath => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromRelativePath(relativePath)} : ${getRelativeUrlFromDocument(relativePath, true)})`11334 };11335 const importMetaMechanisms = {11336 amd: getGenericImportMetaMechanism(() => getResolveUrl(`module.uri, document.baseURI`)),11337 cjs: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId)})`),11338 iife: getGenericImportMetaMechanism(chunkId => getUrlFromDocument(chunkId)),11339 system: (property, { snippets: { getPropertyAccess } }) => property === null ? `module.meta` : `module.meta${getPropertyAccess(property)}`,11340 umd: getGenericImportMetaMechanism(chunkId => `(typeof document === 'undefined' && typeof location === 'undefined' ? ${getFileUrlFromFullPath('__filename')} : ${getUrlFromDocument(chunkId, true)})`)11341 };11342 11343 13144 class NewExpression extends NodeBase { 11344 13145 hasEffects(context) { … … 11775 13576 render(code, options, nodeRenderOptions) { 11776 13577 if (this.consequent.length > 0) { 11777 this.test && this.test.render(code, options); 13578 if (this.test) { 13579 this.test.render(code, options); 13580 } 11778 13581 const testEnd = this.test 11779 13582 ? this.test.end … … 11987 13790 code.indentExclusionRanges.push([this.start, this.end]); 11988 13791 super.render(code, options); 11989 }11990 }11991 11992 class UndefinedVariable extends Variable {11993 constructor() {11994 super('undefined');11995 }11996 getLiteralValueAtPath() {11997 return undefined;11998 }11999 }12000 12001 class ExportDefaultVariable extends LocalVariable {12002 constructor(name, exportDefaultDeclaration, context) {12003 super(name, exportDefaultDeclaration, exportDefaultDeclaration.declaration, context, 'other');12004 this.hasId = false;12005 this.originalId = null;12006 this.originalVariable = null;12007 const declaration = exportDefaultDeclaration.declaration;12008 if ((declaration instanceof FunctionDeclaration || declaration instanceof ClassDeclaration) &&12009 declaration.id) {12010 this.hasId = true;12011 this.originalId = declaration.id;12012 }12013 else if (declaration instanceof Identifier) {12014 this.originalId = declaration;12015 }12016 }12017 addReference(identifier) {12018 if (!this.hasId) {12019 this.name = identifier.name;12020 }12021 }12022 addUsedPlace(usedPlace) {12023 const original = this.getOriginalVariable();12024 if (original === this) {12025 super.addUsedPlace(usedPlace);12026 }12027 else {12028 original.addUsedPlace(usedPlace);12029 }12030 }12031 forbidName(name) {12032 const original = this.getOriginalVariable();12033 if (original === this) {12034 super.forbidName(name);12035 }12036 else {12037 original.forbidName(name);12038 }12039 }12040 getAssignedVariableName() {12041 return (this.originalId && this.originalId.name) || null;12042 }12043 getBaseVariableName() {12044 const original = this.getOriginalVariable();12045 return original === this ? super.getBaseVariableName() : original.getBaseVariableName();12046 }12047 getDirectOriginalVariable() {12048 return this.originalId &&12049 (this.hasId ||12050 !(this.originalId.isPossibleTDZ() ||12051 this.originalId.variable.isReassigned ||12052 this.originalId.variable instanceof UndefinedVariable ||12053 // this avoids a circular dependency12054 'syntheticNamespace' in this.originalId.variable))12055 ? this.originalId.variable12056 : null;12057 }12058 getName(getPropertyAccess) {12059 const original = this.getOriginalVariable();12060 return original === this12061 ? super.getName(getPropertyAccess)12062 : original.getName(getPropertyAccess);12063 }12064 getOriginalVariable() {12065 if (this.originalVariable)12066 return this.originalVariable;12067 // eslint-disable-next-line @typescript-eslint/no-this-alias12068 let original = this;12069 let currentVariable;12070 const checkedVariables = new Set();12071 do {12072 checkedVariables.add(original);12073 currentVariable = original;12074 original = currentVariable.getDirectOriginalVariable();12075 } while (original instanceof ExportDefaultVariable && !checkedVariables.has(original));12076 return (this.originalVariable = original || currentVariable);12077 13792 } 12078 13793 } … … 12568 14283 'ImportNamespaceSpecifier', 12569 14284 'ImportSpecifier', 14285 'JSXAttribute', 14286 'JSXClosingElement', 14287 'JSXClosingFragment', 14288 'JSXElement', 14289 'JSXEmptyExpression', 14290 'JSXExpressionContainer', 14291 'JSXFragment', 14292 'JSXIdentifier', 14293 'JSXMemberExpression', 14294 'JSXNamespacedName', 14295 'JSXOpeningElement', 14296 'JSXOpeningFragment', 14297 'JSXSpreadAttribute', 14298 'JSXSpreadChild', 14299 'JSXText', 12570 14300 'LabeledStatement', 12571 14301 'Literal', … … 12650 14380 ImportNamespaceSpecifier, 12651 14381 ImportSpecifier, 14382 JSXAttribute, 14383 JSXClosingElement, 14384 JSXClosingFragment, 14385 JSXElement, 14386 JSXEmptyExpression, 14387 JSXExpressionContainer, 14388 JSXFragment, 14389 JSXIdentifier, 14390 JSXMemberExpression, 14391 JSXNamespacedName, 14392 JSXOpeningElement, 14393 JSXOpeningFragment, 14394 JSXSpreadAttribute, 14395 JSXSpreadChild, 14396 JSXText, 12652 14397 LabeledStatement, 12653 14398 Literal, … … 12769 14514 const { scope } = node; 12770 14515 const bodyPosition = buffer[position]; 12771 const body = (node.body = []);12772 14516 if (bodyPosition) { 12773 14517 const length = buffer[bodyPosition]; 14518 const body = (node.body = new Array(length)); 12774 14519 for (let index = 0; index < length; index++) { 12775 14520 const nodePosition = buffer[bodyPosition + 1 + index]; 12776 body.push(convertNode(node, (buffer[nodePosition + 3] & 1) === 0 ? scope.instanceScope : scope, nodePosition, buffer)); 12777 } 14521 body[index] = convertNode(node, (buffer[nodePosition + 3] & 1) === 0 ? scope.instanceScope : scope, nodePosition, buffer); 14522 } 14523 } 14524 else { 14525 node.body = []; 12778 14526 } 12779 14527 }, … … 12955 14703 node.imported = 12956 14704 importedPosition === 0 ? node.local : convertNode(node, scope, importedPosition, buffer); 14705 }, 14706 function jsxAttribute(node, position, buffer) { 14707 const { scope } = node; 14708 node.name = convertNode(node, scope, buffer[position], buffer); 14709 const valuePosition = buffer[position + 1]; 14710 node.value = valuePosition === 0 ? null : convertNode(node, scope, valuePosition, buffer); 14711 }, 14712 function jsxClosingElement(node, position, buffer) { 14713 const { scope } = node; 14714 node.name = convertNode(node, scope, buffer[position], buffer); 14715 }, 14716 function jsxClosingFragment() { }, 14717 function jsxElement(node, position, buffer) { 14718 const { scope } = node; 14719 node.openingElement = convertNode(node, scope, buffer[position], buffer); 14720 node.children = convertNodeList(node, scope, buffer[position + 1], buffer); 14721 const closingElementPosition = buffer[position + 2]; 14722 node.closingElement = 14723 closingElementPosition === 0 14724 ? null 14725 : convertNode(node, scope, closingElementPosition, buffer); 14726 }, 14727 function jsxEmptyExpression() { }, 14728 function jsxExpressionContainer(node, position, buffer) { 14729 const { scope } = node; 14730 node.expression = convertNode(node, scope, buffer[position], buffer); 14731 }, 14732 function jsxFragment(node, position, buffer) { 14733 const { scope } = node; 14734 node.openingFragment = convertNode(node, scope, buffer[position], buffer); 14735 node.children = convertNodeList(node, scope, buffer[position + 1], buffer); 14736 node.closingFragment = convertNode(node, scope, buffer[position + 2], buffer); 14737 }, 14738 function jsxIdentifier(node, position, buffer) { 14739 node.name = buffer.convertString(buffer[position]); 14740 }, 14741 function jsxMemberExpression(node, position, buffer) { 14742 const { scope } = node; 14743 node.object = convertNode(node, scope, buffer[position], buffer); 14744 node.property = convertNode(node, scope, buffer[position + 1], buffer); 14745 }, 14746 function jsxNamespacedName(node, position, buffer) { 14747 const { scope } = node; 14748 node.namespace = convertNode(node, scope, buffer[position], buffer); 14749 node.name = convertNode(node, scope, buffer[position + 1], buffer); 14750 }, 14751 function jsxOpeningElement(node, position, buffer) { 14752 const { scope } = node; 14753 const flags = buffer[position]; 14754 node.selfClosing = (flags & 1) === 1; 14755 node.name = convertNode(node, scope, buffer[position + 1], buffer); 14756 node.attributes = convertNodeList(node, scope, buffer[position + 2], buffer); 14757 }, 14758 function jsxOpeningFragment(node) { 14759 node.attributes = []; 14760 node.selfClosing = false; 14761 }, 14762 function jsxSpreadAttribute(node, position, buffer) { 14763 const { scope } = node; 14764 node.argument = convertNode(node, scope, buffer[position], buffer); 14765 }, 14766 function jsxSpreadChild(node, position, buffer) { 14767 const { scope } = node; 14768 node.expression = convertNode(node, scope, buffer[position], buffer); 14769 }, 14770 function jsxText(node, position, buffer) { 14771 node.value = buffer.convertString(buffer[position]); 14772 node.raw = buffer.convertString(buffer[position + 1]); 12957 14773 }, 12958 14774 function labeledStatement(node, position, buffer) { … … 13186 15002 return EMPTY_ARRAY; 13187 15003 const length = buffer[position++]; 13188 const list = [];15004 const list = new Array(length); 13189 15005 for (let index = 0; index < length; index++) { 13190 15006 const nodePosition = buffer[position++]; 13191 list .push(nodePosition ? convertNode(parent, parentScope, nodePosition, buffer) : null);15007 list[index] = nodePosition ? convertNode(parent, parentScope, nodePosition, buffer) : null; 13192 15008 } 13193 15009 return list; … … 13245 15061 ImportNamespaceSpecifier, 13246 15062 ImportSpecifier, 15063 JSXAttribute, 15064 JSXClosingElement, 15065 JSXClosingFragment, 15066 JSXElement, 15067 JSXEmptyExpression, 15068 JSXExpressionContainer, 15069 JSXFragment, 15070 JSXIdentifier, 15071 JSXMemberExpression, 15072 JSXNamespacedName, 15073 JSXOpeningElement, 15074 JSXOpeningFragment, 15075 JSXSpreadAttribute, 15076 JSXSpreadChild, 15077 JSXText, 13247 15078 LabeledStatement, 13248 15079 Literal, … … 13283 15114 }; 13284 15115 13285 const MISSING_EXPORT_SHIM_VARIABLE = '_missingExportShim';13286 13287 15116 class ExportShimVariable extends Variable { 13288 15117 constructor(module) { … … 13293 15122 super.include(); 13294 15123 this.module.needsExportShim = true; 13295 }13296 }13297 13298 class NamespaceVariable extends Variable {13299 constructor(context) {13300 super(context.getModuleName());13301 this.memberVariables = null;13302 this.mergedNamespaces = [];13303 this.referencedEarly = false;13304 this.references = [];13305 this.context = context;13306 this.module = context.module;13307 }13308 addReference(identifier) {13309 this.references.push(identifier);13310 this.name = identifier.name;13311 }13312 deoptimizeArgumentsOnInteractionAtPath(interaction, path, recursionTracker) {13313 if (path.length > 1 || (path.length === 1 && interaction.type === INTERACTION_CALLED)) {13314 const key = path[0];13315 if (typeof key === 'string') {13316 this.getMemberVariables()[key]?.deoptimizeArgumentsOnInteractionAtPath(interaction, path.slice(1), recursionTracker);13317 }13318 else {13319 deoptimizeInteraction(interaction);13320 }13321 }13322 }13323 deoptimizePath(path) {13324 if (path.length > 1) {13325 const key = path[0];13326 if (typeof key === 'string') {13327 this.getMemberVariables()[key]?.deoptimizePath(path.slice(1));13328 }13329 }13330 }13331 getLiteralValueAtPath(path) {13332 if (path[0] === SymbolToStringTag) {13333 return 'Module';13334 }13335 return UnknownValue;13336 }13337 getMemberVariables() {13338 if (this.memberVariables) {13339 return this.memberVariables;13340 }13341 const memberVariables = Object.create(null);13342 const sortedExports = [...this.context.getExports(), ...this.context.getReexports()].sort();13343 for (const name of sortedExports) {13344 if (name[0] !== '*' && name !== this.module.info.syntheticNamedExports) {13345 const exportedVariable = this.context.traceExport(name);13346 if (exportedVariable) {13347 memberVariables[name] = exportedVariable;13348 }13349 }13350 }13351 return (this.memberVariables = memberVariables);13352 }13353 hasEffectsOnInteractionAtPath(path, interaction, context) {13354 const { type } = interaction;13355 if (path.length === 0) {13356 // This can only be a call anyway13357 return true;13358 }13359 if (path.length === 1 && type !== INTERACTION_CALLED) {13360 return type === INTERACTION_ASSIGNED;13361 }13362 const key = path[0];13363 if (typeof key !== 'string') {13364 return true;13365 }13366 const memberVariable = this.getMemberVariables()[key];13367 return (!memberVariable ||13368 memberVariable.hasEffectsOnInteractionAtPath(path.slice(1), interaction, context));13369 }13370 include() {13371 super.include();13372 this.context.includeAllExports();13373 }13374 prepare(accessedGlobalsByScope) {13375 if (this.mergedNamespaces.length > 0) {13376 this.module.scope.addAccessedGlobals([MERGE_NAMESPACES_VARIABLE], accessedGlobalsByScope);13377 }13378 }13379 renderBlock(options) {13380 const { exportNamesByVariable, format, freeze, indent: t, symbols, snippets: { _, cnst, getObject, getPropertyAccess, n, s } } = options;13381 const memberVariables = this.getMemberVariables();13382 const members = Object.entries(memberVariables)13383 .filter(([_, variable]) => variable.included)13384 .map(([name, variable]) => {13385 if (this.referencedEarly || variable.isReassigned || variable === this) {13386 return [13387 null,13388 `get ${stringifyObjectKeyIfNeeded(name)}${_}()${_}{${_}return ${variable.getName(getPropertyAccess)}${s}${_}}`13389 ];13390 }13391 return [name, variable.getName(getPropertyAccess)];13392 });13393 members.unshift([null, `__proto__:${_}null`]);13394 let output = getObject(members, { lineBreakIndent: { base: '', t } });13395 if (this.mergedNamespaces.length > 0) {13396 const assignmentArguments = this.mergedNamespaces.map(variable => variable.getName(getPropertyAccess));13397 output = `/*#__PURE__*/${MERGE_NAMESPACES_VARIABLE}(${output},${_}[${assignmentArguments.join(`,${_}`)}])`;13398 }13399 else {13400 // The helper to merge namespaces will also take care of freezing and toStringTag13401 if (symbols) {13402 output = `/*#__PURE__*/Object.defineProperty(${output},${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)})`;13403 }13404 if (freeze) {13405 output = `/*#__PURE__*/Object.freeze(${output})`;13406 }13407 }13408 const name = this.getName(getPropertyAccess);13409 output = `${cnst} ${name}${_}=${_}${output};`;13410 if (format === 'system' && exportNamesByVariable.has(this)) {13411 output += `${n}${getSystemExportStatement([this], options)};`;13412 }13413 return output;13414 }13415 renderFirst() {13416 return this.referencedEarly;13417 }13418 setMergedNamespaces(mergedNamespaces) {13419 this.mergedNamespaces = mergedNamespaces;13420 const moduleExecIndex = this.context.getModuleExecIndex();13421 for (const identifier of this.references) {13422 const { context } = identifier.scope;13423 if (context.getModuleExecIndex() <= moduleExecIndex) {13424 this.referencedEarly = true;13425 break;13426 }13427 }13428 }13429 }13430 NamespaceVariable.prototype.isNamespace = true;13431 13432 class SyntheticNamedExportVariable extends Variable {13433 constructor(context, name, syntheticNamespace) {13434 super(name);13435 this.baseVariable = null;13436 this.context = context;13437 this.module = context.module;13438 this.syntheticNamespace = syntheticNamespace;13439 }13440 getBaseVariable() {13441 if (this.baseVariable)13442 return this.baseVariable;13443 let baseVariable = this.syntheticNamespace;13444 while (baseVariable instanceof ExportDefaultVariable ||13445 baseVariable instanceof SyntheticNamedExportVariable) {13446 if (baseVariable instanceof ExportDefaultVariable) {13447 const original = baseVariable.getOriginalVariable();13448 if (original === baseVariable)13449 break;13450 baseVariable = original;13451 }13452 if (baseVariable instanceof SyntheticNamedExportVariable) {13453 baseVariable = baseVariable.syntheticNamespace;13454 }13455 }13456 return (this.baseVariable = baseVariable);13457 }13458 getBaseVariableName() {13459 return this.syntheticNamespace.getBaseVariableName();13460 }13461 getName(getPropertyAccess) {13462 return `${this.syntheticNamespace.getName(getPropertyAccess)}${getPropertyAccess(this.name)}`;13463 }13464 include() {13465 super.include();13466 this.context.includeVariableInModule(this.syntheticNamespace);13467 }13468 setRenderNames(baseName, name) {13469 super.setRenderNames(baseName, name);13470 15124 } 13471 15125 } … … 13743 15397 } 13744 15398 13745 function markModuleAndImpureDependenciesAsExecuted(baseModule) {13746 baseModule.isExecuted = true;13747 const modules = [baseModule];13748 const visitedModules = new Set();13749 for (const module of modules) {13750 for (const dependency of [...module.dependencies, ...module.implicitlyLoadedBefore]) {13751 if (!(dependency instanceof ExternalModule) &&13752 !dependency.isExecuted &&13753 (dependency.info.moduleSideEffects || module.implicitlyLoadedBefore.has(dependency)) &&13754 !visitedModules.has(dependency.id)) {13755 dependency.isExecuted = true;13756 visitedModules.add(dependency.id);13757 modules.push(dependency);13758 }13759 }13760 }13761 }13762 13763 15399 const MISSING_EXPORT_SHIM_DESCRIPTION = { 13764 15400 identifier: null, … … 13822 15458 this.dynamicImports = []; 13823 15459 this.execIndex = Infinity; 15460 this.hasTreeShakingPassStarted = false; 13824 15461 this.implicitlyLoadedAfter = new Set(); 13825 15462 this.implicitlyLoadedBefore = new Set(); … … 13898 15535 id, 13899 15536 get implicitlyLoadedAfterOneOf() { 13900 // eslint-disable-next-line unicorn/prefer-spread13901 15537 return Array.from(implicitlyLoadedAfter, getId).sort(); 13902 15538 }, 13903 15539 get implicitlyLoadedBefore() { 13904 // eslint-disable-next-line unicorn/prefer-spread13905 15540 return Array.from(implicitlyLoadedBefore, getId).sort(); 13906 15541 }, 13907 15542 get importedIdResolutions() { 13908 // eslint-disable-next-line unicorn/prefer-spread13909 15543 return Array.from(sourcesWithAttributes.keys(), source => module.resolvedIds[source]).filter(Boolean); 13910 15544 }, … … 13912 15546 // We cannot use this.dependencies because this is needed before 13913 15547 // dependencies are populated 13914 // eslint-disable-next-line unicorn/prefer-spread13915 15548 return Array.from(sourcesWithAttributes.keys(), source => module.resolvedIds[source]?.id).filter(Boolean); 13916 15549 }, … … 13955 15588 } 13956 15589 error(properties, pos) { 13957 pos !== undefined && this.addLocationToLogProps(properties, pos); 15590 if (pos !== undefined) { 15591 this.addLocationToLogProps(properties, pos); 15592 } 13958 15593 return error(properties); 13959 15594 } … … 14308 15943 addImport: this.addImport.bind(this), 14309 15944 addImportMeta: this.addImportMeta.bind(this), 15945 addImportSource: this.addImportSource.bind(this), 14310 15946 code, // Only needed for debugging 14311 15947 deoptimizationTracker: this.graph.deoptimizationTracker, … … 14313 15949 fileName, // Needed for warnings 14314 15950 getExports: this.getExports.bind(this), 15951 getImportedJsxFactoryVariable: this.getImportedJsxFactoryVariable.bind(this), 14315 15952 getModuleExecIndex: () => this.execIndex, 14316 15953 getModuleName: this.basename.bind(this), … … 14342 15979 // Measuring asynchronous code does not provide reasonable results 14343 15980 timeEnd('generate ast', 3); 14344 const astBuffer = await parseAsync(code, false );15981 const astBuffer = await parseAsync(code, false, this.options.jsx !== false); 14345 15982 timeStart('generate ast', 3); 14346 15983 this.ast = convertProgram(astBuffer, programParent, this.scope); … … 14377 16014 code: this.info.code, 14378 16015 customTransformCache: this.customTransformCache, 14379 // eslint-disable-next-line unicorn/prefer-spread14380 16016 dependencies: Array.from(this.dependencies, getId), 14381 16017 id: this.id, … … 14534 16170 start: specifier.start 14535 16171 }); 16172 } 16173 } 16174 addImportSource(importSource) { 16175 if (importSource && !this.sourcesWithAttributes.has(importSource)) { 16176 this.sourcesWithAttributes.set(importSource, EMPTY_OBJECT); 14536 16177 } 14537 16178 } … … 14599 16240 } 14600 16241 } 16242 getImportedJsxFactoryVariable(baseName, nodeStart, importSource) { 16243 const { id } = this.resolvedIds[importSource]; 16244 const module = this.graph.modulesById.get(id); 16245 const [variable] = module.getVariableForExportName(baseName); 16246 if (!variable) { 16247 return this.error(logMissingJsxExport(baseName, id, this.id), nodeStart); 16248 } 16249 return variable; 16250 } 14601 16251 getVariableFromNamespaceReexports(name, importerForSideEffects, searchedNamesAndModules) { 14602 16252 let foundSyntheticDeclaration = null; … … 14719 16369 tryParse() { 14720 16370 try { 14721 return parseAst(this.info.code );16371 return parseAst(this.info.code, { jsx: this.options.jsx !== false }); 14722 16372 } 14723 16373 catch (error_) { … … 14744 16394 } 14745 16395 const copyNameToModulesMap = (searchedNamesAndModules) => searchedNamesAndModules && 14746 // eslint-disable-next-line unicorn/prefer-spread14747 16396 new Map(Array.from(searchedNamesAndModules, ([name, modules]) => [name, new Set(modules)])); 14748 14749 function removeJsExtension(name) {14750 return name.endsWith('.js') ? name.slice(0, -3) : name;14751 }14752 14753 function getCompleteAmdId(options, chunkId) {14754 if (options.autoId) {14755 return `${options.basePath ? options.basePath + '/' : ''}${removeJsExtension(chunkId)}`;14756 }14757 return options.id ?? '';14758 }14759 14760 function getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, mechanism = 'return ') {14761 const { _, getDirectReturnFunction, getFunctionIntro, getPropertyAccess, n, s } = snippets;14762 if (!namedExportsMode) {14763 return `${n}${n}${mechanism}${getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess)};`;14764 }14765 let exportBlock = '';14766 if (namedExportsMode) {14767 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) {14768 if (!reexports) {14769 continue;14770 }14771 for (const specifier of reexports) {14772 if (specifier.reexported !== '*') {14773 const importName = getReexportedImportName(name, specifier.imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess);14774 if (exportBlock)14775 exportBlock += n;14776 if (specifier.imported !== '*' && specifier.needsLiveBinding) {14777 const [left, right] = getDirectReturnFunction([], {14778 functionReturn: true,14779 lineBreakIndent: null,14780 name: null14781 });14782 exportBlock +=14783 `Object.defineProperty(exports,${_}${JSON.stringify(specifier.reexported)},${_}{${n}` +14784 `${t}enumerable:${_}true,${n}` +14785 `${t}get:${_}${left}${importName}${right}${n}});`;14786 }14787 else if (specifier.reexported === '__proto__') {14788 exportBlock +=14789 `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` +14790 `${t}enumerable:${_}true,${n}` +14791 `${t}value:${_}${importName}${n}});`;14792 }14793 else {14794 exportBlock += `exports${getPropertyAccess(specifier.reexported)}${_}=${_}${importName};`;14795 }14796 }14797 }14798 }14799 }14800 for (const { exported, local } of exports) {14801 const lhs = `exports${getPropertyAccess(exported)}`;14802 const rhs = local;14803 if (lhs !== rhs) {14804 if (exportBlock)14805 exportBlock += n;14806 exportBlock +=14807 exported === '__proto__'14808 ? `Object.defineProperty(exports,${_}"__proto__",${_}{${n}` +14809 `${t}enumerable:${_}true,${n}` +14810 `${t}value:${_}${rhs}${n}});`14811 : `${lhs}${_}=${_}${rhs};`;14812 }14813 }14814 if (namedExportsMode) {14815 for (const { name, reexports } of dependencies) {14816 if (!reexports) {14817 continue;14818 }14819 for (const specifier of reexports) {14820 if (specifier.reexported === '*') {14821 if (exportBlock)14822 exportBlock += n;14823 if (!specifier.needsLiveBinding && reexportProtoFromExternal) {14824 const protoString = "'__proto__'";14825 exportBlock +=14826 `Object.prototype.hasOwnProperty.call(${name},${_}${protoString})${_}&&${n}` +14827 `${t}!Object.prototype.hasOwnProperty.call(exports,${_}${protoString})${_}&&${n}` +14828 `${t}Object.defineProperty(exports,${_}${protoString},${_}{${n}` +14829 `${t}${t}enumerable:${_}true,${n}` +14830 `${t}${t}value:${_}${name}[${protoString}]${n}` +14831 `${t}});${n}${n}`;14832 }14833 const copyPropertyIfNecessary = `{${n}${t}if${_}(k${_}!==${_}'default'${_}&&${_}!Object.prototype.hasOwnProperty.call(exports,${_}k))${_}${getDefineProperty(name, specifier.needsLiveBinding, t, snippets)}${s}${n}}`;14834 exportBlock += `Object.keys(${name}).forEach(${getFunctionIntro(['k'], {14835 isAsync: false,14836 name: null14837 })}${copyPropertyIfNecessary});`;14838 }14839 }14840 }14841 }14842 if (exportBlock) {14843 return `${n}${n}${exportBlock}`;14844 }14845 return '';14846 }14847 function getSingleDefaultExport(exports, dependencies, interop, externalLiveBindings, getPropertyAccess) {14848 if (exports.length > 0) {14849 return exports[0].local;14850 }14851 else {14852 for (const { defaultVariableName, importPath, isChunk, name, namedExportsMode: depNamedExportsMode, namespaceVariableName, reexports } of dependencies) {14853 if (reexports) {14854 return getReexportedImportName(name, reexports[0].imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, importPath, externalLiveBindings, getPropertyAccess);14855 }14856 }14857 }14858 }14859 function getReexportedImportName(moduleVariableName, imported, depNamedExportsMode, isChunk, defaultVariableName, namespaceVariableName, interop, moduleId, externalLiveBindings, getPropertyAccess) {14860 if (imported === 'default') {14861 if (!isChunk) {14862 const moduleInterop = interop(moduleId);14863 const variableName = defaultInteropHelpersByInteropType[moduleInterop]14864 ? defaultVariableName14865 : moduleVariableName;14866 return isDefaultAProperty(moduleInterop, externalLiveBindings)14867 ? `${variableName}${getPropertyAccess('default')}`14868 : variableName;14869 }14870 return depNamedExportsMode14871 ? `${moduleVariableName}${getPropertyAccess('default')}`14872 : moduleVariableName;14873 }14874 if (imported === '*') {14875 return (isChunk ? !depNamedExportsMode : namespaceInteropHelpersByInteropType[interop(moduleId)])14876 ? namespaceVariableName14877 : moduleVariableName;14878 }14879 return `${moduleVariableName}${getPropertyAccess(imported)}`;14880 }14881 function getEsModuleValue(getObject) {14882 return getObject([['value', 'true']], {14883 lineBreakIndent: null14884 });14885 }14886 function getNamespaceMarkers(hasNamedExports, addEsModule, addNamespaceToStringTag, { _, getObject }) {14887 if (hasNamedExports) {14888 if (addEsModule) {14889 if (addNamespaceToStringTag) {14890 return `Object.defineProperties(exports,${_}${getObject([14891 ['__esModule', getEsModuleValue(getObject)],14892 [null, `[Symbol.toStringTag]:${_}${getToStringTagValue(getObject)}`]14893 ], {14894 lineBreakIndent: null14895 })});`;14896 }14897 return `Object.defineProperty(exports,${_}'__esModule',${_}${getEsModuleValue(getObject)});`;14898 }14899 if (addNamespaceToStringTag) {14900 return `Object.defineProperty(exports,${_}Symbol.toStringTag,${_}${getToStringTagValue(getObject)});`;14901 }14902 }14903 return '';14904 }14905 const getDefineProperty = (name, needsLiveBinding, t, { _, getDirectReturnFunction, n }) => {14906 if (needsLiveBinding) {14907 const [left, right] = getDirectReturnFunction([], {14908 functionReturn: true,14909 lineBreakIndent: null,14910 name: null14911 });14912 return (`Object.defineProperty(exports,${_}k,${_}{${n}` +14913 `${t}${t}enumerable:${_}true,${n}` +14914 `${t}${t}get:${_}${left}${name}[k]${right}${n}${t}})`);14915 }14916 return `exports[k]${_}=${_}${name}[k]`;14917 };14918 14919 function getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, indent, snippets) {14920 const { _, cnst, n } = snippets;14921 const neededInteropHelpers = new Set();14922 const interopStatements = [];14923 const addInteropStatement = (helperVariableName, helper, dependencyVariableName) => {14924 neededInteropHelpers.add(helper);14925 interopStatements.push(`${cnst} ${helperVariableName}${_}=${_}/*#__PURE__*/${helper}(${dependencyVariableName});`);14926 };14927 for (const { defaultVariableName, imports, importPath, isChunk, name, namedExportsMode, namespaceVariableName, reexports } of dependencies) {14928 if (isChunk) {14929 for (const { imported, reexported } of [14930 ...(imports || []),14931 ...(reexports || [])14932 ]) {14933 if (imported === '*' && reexported !== '*') {14934 if (!namedExportsMode) {14935 addInteropStatement(namespaceVariableName, INTEROP_NAMESPACE_DEFAULT_ONLY_VARIABLE, name);14936 }14937 break;14938 }14939 }14940 }14941 else {14942 const moduleInterop = interop(importPath);14943 let hasDefault = false;14944 let hasNamespace = false;14945 for (const { imported, reexported } of [14946 ...(imports || []),14947 ...(reexports || [])14948 ]) {14949 let helper;14950 let variableName;14951 if (imported === 'default') {14952 if (!hasDefault) {14953 hasDefault = true;14954 if (defaultVariableName !== namespaceVariableName) {14955 variableName = defaultVariableName;14956 helper = defaultInteropHelpersByInteropType[moduleInterop];14957 }14958 }14959 }14960 else if (imported === '*' && reexported !== '*' && !hasNamespace) {14961 hasNamespace = true;14962 helper = namespaceInteropHelpersByInteropType[moduleInterop];14963 variableName = namespaceVariableName;14964 }14965 if (helper) {14966 addInteropStatement(variableName, helper, name);14967 }14968 }14969 }14970 }14971 return `${getHelpersBlock(neededInteropHelpers, accessedGlobals, indent, snippets, externalLiveBindings, freeze, symbols)}${interopStatements.length > 0 ? `${interopStatements.join(n)}${n}${n}` : ''}`;14972 }14973 14974 function addJsExtension(name) {14975 return name.endsWith('.js') ? name : name + '.js';14976 }14977 14978 // AMD resolution will only respect the AMD baseUrl if the .js extension is omitted.14979 // The assumption is that this makes sense for all relative ids:14980 // https://requirejs.org/docs/api.html#jsfiles14981 function updateExtensionForRelativeAmdId(id, forceJsExtensionForImports) {14982 if (id[0] !== '.') {14983 return id;14984 }14985 return forceJsExtensionForImports ? addJsExtension(id) : removeJsExtension(id);14986 }14987 14988 const builtinModules = [14989 "assert",14990 "assert/strict",14991 "async_hooks",14992 "buffer",14993 "child_process",14994 "cluster",14995 "console",14996 "constants",14997 "crypto",14998 "dgram",14999 "diagnostics_channel",15000 "dns",15001 "dns/promises",15002 "domain",15003 "events",15004 "fs",15005 "fs/promises",15006 "http",15007 "http2",15008 "https",15009 "inspector",15010 "inspector/promises",15011 "module",15012 "net",15013 "os",15014 "path",15015 "path/posix",15016 "path/win32",15017 "perf_hooks",15018 "process",15019 "punycode",15020 "querystring",15021 "readline",15022 "readline/promises",15023 "repl",15024 "stream",15025 "stream/consumers",15026 "stream/promises",15027 "stream/web",15028 "string_decoder",15029 "timers",15030 "timers/promises",15031 "tls",15032 "trace_events",15033 "tty",15034 "url",15035 "util",15036 "util/types",15037 "v8",15038 "vm",15039 "wasi",15040 "worker_threads",15041 "zlib"15042 ];15043 15044 const nodeBuiltins = new Set(builtinModules);15045 function warnOnBuiltins(log, dependencies) {15046 const externalBuiltins = dependencies15047 .map(({ importPath }) => importPath)15048 .filter(importPath => nodeBuiltins.has(importPath) || importPath.startsWith('node:'));15049 if (externalBuiltins.length === 0)15050 return;15051 log(LOGLEVEL_WARN, logMissingNodeBuiltins(externalBuiltins));15052 }15053 15054 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 }) {15055 warnOnBuiltins(log, dependencies);15056 const deps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`);15057 const parameters = dependencies.map(m => m.name);15058 const { n, getNonArrowFunctionIntro, _ } = snippets;15059 if (namedExportsMode && hasExports) {15060 parameters.unshift(`exports`);15061 deps.unshift(`'exports'`);15062 }15063 if (accessedGlobals.has('require')) {15064 parameters.unshift('require');15065 deps.unshift(`'require'`);15066 }15067 if (accessedGlobals.has('module')) {15068 parameters.unshift('module');15069 deps.unshift(`'module'`);15070 }15071 const completeAmdId = getCompleteAmdId(amd, id);15072 const defineParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) +15073 (deps.length > 0 ? `[${deps.join(`,${_}`)}],${_}` : ``);15074 const useStrict = strict ? `${_}'use strict';` : '';15075 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`);15076 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);15077 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets);15078 if (namespaceMarkers) {15079 namespaceMarkers = n + n + namespaceMarkers;15080 }15081 magicString15082 .append(`${exportBlock}${namespaceMarkers}${outro}`)15083 .indent(t)15084 // factory function should be wrapped by parentheses to avoid lazy parsing,15085 // cf. https://v8.dev/blog/preparser#pife15086 .prepend(`${amd.define}(${defineParameters}(${getNonArrowFunctionIntro(parameters, {15087 isAsync: false,15088 name: null15089 })}{${useStrict}${n}${n}`)15090 .append(`${n}${n}}));`);15091 }15092 15093 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 }) {15094 const { _, n } = snippets;15095 const useStrict = strict ? `'use strict';${n}${n}` : '';15096 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, isEntryFacade && (esModule === true || (esModule === 'if-default-prop' && hasDefaultExport)), isModuleFacade && symbols, snippets);15097 if (namespaceMarkers) {15098 namespaceMarkers += n + n;15099 }15100 const importBlock = getImportBlock$1(dependencies, snippets, compact);15101 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets);15102 magicString.prepend(`${useStrict}${intro}${namespaceMarkers}${importBlock}${interopBlock}`);15103 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal, `module.exports${_}=${_}`);15104 magicString.append(`${exportBlock}${outro}`);15105 }15106 function getImportBlock$1(dependencies, { _, cnst, n }, compact) {15107 let importBlock = '';15108 let definingVariable = false;15109 for (const { importPath, name, reexports, imports } of dependencies) {15110 if (!reexports && !imports) {15111 if (importBlock) {15112 importBlock += compact && !definingVariable ? ',' : `;${n}`;15113 }15114 definingVariable = false;15115 importBlock += `require('${importPath}')`;15116 }15117 else {15118 importBlock += compact && definingVariable ? ',' : `${importBlock ? `;${n}` : ''}${cnst} `;15119 definingVariable = true;15120 importBlock += `${name}${_}=${_}require('${importPath}')`;15121 }15122 }15123 if (importBlock) {15124 return `${importBlock};${n}${n}`;15125 }15126 return '';15127 }15128 15129 function es(magicString, { accessedGlobals, indent: t, intro, outro, dependencies, exports, snippets }, { externalLiveBindings, freeze, generatedCode: { symbols }, importAttributesKey }) {15130 const { n } = snippets;15131 const importBlock = getImportBlock(dependencies, importAttributesKey, snippets);15132 if (importBlock.length > 0)15133 intro += importBlock.join(n) + n + n;15134 intro += getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols);15135 if (intro)15136 magicString.prepend(intro);15137 const exportBlock = getExportBlock(exports, snippets);15138 if (exportBlock.length > 0)15139 magicString.append(n + n + exportBlock.join(n).trim());15140 if (outro)15141 magicString.append(outro);15142 magicString.trim();15143 }15144 function getImportBlock(dependencies, importAttributesKey, { _ }) {15145 const importBlock = [];15146 for (const { importPath, reexports, imports, name, attributes } of dependencies) {15147 const assertion = attributes ? `${_}${importAttributesKey}${_}${attributes}` : '';15148 const pathWithAssertion = `'${importPath}'${assertion};`;15149 if (!reexports && !imports) {15150 importBlock.push(`import${_}${pathWithAssertion}`);15151 continue;15152 }15153 if (imports) {15154 let defaultImport = null;15155 let starImport = null;15156 const importedNames = [];15157 for (const specifier of imports) {15158 if (specifier.imported === 'default') {15159 defaultImport = specifier;15160 }15161 else if (specifier.imported === '*') {15162 starImport = specifier;15163 }15164 else {15165 importedNames.push(specifier);15166 }15167 }15168 if (starImport) {15169 importBlock.push(`import${_}*${_}as ${starImport.local} from${_}${pathWithAssertion}`);15170 }15171 if (defaultImport && importedNames.length === 0) {15172 importBlock.push(`import ${defaultImport.local} from${_}${pathWithAssertion}`);15173 }15174 else if (importedNames.length > 0) {15175 importBlock.push(`import ${defaultImport ? `${defaultImport.local},${_}` : ''}{${_}${importedNames15176 .map(specifier => specifier.imported === specifier.local15177 ? specifier.imported15178 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${specifier.local}`)15179 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`);15180 }15181 }15182 if (reexports) {15183 let starExport = null;15184 const namespaceReexports = [];15185 const namedReexports = [];15186 for (const specifier of reexports) {15187 if (specifier.reexported === '*') {15188 starExport = specifier;15189 }15190 else if (specifier.imported === '*') {15191 namespaceReexports.push(specifier);15192 }15193 else {15194 namedReexports.push(specifier);15195 }15196 }15197 if (starExport) {15198 importBlock.push(`export${_}*${_}from${_}${pathWithAssertion}`);15199 }15200 if (namespaceReexports.length > 0) {15201 if (!imports ||15202 !imports.some(specifier => specifier.imported === '*' && specifier.local === name)) {15203 importBlock.push(`import${_}*${_}as ${name} from${_}${pathWithAssertion}`);15204 }15205 for (const specifier of namespaceReexports) {15206 importBlock.push(`export${_}{${_}${name === specifier.reexported15207 ? name15208 : `${name} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`} };`);15209 }15210 }15211 if (namedReexports.length > 0) {15212 importBlock.push(`export${_}{${_}${namedReexports15213 .map(specifier => specifier.imported === specifier.reexported15214 ? stringifyIdentifierIfNeeded(specifier.imported)15215 : `${stringifyIdentifierIfNeeded(specifier.imported)} as ${stringifyIdentifierIfNeeded(specifier.reexported)}`)15216 .join(`,${_}`)}${_}}${_}from${_}${pathWithAssertion}`);15217 }15218 }15219 }15220 return importBlock;15221 }15222 function getExportBlock(exports, { _, cnst }) {15223 const exportBlock = [];15224 const exportDeclaration = [];15225 for (const specifier of exports) {15226 if (specifier.expression) {15227 exportBlock.push(`${cnst} ${specifier.local}${_}=${_}${specifier.expression};`);15228 }15229 exportDeclaration.push(specifier.exported === specifier.local15230 ? specifier.local15231 : `${specifier.local} as ${stringifyIdentifierIfNeeded(specifier.exported)}`);15232 }15233 if (exportDeclaration.length > 0) {15234 exportBlock.push(`export${_}{${_}${exportDeclaration.join(`,${_}`)}${_}};`);15235 }15236 return exportBlock;15237 }15238 15239 const keypath = (keypath, getPropertyAccess) => keypath.split('.').map(getPropertyAccess).join('');15240 15241 function setupNamespace(name, root, globals, { _, getPropertyAccess, s }, compact) {15242 const parts = name.split('.');15243 parts[0] = (typeof globals === 'function' ? globals(parts[0]) : globals[parts[0]]) || parts[0];15244 parts.pop();15245 let propertyPath = root;15246 return (parts15247 .map(part => {15248 propertyPath += getPropertyAccess(part);15249 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}${s}`;15250 })15251 .join(compact ? ',' : '\n') + (compact && parts.length > 0 ? ';' : '\n'));15252 }15253 function assignToDeepVariable(deepName, root, globals, assignment, { _, getPropertyAccess }) {15254 const parts = deepName.split('.');15255 parts[0] = (typeof globals === 'function' ? globals(parts[0]) : globals[parts[0]]) || parts[0];15256 const last = parts.pop();15257 let propertyPath = root;15258 let deepAssignment = [15259 ...parts.map(part => {15260 propertyPath += getPropertyAccess(part);15261 return `${propertyPath}${_}=${_}${propertyPath}${_}||${_}{}`;15262 }),15263 `${propertyPath}${getPropertyAccess(last)}`15264 ].join(`,${_}`) + `${_}=${_}${assignment}`;15265 if (parts.length > 0) {15266 deepAssignment = `(${deepAssignment})`;15267 }15268 return deepAssignment;15269 }15270 15271 function trimEmptyImports(dependencies) {15272 let index = dependencies.length;15273 while (index--) {15274 const { imports, reexports } = dependencies[index];15275 if (imports || reexports) {15276 return dependencies.slice(0, index + 1);15277 }15278 }15279 return [];15280 }15281 15282 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 }) {15283 const { _, getNonArrowFunctionIntro, getPropertyAccess, n } = snippets;15284 const isNamespaced = name && name.includes('.');15285 const useVariableAssignment = !extend && !isNamespaced;15286 if (name && useVariableAssignment && !isLegal(name)) {15287 return error(logIllegalIdentifierAsName(name));15288 }15289 warnOnBuiltins(log, dependencies);15290 const external = trimEmptyImports(dependencies);15291 const deps = external.map(dep => dep.globalName || 'null');15292 const parameters = external.map(m => m.name);15293 if (hasExports && !name) {15294 log(LOGLEVEL_WARN, logMissingNameOptionForIifeExport());15295 }15296 if (namedExportsMode && hasExports) {15297 if (extend) {15298 deps.unshift(`this${keypath(name, getPropertyAccess)}${_}=${_}this${keypath(name, getPropertyAccess)}${_}||${_}{}`);15299 parameters.unshift('exports');15300 }15301 else {15302 deps.unshift('{}');15303 parameters.unshift('exports');15304 }15305 }15306 const useStrict = strict ? `${t}'use strict';${n}` : '';15307 const interopBlock = getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets);15308 magicString.prepend(`${intro}${interopBlock}`);15309 let wrapperIntro = `(${getNonArrowFunctionIntro(parameters, {15310 isAsync: false,15311 name: null15312 })}{${n}${useStrict}${n}`;15313 if (hasExports) {15314 if (name && !(extend && namedExportsMode)) {15315 wrapperIntro =15316 (useVariableAssignment ? `var ${name}` : `this${keypath(name, getPropertyAccess)}`) +15317 `${_}=${_}${wrapperIntro}`;15318 }15319 if (isNamespaced) {15320 wrapperIntro = setupNamespace(name, 'this', globals, snippets, compact) + wrapperIntro;15321 }15322 }15323 let wrapperOutro = `${n}${n}})(${deps.join(`,${_}`)});`;15324 if (hasExports && !extend && namedExportsMode) {15325 wrapperOutro = `${n}${n}${t}return exports;${wrapperOutro}`;15326 }15327 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);15328 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets);15329 if (namespaceMarkers) {15330 namespaceMarkers = n + n + namespaceMarkers;15331 }15332 magicString15333 .append(`${exportBlock}${namespaceMarkers}${outro}`)15334 .indent(t)15335 .prepend(wrapperIntro)15336 .append(wrapperOutro);15337 }15338 15339 function system(magicString, { accessedGlobals, dependencies, exports, hasExports, indent: t, intro, snippets, outro, usesTopLevelAwait }, { externalLiveBindings, freeze, name, generatedCode: { symbols }, strict, systemNullSetters }) {15340 const { _, getFunctionIntro, getNonArrowFunctionIntro, n, s } = snippets;15341 const { importBindings, setters, starExcludes } = analyzeDependencies(dependencies, exports, t, snippets);15342 const registeredName = name ? `'${name}',${_}` : '';15343 const wrapperParameters = accessedGlobals.has('module')15344 ? ['exports', 'module']15345 : hasExports15346 ? ['exports']15347 : [];15348 // factory function should be wrapped by parentheses to avoid lazy parsing,15349 // cf. https://v8.dev/blog/preparser#pife15350 let wrapperStart = `System.register(${registeredName}[` +15351 dependencies.map(({ importPath }) => `'${importPath}'`).join(`,${_}`) +15352 `],${_}(${getNonArrowFunctionIntro(wrapperParameters, {15353 isAsync: false,15354 name: null15355 })}{${n}${t}${strict ? "'use strict';" : ''}` +15356 getStarExcludesBlock(starExcludes, t, snippets) +15357 getImportBindingsBlock(importBindings, t, snippets) +15358 `${n}${t}return${_}{${setters.length > 015359 ? `${n}${t}${t}setters:${_}[${setters15360 .map(setter => setter15361 ? `${getFunctionIntro(['module'], {15362 isAsync: false,15363 name: null15364 })}{${n}${t}${t}${t}${setter}${n}${t}${t}}`15365 : systemNullSetters15366 ? `null`15367 : `${getFunctionIntro([], { isAsync: false, name: null })}{}`)15368 .join(`,${_}`)}],`15369 : ''}${n}`;15370 wrapperStart += `${t}${t}execute:${_}(${getNonArrowFunctionIntro([], {15371 isAsync: usesTopLevelAwait,15372 name: null15373 })}{${n}${n}`;15374 const wrapperEnd = `${t}${t}})${n}${t}}${s}${n}}));`;15375 magicString15376 .prepend(intro +15377 getHelpersBlock(null, accessedGlobals, t, snippets, externalLiveBindings, freeze, symbols) +15378 getHoistedExportsBlock(exports, t, snippets))15379 .append(`${outro}${n}${n}` +15380 getSyntheticExportsBlock(exports, t, snippets) +15381 getMissingExportsBlock(exports, t, snippets))15382 .indent(`${t}${t}${t}`)15383 .append(wrapperEnd)15384 .prepend(wrapperStart);15385 }15386 function analyzeDependencies(dependencies, exports, t, { _, cnst, getObject, getPropertyAccess, n }) {15387 const importBindings = [];15388 const setters = [];15389 let starExcludes = null;15390 for (const { imports, reexports } of dependencies) {15391 const setter = [];15392 if (imports) {15393 for (const specifier of imports) {15394 importBindings.push(specifier.local);15395 if (specifier.imported === '*') {15396 setter.push(`${specifier.local}${_}=${_}module;`);15397 }15398 else {15399 setter.push(`${specifier.local}${_}=${_}module${getPropertyAccess(specifier.imported)};`);15400 }15401 }15402 }15403 if (reexports) {15404 const reexportedNames = [];15405 let hasStarReexport = false;15406 for (const { imported, reexported } of reexports) {15407 if (reexported === '*') {15408 hasStarReexport = true;15409 }15410 else {15411 reexportedNames.push([15412 reexported,15413 imported === '*' ? 'module' : `module${getPropertyAccess(imported)}`15414 ]);15415 }15416 }15417 if (reexportedNames.length > 1 || hasStarReexport) {15418 if (hasStarReexport) {15419 if (!starExcludes) {15420 starExcludes = getStarExcludes({ dependencies, exports });15421 }15422 reexportedNames.unshift([null, `__proto__:${_}null`]);15423 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null });15424 setter.push(`${cnst} setter${_}=${_}${exportMapping};`, `for${_}(${cnst} name in module)${_}{`, `${t}if${_}(!_starExcludes[name])${_}setter[name]${_}=${_}module[name];`, '}', 'exports(setter);');15425 }15426 else {15427 const exportMapping = getObject(reexportedNames, { lineBreakIndent: null });15428 setter.push(`exports(${exportMapping});`);15429 }15430 }15431 else {15432 const [key, value] = reexportedNames[0];15433 setter.push(`exports(${JSON.stringify(key)},${_}${value});`);15434 }15435 }15436 setters.push(setter.join(`${n}${t}${t}${t}`));15437 }15438 return { importBindings, setters, starExcludes };15439 }15440 const getStarExcludes = ({ dependencies, exports }) => {15441 const starExcludes = new Set(exports.map(expt => expt.exported));15442 starExcludes.add('default');15443 for (const { reexports } of dependencies) {15444 if (reexports) {15445 for (const reexport of reexports) {15446 if (reexport.reexported !== '*')15447 starExcludes.add(reexport.reexported);15448 }15449 }15450 }15451 return starExcludes;15452 };15453 const getStarExcludesBlock = (starExcludes, t, { _, cnst, getObject, n }) => {15454 if (starExcludes) {15455 const fields = [...starExcludes].map(property => [15456 property,15457 '1'15458 ]);15459 fields.unshift([null, `__proto__:${_}null`]);15460 return `${n}${t}${cnst} _starExcludes${_}=${_}${getObject(fields, {15461 lineBreakIndent: { base: t, t }15462 })};`;15463 }15464 return '';15465 };15466 const getImportBindingsBlock = (importBindings, t, { _, n }) => (importBindings.length > 0 ? `${n}${t}var ${importBindings.join(`,${_}`)};` : '');15467 const getHoistedExportsBlock = (exports, t, snippets) => getExportsBlock(exports.filter(expt => expt.hoisted).map(expt => ({ name: expt.exported, value: expt.local })), t, snippets);15468 function getExportsBlock(exports, t, { _, n }) {15469 if (exports.length === 0) {15470 return '';15471 }15472 if (exports.length === 1) {15473 return `exports(${JSON.stringify(exports[0].name)},${_}${exports[0].value});${n}${n}`;15474 }15475 return (`exports({${n}` +15476 exports15477 .map(({ name, value }) => `${t}${stringifyObjectKeyIfNeeded(name)}:${_}${value}`)15478 .join(`,${n}`) +15479 `${n}});${n}${n}`);15480 }15481 const getSyntheticExportsBlock = (exports, t, snippets) => getExportsBlock(exports15482 .filter(expt => expt.expression)15483 .map(expt => ({ name: expt.exported, value: expt.local })), t, snippets);15484 const getMissingExportsBlock = (exports, t, snippets) => getExportsBlock(exports15485 .filter(expt => expt.local === MISSING_EXPORT_SHIM_VARIABLE)15486 .map(expt => ({ name: expt.exported, value: MISSING_EXPORT_SHIM_VARIABLE })), t, snippets);15487 15488 function globalProperty(name, globalVariable, getPropertyAccess) {15489 if (!name)15490 return 'null';15491 return `${globalVariable}${keypath(name, getPropertyAccess)}`;15492 }15493 function safeAccess(name, globalVariable, { _, getPropertyAccess }) {15494 let propertyPath = globalVariable;15495 return name15496 .split('.')15497 .map(part => (propertyPath += getPropertyAccess(part)))15498 .join(`${_}&&${_}`);15499 }15500 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 }) {15501 const { _, cnst, getFunctionIntro, getNonArrowFunctionIntro, getPropertyAccess, n, s } = snippets;15502 const factoryVariable = compact ? 'f' : 'factory';15503 const globalVariable = compact ? 'g' : 'global';15504 if (hasExports && !name) {15505 return error(logMissingNameOptionForUmdExport());15506 }15507 warnOnBuiltins(log, dependencies);15508 const amdDeps = dependencies.map(m => `'${updateExtensionForRelativeAmdId(m.importPath, amd.forceJsExtensionForImports)}'`);15509 const cjsDeps = dependencies.map(m => `require('${m.importPath}')`);15510 const trimmedImports = trimEmptyImports(dependencies);15511 const globalDeps = trimmedImports.map(module => globalProperty(module.globalName, globalVariable, getPropertyAccess));15512 const factoryParameters = trimmedImports.map(m => m.name);15513 if (namedExportsMode && (hasExports || noConflict)) {15514 amdDeps.unshift(`'exports'`);15515 cjsDeps.unshift(`exports`);15516 globalDeps.unshift(assignToDeepVariable(name, globalVariable, globals, `${extend ? `${globalProperty(name, globalVariable, getPropertyAccess)}${_}||${_}` : ''}{}`, snippets));15517 factoryParameters.unshift('exports');15518 }15519 const completeAmdId = getCompleteAmdId(amd, id);15520 const amdParameters = (completeAmdId ? `'${completeAmdId}',${_}` : ``) +15521 (amdDeps.length > 0 ? `[${amdDeps.join(`,${_}`)}],${_}` : ``);15522 const define = amd.define;15523 const cjsExport = !namedExportsMode && hasExports ? `module.exports${_}=${_}` : ``;15524 const useStrict = strict ? `${_}'use strict';${n}` : ``;15525 let iifeExport;15526 if (noConflict) {15527 const noConflictExportsVariable = compact ? 'e' : 'exports';15528 let factory;15529 if (!namedExportsMode && hasExports) {15530 factory = `${cnst} ${noConflictExportsVariable}${_}=${_}${assignToDeepVariable(name, globalVariable, globals, `${factoryVariable}(${globalDeps.join(`,${_}`)})`, snippets)};`;15531 }15532 else {15533 const module = globalDeps.shift();15534 factory =15535 `${cnst} ${noConflictExportsVariable}${_}=${_}${module};${n}` +15536 `${t}${t}${factoryVariable}(${[noConflictExportsVariable, ...globalDeps].join(`,${_}`)});`;15537 }15538 iifeExport =15539 `(${getFunctionIntro([], { isAsync: false, name: null })}{${n}` +15540 `${t}${t}${cnst} current${_}=${_}${safeAccess(name, globalVariable, snippets)};${n}` +15541 `${t}${t}${factory}${n}` +15542 `${t}${t}${noConflictExportsVariable}.noConflict${_}=${_}${getFunctionIntro([], {15543 isAsync: false,15544 name: null15545 })}{${_}` +15546 `${globalProperty(name, globalVariable, getPropertyAccess)}${_}=${_}current;${_}return ${noConflictExportsVariable}${s}${_}};${n}` +15547 `${t}})()`;15548 }15549 else {15550 iifeExport = `${factoryVariable}(${globalDeps.join(`,${_}`)})`;15551 if (!namedExportsMode && hasExports) {15552 iifeExport = assignToDeepVariable(name, globalVariable, globals, iifeExport, snippets);15553 }15554 }15555 const iifeNeedsGlobal = hasExports || (noConflict && namedExportsMode) || globalDeps.length > 0;15556 const wrapperParameters = [factoryVariable];15557 if (iifeNeedsGlobal) {15558 wrapperParameters.unshift(globalVariable);15559 }15560 const globalArgument = iifeNeedsGlobal ? `this,${_}` : '';15561 const iifeStart = iifeNeedsGlobal15562 ? `(${globalVariable}${_}=${_}typeof globalThis${_}!==${_}'undefined'${_}?${_}globalThis${_}:${_}${globalVariable}${_}||${_}self,${_}`15563 : '';15564 const iifeEnd = iifeNeedsGlobal ? ')' : '';15565 const cjsIntro = iifeNeedsGlobal15566 ? `${t}typeof exports${_}===${_}'object'${_}&&${_}typeof module${_}!==${_}'undefined'${_}?` +15567 `${_}${cjsExport}${factoryVariable}(${cjsDeps.join(`,${_}`)})${_}:${n}`15568 : '';15569 const wrapperIntro = `(${getNonArrowFunctionIntro(wrapperParameters, { isAsync: false, name: null })}{${n}` +15570 cjsIntro +15571 `${t}typeof ${define}${_}===${_}'function'${_}&&${_}${define}.amd${_}?${_}${define}(${amdParameters}${factoryVariable})${_}:${n}` +15572 `${t}${iifeStart}${iifeExport}${iifeEnd};${n}` +15573 // factory function should be wrapped by parentheses to avoid lazy parsing,15574 // cf. https://v8.dev/blog/preparser#pife15575 `})(${globalArgument}(${getNonArrowFunctionIntro(factoryParameters, {15576 isAsync: false,15577 name: null15578 })}{${useStrict}${n}`;15579 const wrapperOutro = n + n + '}));';15580 magicString.prepend(`${intro}${getInteropBlock(dependencies, interop, externalLiveBindings, freeze, symbols, accessedGlobals, t, snippets)}`);15581 const exportBlock = getExportBlock$1(exports, dependencies, namedExportsMode, interop, snippets, t, externalLiveBindings, reexportProtoFromExternal);15582 let namespaceMarkers = getNamespaceMarkers(namedExportsMode && hasExports, esModule === true || (esModule === 'if-default-prop' && hasDefaultExport), symbols, snippets);15583 if (namespaceMarkers) {15584 namespaceMarkers = n + n + namespaceMarkers;15585 }15586 magicString15587 .append(`${exportBlock}${namespaceMarkers}${outro}`)15588 .trim()15589 .indent(t)15590 .append(wrapperOutro)15591 .prepend(wrapperIntro);15592 }15593 15594 const finalisers = { amd, cjs, es, iife, system, umd };15595 16397 15596 16398 const concatSeparator = (out, next) => (next ? `${out}\n${next}` : out); … … 15870 16672 const hashPlaceholderOverhead = hashPlaceholderLeft.length + hashPlaceholderRight.length; 15871 16673 // This is the size of a 128-bits xxhash with base64url encoding 15872 const MAX_HASH_SIZE = 2 2;16674 const MAX_HASH_SIZE = 21; 15873 16675 const DEFAULT_HASH_SIZE = 8; 15874 16676 const getHashPlaceholderGenerator = () => { … … 15931 16733 const bundleEntries = Object.values(outputBundle); 15932 16734 for (const asset of bundleEntries) { 15933 asset.type === 'asset' && asset.needsCodeReference && unreferencedAssets.add(asset.fileName); 16735 if (asset.type === 'asset' && asset.needsCodeReference) { 16736 unreferencedAssets.add(asset.fileName); 16737 } 15934 16738 } 15935 16739 for (const chunk of bundleEntries) { 15936 16740 if (chunk.type === 'chunk') { 15937 16741 for (const referencedFile of chunk.referencedFiles) { 15938 unreferencedAssets.has(referencedFile) && unreferencedAssets.delete(referencedFile); 16742 if (unreferencedAssets.has(referencedFile)) { 16743 unreferencedAssets.delete(referencedFile); 16744 } 15939 16745 } 15940 16746 } … … 16165 16971 } 16166 16972 for (const module of entryModules) { 16167 // eslint-disable-next-line unicorn/prefer-spread16168 16973 const requiredFacades = Array.from(new Set(module.chunkNames.filter(({ isUserDefined }) => isUserDefined).map(({ name }) => name)), 16169 16974 // mapping must run after Set 'name' dedupe … … 16174 16979 requiredFacades.push({}); 16175 16980 } 16176 // eslint-disable-next-line unicorn/prefer-spread16177 16981 requiredFacades.push(...Array.from(module.chunkFileNames, fileName => ({ fileName }))); 16178 16982 if (requiredFacades.length === 0) { … … 16299 17103 dynamicImports: this.getDynamicDependencies().map(resolveFileName), 16300 17104 fileName: this.getFileName(), 16301 // eslint-disable-next-line unicorn/prefer-spread16302 17105 implicitlyLoadedBefore: Array.from(this.implicitlyLoadedBefore, resolveFileName), 16303 17106 importedBindings: getImportedBindingsPerDependency(this.getRenderedDependencies(), resolveFileName), 16304 // eslint-disable-next-line unicorn/prefer-spread16305 17107 imports: Array.from(this.dependencies, resolveFileName), 16306 17108 modules: this.renderedModules, … … 16347 17149 } 16348 17150 if (format === 'es') { 16349 renderedDependency.reexports = reexports.filter( 16350 // eslint-disable-next-line unicorn/prefer-array-some 16351 ({ reexported }) => !renderedExports.find(({ exported }) => exported === reexported)); 17151 renderedDependency.reexports = reexports.filter(({ reexported }) => !renderedExports.find(({ exported }) => exported === reexported)); 16352 17152 } 16353 17153 } … … 16383 17183 if (format === 'es' || format === 'cjs') { 16384 17184 const shebang = facadeModule !== null && facadeModule.info.isEntry && facadeModule.shebang; 16385 shebang && magicString.prepend(`#!${shebang}\n`); 17185 if (shebang) { 17186 magicString.prepend(`#!${shebang}\n`); 17187 } 16386 17188 } 16387 17189 if (footer) … … 16699 17501 : sanitizedId; 16700 17502 if (isAbsolute$1(idWithoutExtension)) { 16701 return preserveModulesRoot && resolve$1(idWithoutExtension).startsWith(preserveModulesRoot) 16702 ? idWithoutExtension.slice(preserveModulesRoot.length).replace(/^[/\\]/, '') 16703 : relative$1(this.inputBase, idWithoutExtension); 17503 if (preserveModulesRoot && resolve$1(idWithoutExtension).startsWith(preserveModulesRoot)) { 17504 return idWithoutExtension.slice(preserveModulesRoot.length).replace(/^[/\\]/, ''); 17505 } 17506 else { 17507 // handle edge case in Windows 17508 if (this.inputBase === '/' && !idWithoutExtension.startsWith('/')) { 17509 return relative$1(this.inputBase, idWithoutExtension.replace(/^[a-zA-Z]:[/\\]/, '/')); 17510 } 17511 return relative$1(this.inputBase, idWithoutExtension); 17512 } 16704 17513 } 16705 17514 else { 16706 return `_virtual/${basename(idWithoutExtension)}`;17515 return (this.outputOptions.virtualDirname.replace(/\/$/, '') + '/' + basename(idWithoutExtension)); 16707 17516 } 16708 17517 } … … 16841 17650 if (!renderOptions.accessedDocumentCurrentScript && 16842 17651 formatsMaybeAccessDocumentCurrentScript.includes(format)) { 16843 // eslint-disable-next-line unicorn/consistent-destructuring16844 17652 this.accessedGlobalsByScope.get(module.scope)?.delete(DOCUMENT_CURRENT_SCRIPT); 16845 17653 } … … 16883 17691 if (hoistedSource) 16884 17692 magicString.prepend(hoistedSource + n + n); 16885 // eslint-disable-next-line unicorn/consistent-destructuring16886 17693 if (this.needsExportsShim) { 16887 17694 magicString.prepend(`${n}${cnst} ${MISSING_EXPORT_SHIM_VARIABLE}${_}=${_}void 0;${n}${n}`); … … 17191 17998 } 17192 17999 function getChunkDefinitionsFromManualChunks(manualChunkAliasByEntry) { 17193 const chunkDefinitions = [];17194 18000 const modulesInManualChunks = new Set(manualChunkAliasByEntry.keys()); 17195 18001 const manualChunkModulesByAlias = Object.create(null); … … 17197 18003 addStaticDependenciesToManualChunk(entry, (manualChunkModulesByAlias[alias] ||= []), modulesInManualChunks); 17198 18004 } 17199 for (const [alias, modules] of Object.entries(manualChunkModulesByAlias)) { 17200 chunkDefinitions.push({ alias, modules }); 18005 const manualChunks = Object.entries(manualChunkModulesByAlias); 18006 const chunkDefinitions = new Array(manualChunks.length); 18007 let index = 0; 18008 for (const [alias, modules] of manualChunks) { 18009 chunkDefinitions[index++] = { alias, modules }; 17201 18010 } 17202 18011 return { chunkDefinitions, modulesInManualChunks }; … … 17217 18026 const dynamicEntryModules = new Set(); 17218 18027 const dependentEntriesByModule = new Map(); 17219 const dynamicImportModulesByEntry = [];17220 18028 const allEntriesSet = new Set(entries); 18029 const dynamicImportModulesByEntry = new Array(allEntriesSet.size); 17221 18030 let entryIndex = 0; 17222 18031 for (const currentEntry of allEntriesSet) { 17223 18032 const dynamicImportsForCurrentEntry = new Set(); 17224 dynamicImportModulesByEntry .push(dynamicImportsForCurrentEntry);18033 dynamicImportModulesByEntry[entryIndex] = dynamicImportsForCurrentEntry; 17225 18034 const modulesToHandle = new Set([currentEntry]); 17226 18035 for (const module of modulesToHandle) { … … 17267 18076 } 17268 18077 } 17269 const dynamicImportsByEntry = []; 18078 const dynamicImportsByEntry = new Array(dynamicImportModulesByEntry.length); 18079 let index = 0; 17270 18080 for (const dynamicImportModules of dynamicImportModulesByEntry) { 17271 18081 const dynamicImports = new Set(); … … 17273 18083 dynamicImports.add(entryIndexByModule.get(dynamicEntry)); 17274 18084 } 17275 dynamicImportsByEntry .push(dynamicImports);18085 dynamicImportsByEntry[index++] = dynamicImports; 17276 18086 } 17277 18087 return { dynamicEntries, dynamicImportsByEntry }; … … 17378 18188 const chunksBySignature = Object.create(null); 17379 18189 const chunkByModule = new Map(); 17380 const sizeByAtom = [];18190 const sizeByAtom = new Array(chunkAtoms.length); 17381 18191 let sideEffectAtoms = 0n; 17382 18192 let atomMask = 1n; 18193 let index = 0; 17383 18194 for (const { dependentEntries, modules } of chunkAtoms) { 17384 18195 let chunkSignature = 0n; … … 17418 18229 sideEffectAtoms |= atomMask; 17419 18230 } 17420 sizeByAtom .push(atomSize);18231 sizeByAtom[index++] = atomSize; 17421 18232 chunk.containedAtoms |= atomMask; 17422 18233 chunk.modules.push(...modules); … … 17543 18354 return chunks; // the actual modules 17544 18355 } 17545 minChunkSize > 1 &&18356 if (minChunkSize > 1) { 17546 18357 log('info', logOptimizeChunkStatus(chunks.length, chunkPartition.small.size, 'Initially')); 18358 } 17547 18359 mergeChunks(chunkPartition, minChunkSize, sideEffectAtoms, sizeByAtom); 17548 minChunkSize > 1 &&18360 if (minChunkSize > 1) { 17549 18361 log('info', logOptimizeChunkStatus(chunkPartition.small.size + chunkPartition.big.size, chunkPartition.small.size, 'After merging chunks')); 18362 } 17550 18363 timeEnd('optimize chunks', 3); 17551 18364 return [...chunkPartition.small, ...chunkPartition.big]; … … 18016 18829 const getHash = hasherByType[outputOptions.hashCharacters]; 18017 18830 const chunkGraph = getChunkGraph(chunks); 18018 const { initialHashesByPlaceholder, nonHashedChunksWithPlaceholders, renderedChunksByPlaceholder, hashDependenciesByPlaceholder } = await transformChunksAndGenerateContentHashes(renderedChunks, chunkGraph, outputOptions, pluginDriver, getHash, log);18019 const hashesByPlaceholder = generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, bundle, getHash);18831 const { hashDependenciesByPlaceholder, initialHashesByPlaceholder, nonHashedChunksWithPlaceholders, placeholders, renderedChunksByPlaceholder } = await transformChunksAndGenerateContentHashes(renderedChunks, chunkGraph, outputOptions, pluginDriver, getHash, log); 18832 const hashesByPlaceholder = generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, placeholders, bundle, getHash); 18020 18833 addChunksToBundle(renderedChunksByPlaceholder, hashesByPlaceholder, bundle, nonHashedChunksWithPlaceholders, pluginDriver, outputOptions); 18021 18834 timeEnd('transform chunks', 2); … … 18147 18960 initialHashesByPlaceholder, 18148 18961 nonHashedChunksWithPlaceholders, 18962 placeholders, 18149 18963 renderedChunksByPlaceholder 18150 18964 }; 18151 18965 } 18152 function generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, bundle, getHash) {18966 function generateFinalHashes(renderedChunksByPlaceholder, hashDependenciesByPlaceholder, initialHashesByPlaceholder, placeholders, bundle, getHash) { 18153 18967 const hashesByPlaceholder = new Map(initialHashesByPlaceholder); 18154 for (const [placeholder, { fileName }] of renderedChunksByPlaceholder) { 18968 for (const placeholder of placeholders) { 18969 const { fileName } = renderedChunksByPlaceholder.get(placeholder); 18155 18970 let contentToHash = ''; 18156 18971 const hashDependencyPlaceholders = new Set([placeholder]); … … 18184 18999 let finalSourcemapFileName = null; 18185 19000 if (map) { 19001 if (options.sourcemapDebugIds) { 19002 updatedCode += calculateDebugIdAndGetComment(updatedCode, map); 19003 } 18186 19004 finalSourcemapFileName = sourcemapFileName 18187 19005 ? replacePlaceholders(sourcemapFileName, hashesByPlaceholder) … … 18196 19014 let finalSourcemapFileName = null; 18197 19015 if (map) { 19016 if (options.sourcemapDebugIds) { 19017 updatedCode += calculateDebugIdAndGetComment(updatedCode, map); 19018 } 18198 19019 finalSourcemapFileName = sourcemapFileName 18199 19020 ? replacePlaceholders(sourcemapFileName, hashesByPlaceholder) … … 18222 19043 } 18223 19044 return sourcemap === 'hidden' ? '' : `//# ${SOURCEMAPPING_URL}=${url}\n`; 19045 } 19046 function calculateDebugIdAndGetComment(code, map) { 19047 const hash = hasherByType.hex(code); 19048 const debugId = [ 19049 hash.slice(0, 8), 19050 hash.slice(8, 12), 19051 '4' + hash.slice(12, 15), 19052 ((parseInt(hash.slice(15, 16), 16) & 3) | 8).toString(16) + hash.slice(17, 20), 19053 hash.slice(20, 32) 19054 ].join('-'); 19055 map.debugId = debugId; 19056 return '//# debugId=' + debugId + '\n'; 18224 19057 } 18225 19058 … … 18286 19119 } 18287 19120 assignManualChunks(getManualChunk) { 18288 // eslint-disable-next-line unicorn/prefer-module18289 19121 const manualChunkAliasesWithEntry = []; 18290 19122 const manualChunksApi = { … … 18312 19144 if ('code' in file) { 18313 19145 try { 18314 parseAst(file.code );19146 parseAst(file.code, { jsx: this.inputOptions.jsx !== false }); 18315 19147 } 18316 19148 catch (error_) { … … 18331 19163 const inputBase = commondir(getAbsoluteEntryModulePaths(includedModules, preserveModules)); 18332 19164 const externalChunkByModule = getExternalChunkByModule(this.graph.modulesById, this.outputOptions, inputBase); 18333 const chunks = []; 18334 const chunkByModule = new Map(); 18335 for (const { alias, modules } of inlineDynamicImports 19165 const executableModule = inlineDynamicImports 18336 19166 ? [{ alias: null, modules: includedModules }] 18337 19167 : preserveModules 18338 19168 ? includedModules.map(module => ({ alias: null, modules: [module] })) 18339 : getChunkAssignments(this.graph.entryModules, manualChunkAliasByEntry, experimentalMinChunkSize, this.inputOptions.onLog)) { 19169 : getChunkAssignments(this.graph.entryModules, manualChunkAliasByEntry, experimentalMinChunkSize, this.inputOptions.onLog); 19170 const chunks = new Array(executableModule.length); 19171 const chunkByModule = new Map(); 19172 let index = 0; 19173 for (const { alias, modules } of executableModule) { 18340 19174 sortByExecutionOrder(modules); 18341 19175 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); 18342 chunks .push(chunk);19176 chunks[index++] = chunk; 18343 19177 } 18344 19178 for (const chunk of chunks) { … … 18440 19274 } 18441 19275 }; 19276 } 19277 19278 class GlobalScope extends Scope { 19279 constructor() { 19280 super(); 19281 this.parent = null; 19282 this.variables.set('undefined', new UndefinedVariable()); 19283 } 19284 findVariable(name) { 19285 let variable = this.variables.get(name); 19286 if (!variable) { 19287 variable = new GlobalVariable(name); 19288 this.variables.set(name, variable); 19289 } 19290 return variable; 19291 } 18442 19292 } 18443 19293 … … 18689 19539 tryCatchDeoptimization: false, 18690 19540 unknownGlobalSideEffects: false 19541 } 19542 }; 19543 const jsxPresets = { 19544 preserve: { 19545 factory: null, 19546 fragment: null, 19547 importSource: null, 19548 mode: 'preserve' 19549 }, 19550 'preserve-react': { 19551 factory: 'React.createElement', 19552 fragment: 'React.Fragment', 19553 importSource: 'react', 19554 mode: 'preserve' 19555 }, 19556 react: { 19557 factory: 'React.createElement', 19558 fragment: 'React.Fragment', 19559 importSource: 'react', 19560 mode: 'classic' 19561 }, 19562 'react-jsx': { 19563 factory: 'React.createElement', 19564 importSource: 'react', 19565 jsxImportSource: 'react/jsx-runtime', 19566 mode: 'automatic' 18691 19567 } 18692 19568 }; … … 19166 20042 } 19167 20043 getResolveStaticDependencyPromises(module) { 19168 // eslint-disable-next-line unicorn/prefer-spread19169 20044 return Array.from(module.sourcesWithAttributes, async ([source, attributes]) => [ 19170 20045 source, … … 19305 20180 } 19306 20181 19307 class GlobalScope extends Scope { 19308 constructor() { 19309 super(); 19310 this.parent = null; 19311 this.variables.set('undefined', new UndefinedVariable()); 19312 } 19313 findVariable(name) { 19314 let variable = this.variables.get(name); 19315 if (!variable) { 19316 variable = new GlobalVariable(name); 19317 this.variables.set(name, variable); 19318 } 19319 return variable; 19320 } 19321 } 19322 19323 function generateAssetFileName(name, source, originalFileName, sourceHash, outputOptions, bundle) { 20182 function generateAssetFileName(name, names, source, originalFileName, originalFileNames, sourceHash, outputOptions, bundle, inputOptions) { 19324 20183 const emittedName = outputOptions.sanitizeFileName(name || 'asset'); 19325 20184 return makeUnique(renderNamePattern(typeof outputOptions.assetFileNames === 'function' 19326 ? outputOptions.assetFileNames({ name, originalFileName, source, type: 'asset' }) 20185 ? outputOptions.assetFileNames({ 20186 // Additionally, this should be non-enumerable in the next major 20187 get name() { 20188 warnDeprecation('Accessing the "name" property of emitted assets when generating the file name is deprecated. Use the "names" property instead.', URL_GENERATEBUNDLE, false, inputOptions); 20189 return name; 20190 }, 20191 names, 20192 // Additionally, this should be non-enumerable in the next major 20193 get originalFileName() { 20194 warnDeprecation('Accessing the "originalFileName" property of emitted assets when generating the file name is deprecated. Use the "originalFileNames" property instead.', URL_GENERATEBUNDLE, false, inputOptions); 20195 return originalFileName; 20196 }, 20197 originalFileNames, 20198 source, 20199 type: 'asset' 20200 }) 19327 20201 : outputOptions.assetFileNames, 'output.assetFileNames', { 19328 20202 ext: () => extname(emittedName).slice(1), … … 19440 20314 const output = (this.output = { 19441 20315 bundle, 19442 fileNamesBySource : new Map(),20316 fileNamesBySourceHash: new Map(), 19443 20317 getHash, 19444 20318 outputOptions … … 19595 20469 return referenceId; 19596 20470 } 19597 finalizeAdditionalAsset(consumedFile, source, { bundle, fileNamesBySource , getHash, outputOptions }) {19598 let { fileName, n eedsCodeReference, originalFileName, referenceId } = consumedFile;20471 finalizeAdditionalAsset(consumedFile, source, { bundle, fileNamesBySourceHash, getHash, outputOptions }) { 20472 let { fileName, name, needsCodeReference, originalFileName, referenceId } = consumedFile; 19599 20473 // Deduplicate assets if an explicit fileName is not provided 19600 20474 if (!fileName) { 19601 20475 const sourceHash = getHash(source); 19602 fileName = fileNamesBySource .get(sourceHash);20476 fileName = fileNamesBySourceHash.get(sourceHash); 19603 20477 if (!fileName) { 19604 fileName = generateAssetFileName( consumedFile.name, source, originalFileName, sourceHash, outputOptions, bundle);19605 fileNamesBySource .set(sourceHash, fileName);20478 fileName = generateAssetFileName(name, name ? [name] : [], source, originalFileName, originalFileName ? [originalFileName] : [], sourceHash, outputOptions, bundle, this.options); 20479 fileNamesBySourceHash.set(sourceHash, fileName); 19606 20480 } 19607 20481 } … … 19612 20486 if (existingAsset?.type === 'asset') { 19613 20487 existingAsset.needsCodeReference &&= needsCodeReference; 20488 if (name) { 20489 existingAsset.names.push(name); 20490 } 20491 if (originalFileName) { 20492 existingAsset.originalFileNames.push(originalFileName); 20493 } 19614 20494 } 19615 20495 else { 20496 const { options } = this; 19616 20497 bundle[fileName] = { 19617 20498 fileName, 19618 name: consumedFile.name, 20499 get name() { 20500 // Additionally, this should be non-enumerable in the next major 20501 warnDeprecation('Accessing the "name" property of emitted assets in the bundle is deprecated. Use the "names" property instead.', URL_GENERATEBUNDLE, false, options); 20502 return name; 20503 }, 20504 names: name ? [name] : [], 19619 20505 needsCodeReference, 19620 originalFileName, 20506 get originalFileName() { 20507 // Additionally, this should be non-enumerable in the next major 20508 warnDeprecation('Accessing the "originalFileName" property of emitted assets in the bundle is deprecated. Use the "originalFileNames" property instead.', URL_GENERATEBUNDLE, false, options); 20509 return originalFileName; 20510 }, 20511 originalFileNames: originalFileName ? [originalFileName] : [], 19621 20512 source, 19622 20513 type: 'asset' … … 19624 20515 } 19625 20516 } 19626 finalizeAssetsWithSameSource(consumedFiles, sourceHash, { bundle, fileNamesBySource, outputOptions }) { 20517 finalizeAssetsWithSameSource(consumedFiles, sourceHash, { bundle, fileNamesBySourceHash, outputOptions }) { 20518 const { names, originalFileNames } = getNamesFromAssets(consumedFiles); 19627 20519 let fileName = ''; 19628 20520 let usedConsumedFile; … … 19630 20522 for (const consumedFile of consumedFiles) { 19631 20523 needsCodeReference &&= consumedFile.needsCodeReference; 19632 const assetFileName = generateAssetFileName(consumedFile.name, consumedFile.source, consumedFile.originalFileName, sourceHash, outputOptions, bundle);20524 const assetFileName = generateAssetFileName(consumedFile.name, names, consumedFile.source, consumedFile.originalFileName, originalFileNames, sourceHash, outputOptions, bundle, this.options); 19633 20525 if (!fileName || 19634 20526 assetFileName.length < fileName.length || … … 19638 20530 } 19639 20531 } 19640 fileNamesBySource .set(sourceHash, fileName);20532 fileNamesBySourceHash.set(sourceHash, fileName); 19641 20533 for (const consumedFile of consumedFiles) { 19642 20534 // We must not modify the original assets to avoid interaction between outputs … … 19644 20536 this.filesByReferenceId.set(consumedFile.referenceId, assetWithFileName); 19645 20537 } 20538 const { options } = this; 19646 20539 bundle[fileName] = { 19647 20540 fileName, 19648 name: usedConsumedFile.name, 20541 get name() { 20542 // Additionally, this should be non-enumerable in the next major 20543 warnDeprecation('Accessing the "name" property of emitted assets in the bundle is deprecated. Use the "names" property instead.', URL_GENERATEBUNDLE, false, options); 20544 return usedConsumedFile.name; 20545 }, 20546 names, 19649 20547 needsCodeReference, 19650 originalFileName: usedConsumedFile.originalFileName, 20548 get originalFileName() { 20549 // Additionally, this should be non-enumerable in the next major 20550 warnDeprecation('Accessing the "originalFileName" property of emitted assets in the bundle is deprecated. Use the "originalFileNames" property instead.', URL_GENERATEBUNDLE, false, options); 20551 return usedConsumedFile.originalFileName; 20552 }, 20553 originalFileNames, 19651 20554 source: usedConsumedFile.source, 19652 20555 type: 'asset' 19653 20556 }; 19654 20557 } 20558 } 20559 function getNamesFromAssets(consumedFiles) { 20560 const names = []; 20561 const originalFileNames = []; 20562 for (const { name, originalFileName } of consumedFiles) { 20563 if (typeof name === 'string') { 20564 names.push(name); 20565 } 20566 if (originalFileName) { 20567 originalFileNames.push(originalFileName); 20568 } 20569 } 20570 originalFileNames.sort(); 20571 // Sort by length first and then alphabetically so that the order is stable 20572 // and the shortest names come first 20573 names.sort((a, b) => a.length - b.length || (a > b ? 1 : a === b ? 0 : -1)); 20574 return { names, originalFileNames }; 19655 20575 } 19656 20576 … … 19889 20809 return handler; 19890 20810 } 19891 // eslint-disable-next-line @typescript-eslint/ ban-types20811 // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type 19892 20812 const hookResult = handler.apply(context, parameters); 19893 20813 if (!hookResult?.then) { … … 19934 20854 } 19935 20855 try { 19936 // eslint-disable-next-line @typescript-eslint/ ban-types20856 // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type 19937 20857 return handler.apply(context, parameters); 19938 20858 } … … 20136 21056 for (const module of this.modules) { 20137 21057 if (module.isExecuted) { 21058 module.hasTreeShakingPassStarted = true; 20138 21059 if (module.info.moduleSideEffects === 'no-treeshake') { 20139 21060 module.includeAllInBundle(); … … 20310 21231 external: getIdMatcher(config.external), 20311 21232 input: getInput(config), 21233 jsx: getJsx(config), 20312 21234 logLevel, 20313 21235 makeAbsoluteExternalsRelative: config.makeAbsoluteExternalsRelative ?? 'ifRelativeSource', … … 20354 21276 const configInput = config.input; 20355 21277 return configInput == null ? [] : typeof configInput === 'string' ? [configInput] : configInput; 21278 }; 21279 const getJsx = (config) => { 21280 const configJsx = config.jsx; 21281 if (!configJsx) 21282 return false; 21283 const configWithPreset = getOptionWithPreset(configJsx, jsxPresets, 'jsx', URL_JSX, 'false, '); 21284 const { factory, importSource, mode } = configWithPreset; 21285 switch (mode) { 21286 case 'automatic': { 21287 return { 21288 factory: factory || 'React.createElement', 21289 importSource: importSource || 'react', 21290 jsxImportSource: configWithPreset.jsxImportSource || 'react/jsx-runtime', 21291 mode: 'automatic' 21292 }; 21293 } 21294 case 'preserve': { 21295 if (importSource && !(factory || configWithPreset.fragment)) { 21296 error(logInvalidOption('jsx', URL_JSX, 'when preserving JSX and specifying an importSource, you also need to specify a factory or fragment')); 21297 } 21298 return { 21299 factory: factory || null, 21300 fragment: configWithPreset.fragment || null, 21301 importSource: importSource || null, 21302 mode: 'preserve' 21303 }; 21304 } 21305 // case 'classic': 21306 default: { 21307 if (mode && mode !== 'classic') { 21308 error(logInvalidOption('jsx.mode', URL_JSX, 'mode must be "automatic", "classic" or "preserve"', mode)); 21309 } 21310 return { 21311 factory: factory || 'React.createElement', 21312 fragment: configWithPreset.fragment || 'React.Fragment', 21313 importSource: importSource || null, 21314 mode: 'classic' 21315 }; 21316 } 21317 } 20356 21318 }; 20357 21319 const getMaxParallelFileOps = (config) => { … … 20485 21447 sourcemap: config.sourcemap || false, 20486 21448 sourcemapBaseUrl: getSourcemapBaseUrl(config), 21449 sourcemapDebugIds: config.sourcemapDebugIds || false, 20487 21450 sourcemapExcludeSources: config.sourcemapExcludeSources || false, 20488 21451 sourcemapFile: config.sourcemapFile, … … 20496 21459 strict: config.strict ?? true, 20497 21460 systemNullSetters: config.systemNullSetters ?? true, 20498 validate: config.validate || false 21461 validate: config.validate || false, 21462 virtualDirname: config.virtualDirname || '_virtual' 20499 21463 }; 20500 21464 warnUnknownOptions(config, Object.keys(outputOptions), 'output options', inputOptions.onLog); … … 20601 21565 return () => configAddon || ''; 20602 21566 }; 20603 // eslint-disable-next-line unicorn/prevent-abbreviations20604 21567 const getDir = (config, file) => { 20605 21568 const { dir } = config; … … 20671 21634 const validateInterop = (interop) => { 20672 21635 if (!ALLOWED_INTEROP_TYPES.has(interop)) { 20673 return error(logInvalidOption('output.interop', URL_OUTPUT_INTEROP, 20674 // eslint-disable-next-line unicorn/prefer-spread 20675 `use one of ${Array.from(ALLOWED_INTEROP_TYPES, value => JSON.stringify(value)).join(', ')}`, interop)); 21636 return error(logInvalidOption('output.interop', URL_OUTPUT_INTEROP, `use one of ${Array.from(ALLOWED_INTEROP_TYPES, value => JSON.stringify(value)).join(', ')}`, interop)); 20676 21637 } 20677 21638 return interop; … … 20707 21668 }; 20708 21669 21670 // @ts-expect-error TS2540: the polyfill of `asyncDispose`. 21671 Symbol.asyncDispose ??= Symbol('Symbol.asyncDispose'); 20709 21672 function rollup(rawInputOptions) { 20710 21673 return rollupInternal(rawInputOptions, null); … … 20750 21713 }, 20751 21714 closed: false, 21715 async [Symbol.asyncDispose]() { 21716 await this.close(); 21717 }, 20752 21718 async generate(rawOutputOptions) { 20753 21719 if (result.closed) … … 21111 22077 external: getExternal(config, overrides), 21112 22078 input: getOption('input') || [], 22079 jsx: getObjectOption(config, overrides, 'jsx', objectifyOptionWithPresets(jsxPresets, 'jsx', URL_JSX, 'false, ')), 21113 22080 logLevel: getOption('logLevel'), 21114 22081 makeAbsoluteExternalsRelative: getOption('makeAbsoluteExternalsRelative'), … … 21197 22164 sourcemap: getOption('sourcemap'), 21198 22165 sourcemapBaseUrl: getOption('sourcemapBaseUrl'), 22166 sourcemapDebugIds: getOption('sourcemapDebugIds'), 21199 22167 sourcemapExcludeSources: getOption('sourcemapExcludeSources'), 21200 22168 sourcemapFile: getOption('sourcemapFile'), … … 21204 22172 strict: getOption('strict'), 21205 22173 systemNullSetters: getOption('systemNullSetters'), 21206 validate: getOption('validate') 22174 validate: getOption('validate'), 22175 virtualDirname: getOption('virtualDirname') 21207 22176 }; 21208 22177 warnUnknownOptions(config, Object.keys(outputOptions), 'output options', log); … … 21304 22273 } 21305 22274 21306 export { createFilter, defineConfig, fseventsImporter, getAugmentedNamespace, picomatch, rollup, rollupInternal, version, watch };22275 export { createFilter, defineConfig, fseventsImporter, getAugmentedNamespace, getDefaultExportFromCjs, rollup, rollupInternal, version, watch }; -
imaps-frontend/node_modules/rollup/dist/es/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 … … 21 21 const Identifier = 'Identifier'; 22 22 const Literal = 'Literal'; 23 const ObjectExpression = 'ObjectExpression'; 23 24 const PanicError = 'PanicError'; 24 25 const ParseError = 'ParseError'; … … 113 114 return EMPTY_ARRAY; 114 115 const length = buffer[position++]; 115 const list = [];116 const list = new Array(length); 116 117 for (let index = 0; index < length; index++) { 117 list .push(convertAnnotation(buffer[position++], buffer));118 list[index] = convertAnnotation(buffer[position++], buffer); 118 119 } 119 120 return list; … … 363 364 const URL_TREATING_MODULE_AS_EXTERNAL_DEPENDENCY = 'troubleshooting/#warning-treating-module-as-external-dependency'; 364 365 const URL_SOURCEMAP_IS_LIKELY_TO_BE_INCORRECT = 'troubleshooting/#warning-sourcemap-is-likely-to-be-incorrect'; 366 // configuration-options 367 const URL_JSX = 'configuration-options/#jsx'; 365 368 const URL_OUTPUT_AMD_ID = 'configuration-options/#output-amd-id'; 366 369 const URL_OUTPUT_AMD_BASEPATH = 'configuration-options/#output-amd-basepath'; … … 384 387 const URL_TREESHAKE_MODULESIDEEFFECTS = 'configuration-options/#treeshake-modulesideeffects'; 385 388 const URL_WATCH = 'configuration-options/#watch'; 389 const URL_GENERATEBUNDLE = 'plugin-development/#generatebundle'; 386 390 387 391 function error(base) { … … 432 436 prefix += `${relativeId(id)}${position}: `; 433 437 } 438 const oldMessage = log.message; 434 439 log.message = prefix + log.message; 440 tweakStackMessage(log, oldMessage); 435 441 } 436 442 // Error codes should be sorted alphabetically while errors should be sorted by 437 443 // error code below 438 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_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', 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_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_EXPORT = 'MISSING_EXPORT', 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', 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';444 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_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', 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_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_EXPORT = 'MISSING_EXPORT', 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', 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'; 439 445 function logAddonNotGenerated(message, hook, plugin) { 440 446 return { … … 658 664 }; 659 665 } 666 function tweakStackMessage(error, oldMessage) { 667 if (!error.stack) { 668 return error; 669 } 670 error.stack = error.stack.replace(oldMessage, error.message); 671 return error; 672 } 660 673 function logInvalidExportOptionValue(optionValue) { 661 674 return { … … 788 801 }; 789 802 } 803 function logMissingJsxExport(name, exporter, importer) { 804 return { 805 code: MISSING_JSX_EXPORT, 806 exporter, 807 id: importer, 808 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.`, 809 names: [name], 810 url: getRollupUrl(URL_JSX) 811 }; 812 } 790 813 function logMissingNameOptionForIifeExport() { 791 814 return { … … 809 832 }; 810 833 } 811 // eslint-disable-next-line unicorn/prevent-abbreviations812 834 function logMissingFileOrDirOption() { 813 835 return { … … 865 887 }; 866 888 } 889 function logReservedNamespace(namespace) { 890 return { 891 code: RESERVED_NAMESPACE, 892 message: `You have overided reserved namespace "${namespace}"` 893 }; 894 } 867 895 function logModuleParseError(error, moduleId) { 868 896 let message = error.message.replace(/ \(\d+:\d+\)$/, ''); … … 873 901 message += ' (Note that you need plugins to import files that are not JavaScript)'; 874 902 } 875 return {903 return tweakStackMessage({ 876 904 cause: error, 877 905 code: PARSE_ERROR, … … 879 907 message, 880 908 stack: error.stack 881 } ;909 }, error.message); 882 910 } 883 911 function logPluginError(error, plugin, { hook, id } = {}) { … … 1036 1064 } 1037 1065 function warnDeprecationWithOptions(deprecation, urlSnippet, activeDeprecation, log, strictDeprecations, plugin) { 1038 {1066 if (activeDeprecation || strictDeprecations) { 1039 1067 const warning = logDeprecation(deprecation, urlSnippet); 1040 1068 if (strictDeprecations) { … … 1485 1513 }; 1486 1514 }, 1515 function jsxAttribute(position, buffer) { 1516 const valuePosition = buffer[position + 3]; 1517 return { 1518 type: 'JSXAttribute', 1519 start: buffer[position], 1520 end: buffer[position + 1], 1521 name: convertNode(buffer[position + 2], buffer), 1522 value: valuePosition === 0 ? null : convertNode(valuePosition, buffer) 1523 }; 1524 }, 1525 function jsxClosingElement(position, buffer) { 1526 return { 1527 type: 'JSXClosingElement', 1528 start: buffer[position], 1529 end: buffer[position + 1], 1530 name: convertNode(buffer[position + 2], buffer) 1531 }; 1532 }, 1533 function jsxClosingFragment(position, buffer) { 1534 return { 1535 type: 'JSXClosingFragment', 1536 start: buffer[position], 1537 end: buffer[position + 1] 1538 }; 1539 }, 1540 function jsxElement(position, buffer) { 1541 const closingElementPosition = buffer[position + 4]; 1542 return { 1543 type: 'JSXElement', 1544 start: buffer[position], 1545 end: buffer[position + 1], 1546 openingElement: convertNode(buffer[position + 2], buffer), 1547 children: convertNodeList(buffer[position + 3], buffer), 1548 closingElement: closingElementPosition === 0 ? null : convertNode(closingElementPosition, buffer) 1549 }; 1550 }, 1551 function jsxEmptyExpression(position, buffer) { 1552 return { 1553 type: 'JSXEmptyExpression', 1554 start: buffer[position], 1555 end: buffer[position + 1] 1556 }; 1557 }, 1558 function jsxExpressionContainer(position, buffer) { 1559 return { 1560 type: 'JSXExpressionContainer', 1561 start: buffer[position], 1562 end: buffer[position + 1], 1563 expression: convertNode(buffer[position + 2], buffer) 1564 }; 1565 }, 1566 function jsxFragment(position, buffer) { 1567 return { 1568 type: 'JSXFragment', 1569 start: buffer[position], 1570 end: buffer[position + 1], 1571 openingFragment: convertNode(buffer[position + 2], buffer), 1572 children: convertNodeList(buffer[position + 3], buffer), 1573 closingFragment: convertNode(buffer[position + 4], buffer) 1574 }; 1575 }, 1576 function jsxIdentifier(position, buffer) { 1577 return { 1578 type: 'JSXIdentifier', 1579 start: buffer[position], 1580 end: buffer[position + 1], 1581 name: buffer.convertString(buffer[position + 2]) 1582 }; 1583 }, 1584 function jsxMemberExpression(position, buffer) { 1585 return { 1586 type: 'JSXMemberExpression', 1587 start: buffer[position], 1588 end: buffer[position + 1], 1589 object: convertNode(buffer[position + 2], buffer), 1590 property: convertNode(buffer[position + 3], buffer) 1591 }; 1592 }, 1593 function jsxNamespacedName(position, buffer) { 1594 return { 1595 type: 'JSXNamespacedName', 1596 start: buffer[position], 1597 end: buffer[position + 1], 1598 namespace: convertNode(buffer[position + 2], buffer), 1599 name: convertNode(buffer[position + 3], buffer) 1600 }; 1601 }, 1602 function jsxOpeningElement(position, buffer) { 1603 const flags = buffer[position + 2]; 1604 return { 1605 type: 'JSXOpeningElement', 1606 start: buffer[position], 1607 end: buffer[position + 1], 1608 selfClosing: (flags & 1) === 1, 1609 name: convertNode(buffer[position + 3], buffer), 1610 attributes: convertNodeList(buffer[position + 4], buffer) 1611 }; 1612 }, 1613 function jsxOpeningFragment(position, buffer) { 1614 return { 1615 type: 'JSXOpeningFragment', 1616 start: buffer[position], 1617 end: buffer[position + 1], 1618 attributes: [], 1619 selfClosing: false 1620 }; 1621 }, 1622 function jsxSpreadAttribute(position, buffer) { 1623 return { 1624 type: 'JSXSpreadAttribute', 1625 start: buffer[position], 1626 end: buffer[position + 1], 1627 argument: convertNode(buffer[position + 2], buffer) 1628 }; 1629 }, 1630 function jsxSpreadChild(position, buffer) { 1631 return { 1632 type: 'JSXSpreadChild', 1633 start: buffer[position], 1634 end: buffer[position + 1], 1635 expression: convertNode(buffer[position + 2], buffer) 1636 }; 1637 }, 1638 function jsxText(position, buffer) { 1639 return { 1640 type: 'JSXText', 1641 start: buffer[position], 1642 end: buffer[position + 1], 1643 value: buffer.convertString(buffer[position + 2]), 1644 raw: buffer.convertString(buffer[position + 3]) 1645 }; 1646 }, 1487 1647 function labeledStatement(position, buffer) { 1488 1648 return { … … 1878 2038 return EMPTY_ARRAY; 1879 2039 const length = buffer[position++]; 1880 const list = [];2040 const list = new Array(length); 1881 2041 for (let index = 0; index < length; index++) { 1882 2042 const nodePosition = buffer[position++]; 1883 list .push(nodePosition ? convertNode(nodePosition, buffer) : null);2043 list[index] = nodePosition ? convertNode(nodePosition, buffer) : null; 1884 2044 } 1885 2045 return list; … … 1907 2067 } 1908 2068 1909 const parseAst = (input, { allowReturnOutsideFunction = false } = {}) => convertProgram(getAstBuffer(parse(input, allowReturnOutsideFunction)));1910 const parseAstAsync = async (input, { allowReturnOutsideFunction = false, signal } = {}) => convertProgram(getAstBuffer(await parseAsync(input, allowReturnOutsideFunction, signal)));1911 1912 export { ANNOTATION_KEY, ArrowFunctionExpression, BLANK, BlockStatement, CallExpression, CatchClause, EMPTY_ARRAY, EMPTY_OBJECT, EMPTY_SET, ExportDefaultDeclaration, ExpressionStatement, FIXED_STRINGS, INVALID_ANNOTATION_KEY, Identifier, LOGLEVEL_DEBUG, LOGLEVEL_ERROR, LOGLEVEL_INFO, LOGLEVEL_WARN, Literal, Program, Property, ReturnStatement, StaticBlock, TemplateLiteral, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_AMD_ID, URL_OUTPUT_DIR, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, URL_OUTPUT_FORMAT, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_OUTPUT_INTEROP, URL_OUTPUT_MANUALCHUNKS, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_SOURCEMAPFILE, URL_PRESERVEENTRYSIGNATURES, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, URL_WATCH, VariableDeclarator, addTrailingSlashIfMissed, augmentCodeLocation, augmentLogMessage, convertAnnotations, convertNode, error, getAliasName, getAstBuffer, getImportPath, getRollupError, isAbsolute, isPathFragment, isRelative, isValidUrl, locate, logAddonNotGenerated, logAlreadyClosed, logAmbiguousExternalNamespaces, logAnonymousPluginCache, logAssetNotFinalisedForFileName, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logBadLoader, logCannotAssignModuleToChunk, logCannotCallNamespace, logCannotEmitFromOptionsHook, logChunkInvalid, logChunkNotGeneratedForFileName, logCircularDependency, logCircularReexport, logConflictingSourcemapSources, logConstVariableReassignError, logCyclicCrossChunkReexport, logDuplicateArgumentNameError, logDuplicateExportError, logDuplicatePluginName, logEmptyChunk, logEntryCannotBeExternal, logEval, logExternalModulesCannotBeIncludedInManualChunks, logExternalModulesCannotBeTransformedToModules, logExternalSyntheticExports, logFailedValidation, logFileNameConflict, logFileReferenceIdNotFoundForFilename, logFirstSideEffect, logIllegalIdentifierAsName, logIllegalImportReassignment, logImplicitDependantCannotBeExternal, logImplicitDependantIsNotIncluded, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logIncompatibleExportOptionValue, logInconsistentImportAttributes, logInputHookInOutputPlugin, logInternalIdCannotBeExternal, logInvalidAddonPluginHook, logInvalidAnnotation, logInvalidExportOptionValue, logInvalidFormatForTopLevelAwait, logInvalidFunctionPluginHook, logInvalidLogPosition, logInvalidOption, logInvalidRollupPhaseForChunkEmission, logInvalidSetAssetSourceCall, logInvalidSourcemapForError, logLevelPriority, logMissingEntryExport, logMissingExport, logMissingFileOrDirOption, logMissingGlobalName, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, logMissingNodeBuiltins, logMixedExport, logModuleLevelDirective, logModuleParseError, logNamespaceConflict, logNoAssetSourceSet, logNoTransformMapOrAstWithoutCode, logOptimizeChunkStatus, logParseError, logPluginError, logRedeclarationError, logShimmedExport, logSourcemapBroken, logSyntheticNamedExportsNeedNamespaceExport, logThisIsUndefined, logUnexpectedNamedImport, logUnexpectedNamespaceReexport, logUnknownOption, logUnresolvedEntry, logUnresolvedImplicitDependant, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logUnusedExternalImports, normalize, parseAst, parseAstAsync, printQuotedStringList, relative, relativeId, warnDeprecation };2069 const parseAst = (input, { allowReturnOutsideFunction = false, jsx = false } = {}) => convertProgram(getAstBuffer(parse(input, allowReturnOutsideFunction, jsx))); 2070 const parseAstAsync = async (input, { allowReturnOutsideFunction = false, jsx = false, signal } = {}) => convertProgram(getAstBuffer(await parseAsync(input, allowReturnOutsideFunction, jsx, signal))); 2071 2072 export { ANNOTATION_KEY, ArrowFunctionExpression, BLANK, BlockStatement, CallExpression, CatchClause, EMPTY_ARRAY, EMPTY_OBJECT, EMPTY_SET, ExportDefaultDeclaration, ExpressionStatement, FIXED_STRINGS, INVALID_ANNOTATION_KEY, Identifier, LOGLEVEL_DEBUG, LOGLEVEL_ERROR, LOGLEVEL_INFO, LOGLEVEL_WARN, Literal, ObjectExpression, Program, Property, ReturnStatement, StaticBlock, TemplateLiteral, URL_GENERATEBUNDLE, URL_JSX, URL_OUTPUT_AMD_BASEPATH, URL_OUTPUT_AMD_ID, URL_OUTPUT_DIR, URL_OUTPUT_EXTERNALIMPORTATTRIBUTES, URL_OUTPUT_FORMAT, URL_OUTPUT_GENERATEDCODE, URL_OUTPUT_INLINEDYNAMICIMPORTS, URL_OUTPUT_INTEROP, URL_OUTPUT_MANUALCHUNKS, URL_OUTPUT_SOURCEMAPBASEURL, URL_OUTPUT_SOURCEMAPFILE, URL_PRESERVEENTRYSIGNATURES, URL_TREESHAKE, URL_TREESHAKE_MODULESIDEEFFECTS, URL_WATCH, VariableDeclarator, addTrailingSlashIfMissed, augmentCodeLocation, augmentLogMessage, convertAnnotations, convertNode, error, getAliasName, getAstBuffer, getImportPath, getRollupError, isAbsolute, isPathFragment, isRelative, isValidUrl, locate, logAddonNotGenerated, logAlreadyClosed, logAmbiguousExternalNamespaces, logAnonymousPluginCache, logAssetNotFinalisedForFileName, logAssetReferenceIdNotFoundForSetSource, logAssetSourceAlreadySet, logBadLoader, logCannotAssignModuleToChunk, logCannotCallNamespace, logCannotEmitFromOptionsHook, logChunkInvalid, logChunkNotGeneratedForFileName, logCircularDependency, logCircularReexport, logConflictingSourcemapSources, logConstVariableReassignError, logCyclicCrossChunkReexport, logDuplicateArgumentNameError, logDuplicateExportError, logDuplicatePluginName, logEmptyChunk, logEntryCannotBeExternal, logEval, logExternalModulesCannotBeIncludedInManualChunks, logExternalModulesCannotBeTransformedToModules, logExternalSyntheticExports, logFailedValidation, logFileNameConflict, logFileReferenceIdNotFoundForFilename, logFirstSideEffect, logIllegalIdentifierAsName, logIllegalImportReassignment, logImplicitDependantCannotBeExternal, logImplicitDependantIsNotIncluded, logImportAttributeIsInvalid, logImportOptionsAreInvalid, logIncompatibleExportOptionValue, logInconsistentImportAttributes, logInputHookInOutputPlugin, logInternalIdCannotBeExternal, logInvalidAddonPluginHook, logInvalidAnnotation, logInvalidExportOptionValue, logInvalidFormatForTopLevelAwait, logInvalidFunctionPluginHook, logInvalidLogPosition, logInvalidOption, logInvalidRollupPhaseForChunkEmission, logInvalidSetAssetSourceCall, logInvalidSourcemapForError, logLevelPriority, logMissingEntryExport, logMissingExport, logMissingFileOrDirOption, logMissingGlobalName, logMissingJsxExport, logMissingNameOptionForIifeExport, logMissingNameOptionForUmdExport, logMissingNodeBuiltins, logMixedExport, logModuleLevelDirective, logModuleParseError, logNamespaceConflict, logNoAssetSourceSet, logNoTransformMapOrAstWithoutCode, logOptimizeChunkStatus, logParseError, logPluginError, logRedeclarationError, logReservedNamespace, logShimmedExport, logSourcemapBroken, logSyntheticNamedExportsNeedNamespaceExport, logThisIsUndefined, logUnexpectedNamedImport, logUnexpectedNamespaceReexport, logUnknownOption, logUnresolvedEntry, logUnresolvedImplicitDependant, logUnresolvedImport, logUnresolvedImportTreatedAsExternal, logUnusedExternalImports, normalize, parseAst, parseAstAsync, printQuotedStringList, relative, relativeId, warnDeprecation }; -
imaps-frontend/node_modules/rollup/dist/es/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 … … 8 8 Released under the MIT License. 9 9 */ 10 import path$1 from 'node:path'; 10 import { getAugmentedNamespace, fseventsImporter, getDefaultExportFromCjs, createFilter, rollupInternal } from './node-entry.js'; 11 import path from 'node:path'; 11 12 import process$1 from 'node:process'; 12 import { picomatch as picomatch$2, getAugmentedNamespace, fseventsImporter, createFilter, rollupInternal } from './node-entry.js'; 13 import { platform } from 'node:os'; 14 import require$$0$1 from 'fs'; 13 import require$$0$1 from 'path'; 14 import require$$0$2 from 'fs'; 15 15 import require$$2 from 'util'; 16 16 import require$$1 from 'stream'; 17 import require$$0$2 from 'path';18 17 import require$$2$1 from 'os'; 19 18 import require$$0$3 from 'events'; 19 import { platform } from 'node:os'; 20 20 import './parseAst.js'; 21 21 import '../../native.js'; … … 24 24 import 'tty'; 25 25 26 var chokidar = {}; 27 28 const fs$3 = require$$0$1; 29 const { Readable } = require$$1; 30 const sysPath$3 = require$$0$2; 31 const { promisify: promisify$3 } = require$$2; 32 const picomatch$1 = picomatch$2; 33 34 const readdir$1 = promisify$3(fs$3.readdir); 35 const stat$3 = promisify$3(fs$3.stat); 36 const lstat$2 = promisify$3(fs$3.lstat); 37 const realpath$1 = promisify$3(fs$3.realpath); 38 39 /** 40 * @typedef {Object} EntryInfo 41 * @property {String} path 42 * @property {String} fullPath 43 * @property {fs.Stats=} stats 44 * @property {fs.Dirent=} dirent 45 * @property {String} basename 46 */ 47 48 const BANG$2 = '!'; 49 const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR'; 50 const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]); 51 const FILE_TYPE = 'files'; 52 const DIR_TYPE = 'directories'; 53 const FILE_DIR_TYPE = 'files_directories'; 54 const EVERYTHING_TYPE = 'all'; 55 const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]; 56 57 const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code); 58 const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10)); 59 const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5)); 60 61 const normalizeFilter = filter => { 62 if (filter === undefined) return; 63 if (typeof filter === 'function') return filter; 64 65 if (typeof filter === 'string') { 66 const glob = picomatch$1(filter.trim()); 67 return entry => glob(entry.basename); 68 } 69 70 if (Array.isArray(filter)) { 71 const positive = []; 72 const negative = []; 73 for (const item of filter) { 74 const trimmed = item.trim(); 75 if (trimmed.charAt(0) === BANG$2) { 76 negative.push(picomatch$1(trimmed.slice(1))); 77 } else { 78 positive.push(picomatch$1(trimmed)); 79 } 80 } 81 82 if (negative.length > 0) { 83 if (positive.length > 0) { 84 return entry => 85 positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename)); 86 } 87 return entry => !negative.some(f => f(entry.basename)); 88 } 89 return entry => positive.some(f => f(entry.basename)); 90 } 91 }; 92 93 class ReaddirpStream extends Readable { 94 static get defaultOptions() { 95 return { 96 root: '.', 97 /* eslint-disable no-unused-vars */ 98 fileFilter: (path) => true, 99 directoryFilter: (path) => true, 100 /* eslint-enable no-unused-vars */ 101 type: FILE_TYPE, 102 lstat: false, 103 depth: 2147483648, 104 alwaysStat: false 105 }; 106 } 107 108 constructor(options = {}) { 109 super({ 110 objectMode: true, 111 autoDestroy: true, 112 highWaterMark: options.highWaterMark || 4096 113 }); 114 const opts = { ...ReaddirpStream.defaultOptions, ...options }; 115 const { root, type } = opts; 116 117 this._fileFilter = normalizeFilter(opts.fileFilter); 118 this._directoryFilter = normalizeFilter(opts.directoryFilter); 119 120 const statMethod = opts.lstat ? lstat$2 : stat$3; 121 // Use bigint stats if it's windows and stat() supports options (node 10+). 122 if (wantBigintFsStats) { 123 this._stat = path => statMethod(path, { bigint: true }); 124 } else { 125 this._stat = statMethod; 126 } 127 128 this._maxDepth = opts.depth; 129 this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); 130 this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); 131 this._wantsEverything = type === EVERYTHING_TYPE; 132 this._root = sysPath$3.resolve(root); 133 this._isDirent = ('Dirent' in fs$3) && !opts.alwaysStat; 134 this._statsProp = this._isDirent ? 'dirent' : 'stats'; 135 this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent }; 136 137 // Launch stream with one parent, the root dir. 138 this.parents = [this._exploreDir(root, 1)]; 139 this.reading = false; 140 this.parent = undefined; 141 } 142 143 async _read(batch) { 144 if (this.reading) return; 145 this.reading = true; 146 147 try { 148 while (!this.destroyed && batch > 0) { 149 const { path, depth, files = [] } = this.parent || {}; 150 151 if (files.length > 0) { 152 const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path)); 153 for (const entry of await Promise.all(slice)) { 154 if (this.destroyed) return; 155 156 const entryType = await this._getEntryType(entry); 157 if (entryType === 'directory' && this._directoryFilter(entry)) { 158 if (depth <= this._maxDepth) { 159 this.parents.push(this._exploreDir(entry.fullPath, depth + 1)); 160 } 161 162 if (this._wantsDir) { 163 this.push(entry); 164 batch--; 165 } 166 } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) { 167 if (this._wantsFile) { 168 this.push(entry); 169 batch--; 170 } 171 } 172 } 173 } else { 174 const parent = this.parents.pop(); 175 if (!parent) { 176 this.push(null); 177 break; 178 } 179 this.parent = await parent; 180 if (this.destroyed) return; 181 } 182 } 183 } catch (error) { 184 this.destroy(error); 185 } finally { 186 this.reading = false; 187 } 188 } 189 190 async _exploreDir(path, depth) { 191 let files; 192 try { 193 files = await readdir$1(path, this._rdOptions); 194 } catch (error) { 195 this._onError(error); 196 } 197 return { files, depth, path }; 198 } 199 200 async _formatEntry(dirent, path) { 201 let entry; 202 try { 203 const basename = this._isDirent ? dirent.name : dirent; 204 const fullPath = sysPath$3.resolve(sysPath$3.join(path, basename)); 205 entry = { path: sysPath$3.relative(this._root, fullPath), fullPath, basename }; 206 entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath); 207 } catch (err) { 208 this._onError(err); 209 } 210 return entry; 211 } 212 213 _onError(err) { 214 if (isNormalFlowError(err) && !this.destroyed) { 215 this.emit('warn', err); 216 } else { 217 this.destroy(err); 218 } 219 } 220 221 async _getEntryType(entry) { 222 // entry may be undefined, because a warning or an error were emitted 223 // and the statsProp is undefined 224 const stats = entry && entry[this._statsProp]; 225 if (!stats) { 226 return; 227 } 228 if (stats.isFile()) { 229 return 'file'; 230 } 231 if (stats.isDirectory()) { 232 return 'directory'; 233 } 234 if (stats && stats.isSymbolicLink()) { 235 const full = entry.fullPath; 236 try { 237 const entryRealPath = await realpath$1(full); 238 const entryRealPathStats = await lstat$2(entryRealPath); 239 if (entryRealPathStats.isFile()) { 240 return 'file'; 241 } 242 if (entryRealPathStats.isDirectory()) { 243 const len = entryRealPath.length; 244 if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath$3.sep) { 245 const recursiveError = new Error( 246 `Circular symlink detected: "${full}" points to "${entryRealPath}"` 247 ); 248 recursiveError.code = RECURSIVE_ERROR_CODE; 249 return this._onError(recursiveError); 250 } 251 return 'directory'; 252 } 253 } catch (error) { 254 this._onError(error); 255 } 256 } 257 } 258 259 _includeAsFile(entry) { 260 const stats = entry && entry[this._statsProp]; 261 262 return stats && this._wantsEverything && !stats.isDirectory(); 263 } 26 var chokidar$1 = {}; 27 28 var utils$2 = {}; 29 30 var constants$3; 31 var hasRequiredConstants$3; 32 33 function requireConstants$3 () { 34 if (hasRequiredConstants$3) return constants$3; 35 hasRequiredConstants$3 = 1; 36 37 const path = require$$0$1; 38 const WIN_SLASH = '\\\\/'; 39 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 40 41 /** 42 * Posix glob regex 43 */ 44 45 const DOT_LITERAL = '\\.'; 46 const PLUS_LITERAL = '\\+'; 47 const QMARK_LITERAL = '\\?'; 48 const SLASH_LITERAL = '\\/'; 49 const ONE_CHAR = '(?=.)'; 50 const QMARK = '[^/]'; 51 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 52 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 53 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 54 const NO_DOT = `(?!${DOT_LITERAL})`; 55 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 56 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 57 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 58 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 59 const STAR = `${QMARK}*?`; 60 61 const POSIX_CHARS = { 62 DOT_LITERAL, 63 PLUS_LITERAL, 64 QMARK_LITERAL, 65 SLASH_LITERAL, 66 ONE_CHAR, 67 QMARK, 68 END_ANCHOR, 69 DOTS_SLASH, 70 NO_DOT, 71 NO_DOTS, 72 NO_DOT_SLASH, 73 NO_DOTS_SLASH, 74 QMARK_NO_DOT, 75 STAR, 76 START_ANCHOR 77 }; 78 79 /** 80 * Windows glob regex 81 */ 82 83 const WINDOWS_CHARS = { 84 ...POSIX_CHARS, 85 86 SLASH_LITERAL: `[${WIN_SLASH}]`, 87 QMARK: WIN_NO_SLASH, 88 STAR: `${WIN_NO_SLASH}*?`, 89 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, 90 NO_DOT: `(?!${DOT_LITERAL})`, 91 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 92 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, 93 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 94 QMARK_NO_DOT: `[^.${WIN_SLASH}]`, 95 START_ANCHOR: `(?:^|[${WIN_SLASH}])`, 96 END_ANCHOR: `(?:[${WIN_SLASH}]|$)` 97 }; 98 99 /** 100 * POSIX Bracket Regex 101 */ 102 103 const POSIX_REGEX_SOURCE = { 104 alnum: 'a-zA-Z0-9', 105 alpha: 'a-zA-Z', 106 ascii: '\\x00-\\x7F', 107 blank: ' \\t', 108 cntrl: '\\x00-\\x1F\\x7F', 109 digit: '0-9', 110 graph: '\\x21-\\x7E', 111 lower: 'a-z', 112 print: '\\x20-\\x7E ', 113 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', 114 space: ' \\t\\r\\n\\v\\f', 115 upper: 'A-Z', 116 word: 'A-Za-z0-9_', 117 xdigit: 'A-Fa-f0-9' 118 }; 119 120 constants$3 = { 121 MAX_LENGTH: 1024 * 64, 122 POSIX_REGEX_SOURCE, 123 124 // regular expressions 125 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, 126 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, 127 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, 128 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, 129 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, 130 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, 131 132 // Replace globs with equivalent patterns to reduce parsing time. 133 REPLACEMENTS: { 134 '***': '*', 135 '**/**': '**', 136 '**/**/**': '**' 137 }, 138 139 // Digits 140 CHAR_0: 48, /* 0 */ 141 CHAR_9: 57, /* 9 */ 142 143 // Alphabet chars. 144 CHAR_UPPERCASE_A: 65, /* A */ 145 CHAR_LOWERCASE_A: 97, /* a */ 146 CHAR_UPPERCASE_Z: 90, /* Z */ 147 CHAR_LOWERCASE_Z: 122, /* z */ 148 149 CHAR_LEFT_PARENTHESES: 40, /* ( */ 150 CHAR_RIGHT_PARENTHESES: 41, /* ) */ 151 152 CHAR_ASTERISK: 42, /* * */ 153 154 // Non-alphabetic chars. 155 CHAR_AMPERSAND: 38, /* & */ 156 CHAR_AT: 64, /* @ */ 157 CHAR_BACKWARD_SLASH: 92, /* \ */ 158 CHAR_CARRIAGE_RETURN: 13, /* \r */ 159 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ 160 CHAR_COLON: 58, /* : */ 161 CHAR_COMMA: 44, /* , */ 162 CHAR_DOT: 46, /* . */ 163 CHAR_DOUBLE_QUOTE: 34, /* " */ 164 CHAR_EQUAL: 61, /* = */ 165 CHAR_EXCLAMATION_MARK: 33, /* ! */ 166 CHAR_FORM_FEED: 12, /* \f */ 167 CHAR_FORWARD_SLASH: 47, /* / */ 168 CHAR_GRAVE_ACCENT: 96, /* ` */ 169 CHAR_HASH: 35, /* # */ 170 CHAR_HYPHEN_MINUS: 45, /* - */ 171 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ 172 CHAR_LEFT_CURLY_BRACE: 123, /* { */ 173 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ 174 CHAR_LINE_FEED: 10, /* \n */ 175 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ 176 CHAR_PERCENT: 37, /* % */ 177 CHAR_PLUS: 43, /* + */ 178 CHAR_QUESTION_MARK: 63, /* ? */ 179 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ 180 CHAR_RIGHT_CURLY_BRACE: 125, /* } */ 181 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ 182 CHAR_SEMICOLON: 59, /* ; */ 183 CHAR_SINGLE_QUOTE: 39, /* ' */ 184 CHAR_SPACE: 32, /* */ 185 CHAR_TAB: 9, /* \t */ 186 CHAR_UNDERSCORE: 95, /* _ */ 187 CHAR_VERTICAL_LINE: 124, /* | */ 188 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ 189 190 SEP: path.sep, 191 192 /** 193 * Create EXTGLOB_CHARS 194 */ 195 196 extglobChars(chars) { 197 return { 198 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, 199 '?': { type: 'qmark', open: '(?:', close: ')?' }, 200 '+': { type: 'plus', open: '(?:', close: ')+' }, 201 '*': { type: 'star', open: '(?:', close: ')*' }, 202 '@': { type: 'at', open: '(?:', close: ')' } 203 }; 204 }, 205 206 /** 207 * Create GLOB_CHARS 208 */ 209 210 globChars(win32) { 211 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; 212 } 213 }; 214 return constants$3; 264 215 } 265 216 266 /** 267 * @typedef {Object} ReaddirpArguments 268 * @property {Function=} fileFilter 269 * @property {Function=} directoryFilter 270 * @property {String=} type 271 * @property {Number=} depth 272 * @property {String=} root 273 * @property {Boolean=} lstat 274 * @property {Boolean=} bigint 275 */ 276 277 /** 278 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively. 279 * @param {String} root Root directory 280 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth 281 */ 282 const readdirp$1 = (root, options = {}) => { 283 let type = options.entryType || options.type; 284 if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility 285 if (type) options.type = type; 286 if (!root) { 287 throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)'); 288 } else if (typeof root !== 'string') { 289 throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)'); 290 } else if (type && !ALL_TYPES.includes(type)) { 291 throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`); 292 } 293 294 options.root = root; 295 return new ReaddirpStream(options); 296 }; 297 298 const readdirpPromise = (root, options = {}) => { 299 return new Promise((resolve, reject) => { 300 const files = []; 301 readdirp$1(root, options) 302 .on('data', entry => files.push(entry)) 303 .on('end', () => resolve(files)) 304 .on('error', error => reject(error)); 305 }); 306 }; 307 308 readdirp$1.promise = readdirpPromise; 309 readdirp$1.ReaddirpStream = ReaddirpStream; 310 readdirp$1.default = readdirp$1; 311 312 var readdirp_1 = readdirp$1; 313 314 var anymatch$2 = {exports: {}}; 217 var hasRequiredUtils$2; 218 219 function requireUtils$2 () { 220 if (hasRequiredUtils$2) return utils$2; 221 hasRequiredUtils$2 = 1; 222 (function (exports) { 223 224 const path = require$$0$1; 225 const win32 = process.platform === 'win32'; 226 const { 227 REGEX_BACKSLASH, 228 REGEX_REMOVE_BACKSLASH, 229 REGEX_SPECIAL_CHARS, 230 REGEX_SPECIAL_CHARS_GLOBAL 231 } = /*@__PURE__*/ requireConstants$3(); 232 233 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 234 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); 235 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); 236 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); 237 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); 238 239 exports.removeBackslashes = str => { 240 return str.replace(REGEX_REMOVE_BACKSLASH, match => { 241 return match === '\\' ? '' : match; 242 }); 243 }; 244 245 exports.supportsLookbehinds = () => { 246 const segs = process.version.slice(1).split('.').map(Number); 247 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { 248 return true; 249 } 250 return false; 251 }; 252 253 exports.isWindows = options => { 254 if (options && typeof options.windows === 'boolean') { 255 return options.windows; 256 } 257 return win32 === true || path.sep === '\\'; 258 }; 259 260 exports.escapeLast = (input, char, lastIdx) => { 261 const idx = input.lastIndexOf(char, lastIdx); 262 if (idx === -1) return input; 263 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); 264 return `${input.slice(0, idx)}\\${input.slice(idx)}`; 265 }; 266 267 exports.removePrefix = (input, state = {}) => { 268 let output = input; 269 if (output.startsWith('./')) { 270 output = output.slice(2); 271 state.prefix = './'; 272 } 273 return output; 274 }; 275 276 exports.wrapOutput = (input, state = {}, options = {}) => { 277 const prepend = options.contains ? '' : '^'; 278 const append = options.contains ? '' : '$'; 279 280 let output = `${prepend}(?:${input})${append}`; 281 if (state.negated === true) { 282 output = `(?:^(?!${output}).*$)`; 283 } 284 return output; 285 }; 286 } (utils$2)); 287 return utils$2; 288 } 289 290 var scan_1$1; 291 var hasRequiredScan$1; 292 293 function requireScan$1 () { 294 if (hasRequiredScan$1) return scan_1$1; 295 hasRequiredScan$1 = 1; 296 297 const utils = /*@__PURE__*/ requireUtils$2(); 298 const { 299 CHAR_ASTERISK, /* * */ 300 CHAR_AT, /* @ */ 301 CHAR_BACKWARD_SLASH, /* \ */ 302 CHAR_COMMA, /* , */ 303 CHAR_DOT, /* . */ 304 CHAR_EXCLAMATION_MARK, /* ! */ 305 CHAR_FORWARD_SLASH, /* / */ 306 CHAR_LEFT_CURLY_BRACE, /* { */ 307 CHAR_LEFT_PARENTHESES, /* ( */ 308 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 309 CHAR_PLUS, /* + */ 310 CHAR_QUESTION_MARK, /* ? */ 311 CHAR_RIGHT_CURLY_BRACE, /* } */ 312 CHAR_RIGHT_PARENTHESES, /* ) */ 313 CHAR_RIGHT_SQUARE_BRACKET /* ] */ 314 } = /*@__PURE__*/ requireConstants$3(); 315 316 const isPathSeparator = code => { 317 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; 318 }; 319 320 const depth = token => { 321 if (token.isPrefix !== true) { 322 token.depth = token.isGlobstar ? Infinity : 1; 323 } 324 }; 325 326 /** 327 * Quickly scans a glob pattern and returns an object with a handful of 328 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), 329 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not 330 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). 331 * 332 * ```js 333 * const pm = require('picomatch'); 334 * console.log(pm.scan('foo/bar/*.js')); 335 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } 336 * ``` 337 * @param {String} `str` 338 * @param {Object} `options` 339 * @return {Object} Returns an object with tokens and regex source string. 340 * @api public 341 */ 342 343 const scan = (input, options) => { 344 const opts = options || {}; 345 346 const length = input.length - 1; 347 const scanToEnd = opts.parts === true || opts.scanToEnd === true; 348 const slashes = []; 349 const tokens = []; 350 const parts = []; 351 352 let str = input; 353 let index = -1; 354 let start = 0; 355 let lastIndex = 0; 356 let isBrace = false; 357 let isBracket = false; 358 let isGlob = false; 359 let isExtglob = false; 360 let isGlobstar = false; 361 let braceEscaped = false; 362 let backslashes = false; 363 let negated = false; 364 let negatedExtglob = false; 365 let finished = false; 366 let braces = 0; 367 let prev; 368 let code; 369 let token = { value: '', depth: 0, isGlob: false }; 370 371 const eos = () => index >= length; 372 const peek = () => str.charCodeAt(index + 1); 373 const advance = () => { 374 prev = code; 375 return str.charCodeAt(++index); 376 }; 377 378 while (index < length) { 379 code = advance(); 380 let next; 381 382 if (code === CHAR_BACKWARD_SLASH) { 383 backslashes = token.backslashes = true; 384 code = advance(); 385 386 if (code === CHAR_LEFT_CURLY_BRACE) { 387 braceEscaped = true; 388 } 389 continue; 390 } 391 392 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { 393 braces++; 394 395 while (eos() !== true && (code = advance())) { 396 if (code === CHAR_BACKWARD_SLASH) { 397 backslashes = token.backslashes = true; 398 advance(); 399 continue; 400 } 401 402 if (code === CHAR_LEFT_CURLY_BRACE) { 403 braces++; 404 continue; 405 } 406 407 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { 408 isBrace = token.isBrace = true; 409 isGlob = token.isGlob = true; 410 finished = true; 411 412 if (scanToEnd === true) { 413 continue; 414 } 415 416 break; 417 } 418 419 if (braceEscaped !== true && code === CHAR_COMMA) { 420 isBrace = token.isBrace = true; 421 isGlob = token.isGlob = true; 422 finished = true; 423 424 if (scanToEnd === true) { 425 continue; 426 } 427 428 break; 429 } 430 431 if (code === CHAR_RIGHT_CURLY_BRACE) { 432 braces--; 433 434 if (braces === 0) { 435 braceEscaped = false; 436 isBrace = token.isBrace = true; 437 finished = true; 438 break; 439 } 440 } 441 } 442 443 if (scanToEnd === true) { 444 continue; 445 } 446 447 break; 448 } 449 450 if (code === CHAR_FORWARD_SLASH) { 451 slashes.push(index); 452 tokens.push(token); 453 token = { value: '', depth: 0, isGlob: false }; 454 455 if (finished === true) continue; 456 if (prev === CHAR_DOT && index === (start + 1)) { 457 start += 2; 458 continue; 459 } 460 461 lastIndex = index + 1; 462 continue; 463 } 464 465 if (opts.noext !== true) { 466 const isExtglobChar = code === CHAR_PLUS 467 || code === CHAR_AT 468 || code === CHAR_ASTERISK 469 || code === CHAR_QUESTION_MARK 470 || code === CHAR_EXCLAMATION_MARK; 471 472 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { 473 isGlob = token.isGlob = true; 474 isExtglob = token.isExtglob = true; 475 finished = true; 476 if (code === CHAR_EXCLAMATION_MARK && index === start) { 477 negatedExtglob = true; 478 } 479 480 if (scanToEnd === true) { 481 while (eos() !== true && (code = advance())) { 482 if (code === CHAR_BACKWARD_SLASH) { 483 backslashes = token.backslashes = true; 484 code = advance(); 485 continue; 486 } 487 488 if (code === CHAR_RIGHT_PARENTHESES) { 489 isGlob = token.isGlob = true; 490 finished = true; 491 break; 492 } 493 } 494 continue; 495 } 496 break; 497 } 498 } 499 500 if (code === CHAR_ASTERISK) { 501 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; 502 isGlob = token.isGlob = true; 503 finished = true; 504 505 if (scanToEnd === true) { 506 continue; 507 } 508 break; 509 } 510 511 if (code === CHAR_QUESTION_MARK) { 512 isGlob = token.isGlob = true; 513 finished = true; 514 515 if (scanToEnd === true) { 516 continue; 517 } 518 break; 519 } 520 521 if (code === CHAR_LEFT_SQUARE_BRACKET) { 522 while (eos() !== true && (next = advance())) { 523 if (next === CHAR_BACKWARD_SLASH) { 524 backslashes = token.backslashes = true; 525 advance(); 526 continue; 527 } 528 529 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 530 isBracket = token.isBracket = true; 531 isGlob = token.isGlob = true; 532 finished = true; 533 break; 534 } 535 } 536 537 if (scanToEnd === true) { 538 continue; 539 } 540 541 break; 542 } 543 544 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { 545 negated = token.negated = true; 546 start++; 547 continue; 548 } 549 550 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { 551 isGlob = token.isGlob = true; 552 553 if (scanToEnd === true) { 554 while (eos() !== true && (code = advance())) { 555 if (code === CHAR_LEFT_PARENTHESES) { 556 backslashes = token.backslashes = true; 557 code = advance(); 558 continue; 559 } 560 561 if (code === CHAR_RIGHT_PARENTHESES) { 562 finished = true; 563 break; 564 } 565 } 566 continue; 567 } 568 break; 569 } 570 571 if (isGlob === true) { 572 finished = true; 573 574 if (scanToEnd === true) { 575 continue; 576 } 577 578 break; 579 } 580 } 581 582 if (opts.noext === true) { 583 isExtglob = false; 584 isGlob = false; 585 } 586 587 let base = str; 588 let prefix = ''; 589 let glob = ''; 590 591 if (start > 0) { 592 prefix = str.slice(0, start); 593 str = str.slice(start); 594 lastIndex -= start; 595 } 596 597 if (base && isGlob === true && lastIndex > 0) { 598 base = str.slice(0, lastIndex); 599 glob = str.slice(lastIndex); 600 } else if (isGlob === true) { 601 base = ''; 602 glob = str; 603 } else { 604 base = str; 605 } 606 607 if (base && base !== '' && base !== '/' && base !== str) { 608 if (isPathSeparator(base.charCodeAt(base.length - 1))) { 609 base = base.slice(0, -1); 610 } 611 } 612 613 if (opts.unescape === true) { 614 if (glob) glob = utils.removeBackslashes(glob); 615 616 if (base && backslashes === true) { 617 base = utils.removeBackslashes(base); 618 } 619 } 620 621 const state = { 622 prefix, 623 input, 624 start, 625 base, 626 glob, 627 isBrace, 628 isBracket, 629 isGlob, 630 isExtglob, 631 isGlobstar, 632 negated, 633 negatedExtglob 634 }; 635 636 if (opts.tokens === true) { 637 state.maxDepth = 0; 638 if (!isPathSeparator(code)) { 639 tokens.push(token); 640 } 641 state.tokens = tokens; 642 } 643 644 if (opts.parts === true || opts.tokens === true) { 645 let prevIndex; 646 647 for (let idx = 0; idx < slashes.length; idx++) { 648 const n = prevIndex ? prevIndex + 1 : start; 649 const i = slashes[idx]; 650 const value = input.slice(n, i); 651 if (opts.tokens) { 652 if (idx === 0 && start !== 0) { 653 tokens[idx].isPrefix = true; 654 tokens[idx].value = prefix; 655 } else { 656 tokens[idx].value = value; 657 } 658 depth(tokens[idx]); 659 state.maxDepth += tokens[idx].depth; 660 } 661 if (idx !== 0 || value !== '') { 662 parts.push(value); 663 } 664 prevIndex = i; 665 } 666 667 if (prevIndex && prevIndex + 1 < input.length) { 668 const value = input.slice(prevIndex + 1); 669 parts.push(value); 670 671 if (opts.tokens) { 672 tokens[tokens.length - 1].value = value; 673 depth(tokens[tokens.length - 1]); 674 state.maxDepth += tokens[tokens.length - 1].depth; 675 } 676 } 677 678 state.slashes = slashes; 679 state.parts = parts; 680 } 681 682 return state; 683 }; 684 685 scan_1$1 = scan; 686 return scan_1$1; 687 } 688 689 var parse_1$2; 690 var hasRequiredParse$2; 691 692 function requireParse$2 () { 693 if (hasRequiredParse$2) return parse_1$2; 694 hasRequiredParse$2 = 1; 695 696 const constants = /*@__PURE__*/ requireConstants$3(); 697 const utils = /*@__PURE__*/ requireUtils$2(); 698 699 /** 700 * Constants 701 */ 702 703 const { 704 MAX_LENGTH, 705 POSIX_REGEX_SOURCE, 706 REGEX_NON_SPECIAL_CHARS, 707 REGEX_SPECIAL_CHARS_BACKREF, 708 REPLACEMENTS 709 } = constants; 710 711 /** 712 * Helpers 713 */ 714 715 const expandRange = (args, options) => { 716 if (typeof options.expandRange === 'function') { 717 return options.expandRange(...args, options); 718 } 719 720 args.sort(); 721 const value = `[${args.join('-')}]`; 722 723 return value; 724 }; 725 726 /** 727 * Create the message for a syntax error 728 */ 729 730 const syntaxError = (type, char) => { 731 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; 732 }; 733 734 /** 735 * Parse the given input string. 736 * @param {String} input 737 * @param {Object} options 738 * @return {Object} 739 */ 740 741 const parse = (input, options) => { 742 if (typeof input !== 'string') { 743 throw new TypeError('Expected a string'); 744 } 745 746 input = REPLACEMENTS[input] || input; 747 748 const opts = { ...options }; 749 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 750 751 let len = input.length; 752 if (len > max) { 753 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 754 } 755 756 const bos = { type: 'bos', value: '', output: opts.prepend || '' }; 757 const tokens = [bos]; 758 759 const capture = opts.capture ? '' : '?:'; 760 const win32 = utils.isWindows(options); 761 762 // create constants based on platform, for windows or posix 763 const PLATFORM_CHARS = constants.globChars(win32); 764 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); 765 766 const { 767 DOT_LITERAL, 768 PLUS_LITERAL, 769 SLASH_LITERAL, 770 ONE_CHAR, 771 DOTS_SLASH, 772 NO_DOT, 773 NO_DOT_SLASH, 774 NO_DOTS_SLASH, 775 QMARK, 776 QMARK_NO_DOT, 777 STAR, 778 START_ANCHOR 779 } = PLATFORM_CHARS; 780 781 const globstar = opts => { 782 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 783 }; 784 785 const nodot = opts.dot ? '' : NO_DOT; 786 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; 787 let star = opts.bash === true ? globstar(opts) : STAR; 788 789 if (opts.capture) { 790 star = `(${star})`; 791 } 792 793 // minimatch options support 794 if (typeof opts.noext === 'boolean') { 795 opts.noextglob = opts.noext; 796 } 797 798 const state = { 799 input, 800 index: -1, 801 start: 0, 802 dot: opts.dot === true, 803 consumed: '', 804 output: '', 805 prefix: '', 806 backtrack: false, 807 negated: false, 808 brackets: 0, 809 braces: 0, 810 parens: 0, 811 quotes: 0, 812 globstar: false, 813 tokens 814 }; 815 816 input = utils.removePrefix(input, state); 817 len = input.length; 818 819 const extglobs = []; 820 const braces = []; 821 const stack = []; 822 let prev = bos; 823 let value; 824 825 /** 826 * Tokenizing helpers 827 */ 828 829 const eos = () => state.index === len - 1; 830 const peek = state.peek = (n = 1) => input[state.index + n]; 831 const advance = state.advance = () => input[++state.index] || ''; 832 const remaining = () => input.slice(state.index + 1); 833 const consume = (value = '', num = 0) => { 834 state.consumed += value; 835 state.index += num; 836 }; 837 838 const append = token => { 839 state.output += token.output != null ? token.output : token.value; 840 consume(token.value); 841 }; 842 843 const negate = () => { 844 let count = 1; 845 846 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { 847 advance(); 848 state.start++; 849 count++; 850 } 851 852 if (count % 2 === 0) { 853 return false; 854 } 855 856 state.negated = true; 857 state.start++; 858 return true; 859 }; 860 861 const increment = type => { 862 state[type]++; 863 stack.push(type); 864 }; 865 866 const decrement = type => { 867 state[type]--; 868 stack.pop(); 869 }; 870 871 /** 872 * Push tokens onto the tokens array. This helper speeds up 873 * tokenizing by 1) helping us avoid backtracking as much as possible, 874 * and 2) helping us avoid creating extra tokens when consecutive 875 * characters are plain text. This improves performance and simplifies 876 * lookbehinds. 877 */ 878 879 const push = tok => { 880 if (prev.type === 'globstar') { 881 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); 882 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); 883 884 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { 885 state.output = state.output.slice(0, -prev.output.length); 886 prev.type = 'star'; 887 prev.value = '*'; 888 prev.output = star; 889 state.output += prev.output; 890 } 891 } 892 893 if (extglobs.length && tok.type !== 'paren') { 894 extglobs[extglobs.length - 1].inner += tok.value; 895 } 896 897 if (tok.value || tok.output) append(tok); 898 if (prev && prev.type === 'text' && tok.type === 'text') { 899 prev.value += tok.value; 900 prev.output = (prev.output || '') + tok.value; 901 return; 902 } 903 904 tok.prev = prev; 905 tokens.push(tok); 906 prev = tok; 907 }; 908 909 const extglobOpen = (type, value) => { 910 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; 911 912 token.prev = prev; 913 token.parens = state.parens; 914 token.output = state.output; 915 const output = (opts.capture ? '(' : '') + token.open; 916 917 increment('parens'); 918 push({ type, value, output: state.output ? '' : ONE_CHAR }); 919 push({ type: 'paren', extglob: true, value: advance(), output }); 920 extglobs.push(token); 921 }; 922 923 const extglobClose = token => { 924 let output = token.close + (opts.capture ? ')' : ''); 925 let rest; 926 927 if (token.type === 'negate') { 928 let extglobStar = star; 929 930 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { 931 extglobStar = globstar(opts); 932 } 933 934 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { 935 output = token.close = `)$))${extglobStar}`; 936 } 937 938 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { 939 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. 940 // In this case, we need to parse the string and use it in the output of the original pattern. 941 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. 942 // 943 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. 944 const expression = parse(rest, { ...options, fastpaths: false }).output; 945 946 output = token.close = `)${expression})${extglobStar})`; 947 } 948 949 if (token.prev.type === 'bos') { 950 state.negatedExtglob = true; 951 } 952 } 953 954 push({ type: 'paren', extglob: true, value, output }); 955 decrement('parens'); 956 }; 957 958 /** 959 * Fast paths 960 */ 961 962 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { 963 let backslashes = false; 964 965 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { 966 if (first === '\\') { 967 backslashes = true; 968 return m; 969 } 970 971 if (first === '?') { 972 if (esc) { 973 return esc + first + (rest ? QMARK.repeat(rest.length) : ''); 974 } 975 if (index === 0) { 976 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); 977 } 978 return QMARK.repeat(chars.length); 979 } 980 981 if (first === '.') { 982 return DOT_LITERAL.repeat(chars.length); 983 } 984 985 if (first === '*') { 986 if (esc) { 987 return esc + first + (rest ? star : ''); 988 } 989 return star; 990 } 991 return esc ? m : `\\${m}`; 992 }); 993 994 if (backslashes === true) { 995 if (opts.unescape === true) { 996 output = output.replace(/\\/g, ''); 997 } else { 998 output = output.replace(/\\+/g, m => { 999 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); 1000 }); 1001 } 1002 } 1003 1004 if (output === input && opts.contains === true) { 1005 state.output = input; 1006 return state; 1007 } 1008 1009 state.output = utils.wrapOutput(output, state, options); 1010 return state; 1011 } 1012 1013 /** 1014 * Tokenize input until we reach end-of-string 1015 */ 1016 1017 while (!eos()) { 1018 value = advance(); 1019 1020 if (value === '\u0000') { 1021 continue; 1022 } 1023 1024 /** 1025 * Escaped characters 1026 */ 1027 1028 if (value === '\\') { 1029 const next = peek(); 1030 1031 if (next === '/' && opts.bash !== true) { 1032 continue; 1033 } 1034 1035 if (next === '.' || next === ';') { 1036 continue; 1037 } 1038 1039 if (!next) { 1040 value += '\\'; 1041 push({ type: 'text', value }); 1042 continue; 1043 } 1044 1045 // collapse slashes to reduce potential for exploits 1046 const match = /^\\+/.exec(remaining()); 1047 let slashes = 0; 1048 1049 if (match && match[0].length > 2) { 1050 slashes = match[0].length; 1051 state.index += slashes; 1052 if (slashes % 2 !== 0) { 1053 value += '\\'; 1054 } 1055 } 1056 1057 if (opts.unescape === true) { 1058 value = advance(); 1059 } else { 1060 value += advance(); 1061 } 1062 1063 if (state.brackets === 0) { 1064 push({ type: 'text', value }); 1065 continue; 1066 } 1067 } 1068 1069 /** 1070 * If we're inside a regex character class, continue 1071 * until we reach the closing bracket. 1072 */ 1073 1074 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { 1075 if (opts.posix !== false && value === ':') { 1076 const inner = prev.value.slice(1); 1077 if (inner.includes('[')) { 1078 prev.posix = true; 1079 1080 if (inner.includes(':')) { 1081 const idx = prev.value.lastIndexOf('['); 1082 const pre = prev.value.slice(0, idx); 1083 const rest = prev.value.slice(idx + 2); 1084 const posix = POSIX_REGEX_SOURCE[rest]; 1085 if (posix) { 1086 prev.value = pre + posix; 1087 state.backtrack = true; 1088 advance(); 1089 1090 if (!bos.output && tokens.indexOf(prev) === 1) { 1091 bos.output = ONE_CHAR; 1092 } 1093 continue; 1094 } 1095 } 1096 } 1097 } 1098 1099 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { 1100 value = `\\${value}`; 1101 } 1102 1103 if (value === ']' && (prev.value === '[' || prev.value === '[^')) { 1104 value = `\\${value}`; 1105 } 1106 1107 if (opts.posix === true && value === '!' && prev.value === '[') { 1108 value = '^'; 1109 } 1110 1111 prev.value += value; 1112 append({ value }); 1113 continue; 1114 } 1115 1116 /** 1117 * If we're inside a quoted string, continue 1118 * until we reach the closing double quote. 1119 */ 1120 1121 if (state.quotes === 1 && value !== '"') { 1122 value = utils.escapeRegex(value); 1123 prev.value += value; 1124 append({ value }); 1125 continue; 1126 } 1127 1128 /** 1129 * Double quotes 1130 */ 1131 1132 if (value === '"') { 1133 state.quotes = state.quotes === 1 ? 0 : 1; 1134 if (opts.keepQuotes === true) { 1135 push({ type: 'text', value }); 1136 } 1137 continue; 1138 } 1139 1140 /** 1141 * Parentheses 1142 */ 1143 1144 if (value === '(') { 1145 increment('parens'); 1146 push({ type: 'paren', value }); 1147 continue; 1148 } 1149 1150 if (value === ')') { 1151 if (state.parens === 0 && opts.strictBrackets === true) { 1152 throw new SyntaxError(syntaxError('opening', '(')); 1153 } 1154 1155 const extglob = extglobs[extglobs.length - 1]; 1156 if (extglob && state.parens === extglob.parens + 1) { 1157 extglobClose(extglobs.pop()); 1158 continue; 1159 } 1160 1161 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); 1162 decrement('parens'); 1163 continue; 1164 } 1165 1166 /** 1167 * Square brackets 1168 */ 1169 1170 if (value === '[') { 1171 if (opts.nobracket === true || !remaining().includes(']')) { 1172 if (opts.nobracket !== true && opts.strictBrackets === true) { 1173 throw new SyntaxError(syntaxError('closing', ']')); 1174 } 1175 1176 value = `\\${value}`; 1177 } else { 1178 increment('brackets'); 1179 } 1180 1181 push({ type: 'bracket', value }); 1182 continue; 1183 } 1184 1185 if (value === ']') { 1186 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { 1187 push({ type: 'text', value, output: `\\${value}` }); 1188 continue; 1189 } 1190 1191 if (state.brackets === 0) { 1192 if (opts.strictBrackets === true) { 1193 throw new SyntaxError(syntaxError('opening', '[')); 1194 } 1195 1196 push({ type: 'text', value, output: `\\${value}` }); 1197 continue; 1198 } 1199 1200 decrement('brackets'); 1201 1202 const prevValue = prev.value.slice(1); 1203 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { 1204 value = `/${value}`; 1205 } 1206 1207 prev.value += value; 1208 append({ value }); 1209 1210 // when literal brackets are explicitly disabled 1211 // assume we should match with a regex character class 1212 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { 1213 continue; 1214 } 1215 1216 const escaped = utils.escapeRegex(prev.value); 1217 state.output = state.output.slice(0, -prev.value.length); 1218 1219 // when literal brackets are explicitly enabled 1220 // assume we should escape the brackets to match literal characters 1221 if (opts.literalBrackets === true) { 1222 state.output += escaped; 1223 prev.value = escaped; 1224 continue; 1225 } 1226 1227 // when the user specifies nothing, try to match both 1228 prev.value = `(${capture}${escaped}|${prev.value})`; 1229 state.output += prev.value; 1230 continue; 1231 } 1232 1233 /** 1234 * Braces 1235 */ 1236 1237 if (value === '{' && opts.nobrace !== true) { 1238 increment('braces'); 1239 1240 const open = { 1241 type: 'brace', 1242 value, 1243 output: '(', 1244 outputIndex: state.output.length, 1245 tokensIndex: state.tokens.length 1246 }; 1247 1248 braces.push(open); 1249 push(open); 1250 continue; 1251 } 1252 1253 if (value === '}') { 1254 const brace = braces[braces.length - 1]; 1255 1256 if (opts.nobrace === true || !brace) { 1257 push({ type: 'text', value, output: value }); 1258 continue; 1259 } 1260 1261 let output = ')'; 1262 1263 if (brace.dots === true) { 1264 const arr = tokens.slice(); 1265 const range = []; 1266 1267 for (let i = arr.length - 1; i >= 0; i--) { 1268 tokens.pop(); 1269 if (arr[i].type === 'brace') { 1270 break; 1271 } 1272 if (arr[i].type !== 'dots') { 1273 range.unshift(arr[i].value); 1274 } 1275 } 1276 1277 output = expandRange(range, opts); 1278 state.backtrack = true; 1279 } 1280 1281 if (brace.comma !== true && brace.dots !== true) { 1282 const out = state.output.slice(0, brace.outputIndex); 1283 const toks = state.tokens.slice(brace.tokensIndex); 1284 brace.value = brace.output = '\\{'; 1285 value = output = '\\}'; 1286 state.output = out; 1287 for (const t of toks) { 1288 state.output += (t.output || t.value); 1289 } 1290 } 1291 1292 push({ type: 'brace', value, output }); 1293 decrement('braces'); 1294 braces.pop(); 1295 continue; 1296 } 1297 1298 /** 1299 * Pipes 1300 */ 1301 1302 if (value === '|') { 1303 if (extglobs.length > 0) { 1304 extglobs[extglobs.length - 1].conditions++; 1305 } 1306 push({ type: 'text', value }); 1307 continue; 1308 } 1309 1310 /** 1311 * Commas 1312 */ 1313 1314 if (value === ',') { 1315 let output = value; 1316 1317 const brace = braces[braces.length - 1]; 1318 if (brace && stack[stack.length - 1] === 'braces') { 1319 brace.comma = true; 1320 output = '|'; 1321 } 1322 1323 push({ type: 'comma', value, output }); 1324 continue; 1325 } 1326 1327 /** 1328 * Slashes 1329 */ 1330 1331 if (value === '/') { 1332 // if the beginning of the glob is "./", advance the start 1333 // to the current index, and don't add the "./" characters 1334 // to the state. This greatly simplifies lookbehinds when 1335 // checking for BOS characters like "!" and "." (not "./") 1336 if (prev.type === 'dot' && state.index === state.start + 1) { 1337 state.start = state.index + 1; 1338 state.consumed = ''; 1339 state.output = ''; 1340 tokens.pop(); 1341 prev = bos; // reset "prev" to the first token 1342 continue; 1343 } 1344 1345 push({ type: 'slash', value, output: SLASH_LITERAL }); 1346 continue; 1347 } 1348 1349 /** 1350 * Dots 1351 */ 1352 1353 if (value === '.') { 1354 if (state.braces > 0 && prev.type === 'dot') { 1355 if (prev.value === '.') prev.output = DOT_LITERAL; 1356 const brace = braces[braces.length - 1]; 1357 prev.type = 'dots'; 1358 prev.output += value; 1359 prev.value += value; 1360 brace.dots = true; 1361 continue; 1362 } 1363 1364 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { 1365 push({ type: 'text', value, output: DOT_LITERAL }); 1366 continue; 1367 } 1368 1369 push({ type: 'dot', value, output: DOT_LITERAL }); 1370 continue; 1371 } 1372 1373 /** 1374 * Question marks 1375 */ 1376 1377 if (value === '?') { 1378 const isGroup = prev && prev.value === '('; 1379 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 1380 extglobOpen('qmark', value); 1381 continue; 1382 } 1383 1384 if (prev && prev.type === 'paren') { 1385 const next = peek(); 1386 let output = value; 1387 1388 if (next === '<' && !utils.supportsLookbehinds()) { 1389 throw new Error('Node.js v10 or higher is required for regex lookbehinds'); 1390 } 1391 1392 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { 1393 output = `\\${value}`; 1394 } 1395 1396 push({ type: 'text', value, output }); 1397 continue; 1398 } 1399 1400 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { 1401 push({ type: 'qmark', value, output: QMARK_NO_DOT }); 1402 continue; 1403 } 1404 1405 push({ type: 'qmark', value, output: QMARK }); 1406 continue; 1407 } 1408 1409 /** 1410 * Exclamation 1411 */ 1412 1413 if (value === '!') { 1414 if (opts.noextglob !== true && peek() === '(') { 1415 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { 1416 extglobOpen('negate', value); 1417 continue; 1418 } 1419 } 1420 1421 if (opts.nonegate !== true && state.index === 0) { 1422 negate(); 1423 continue; 1424 } 1425 } 1426 1427 /** 1428 * Plus 1429 */ 1430 1431 if (value === '+') { 1432 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 1433 extglobOpen('plus', value); 1434 continue; 1435 } 1436 1437 if ((prev && prev.value === '(') || opts.regex === false) { 1438 push({ type: 'plus', value, output: PLUS_LITERAL }); 1439 continue; 1440 } 1441 1442 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { 1443 push({ type: 'plus', value }); 1444 continue; 1445 } 1446 1447 push({ type: 'plus', value: PLUS_LITERAL }); 1448 continue; 1449 } 1450 1451 /** 1452 * Plain text 1453 */ 1454 1455 if (value === '@') { 1456 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 1457 push({ type: 'at', extglob: true, value, output: '' }); 1458 continue; 1459 } 1460 1461 push({ type: 'text', value }); 1462 continue; 1463 } 1464 1465 /** 1466 * Plain text 1467 */ 1468 1469 if (value !== '*') { 1470 if (value === '$' || value === '^') { 1471 value = `\\${value}`; 1472 } 1473 1474 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); 1475 if (match) { 1476 value += match[0]; 1477 state.index += match[0].length; 1478 } 1479 1480 push({ type: 'text', value }); 1481 continue; 1482 } 1483 1484 /** 1485 * Stars 1486 */ 1487 1488 if (prev && (prev.type === 'globstar' || prev.star === true)) { 1489 prev.type = 'star'; 1490 prev.star = true; 1491 prev.value += value; 1492 prev.output = star; 1493 state.backtrack = true; 1494 state.globstar = true; 1495 consume(value); 1496 continue; 1497 } 1498 1499 let rest = remaining(); 1500 if (opts.noextglob !== true && /^\([^?]/.test(rest)) { 1501 extglobOpen('star', value); 1502 continue; 1503 } 1504 1505 if (prev.type === 'star') { 1506 if (opts.noglobstar === true) { 1507 consume(value); 1508 continue; 1509 } 1510 1511 const prior = prev.prev; 1512 const before = prior.prev; 1513 const isStart = prior.type === 'slash' || prior.type === 'bos'; 1514 const afterStar = before && (before.type === 'star' || before.type === 'globstar'); 1515 1516 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { 1517 push({ type: 'star', value, output: '' }); 1518 continue; 1519 } 1520 1521 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); 1522 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); 1523 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { 1524 push({ type: 'star', value, output: '' }); 1525 continue; 1526 } 1527 1528 // strip consecutive `/**/` 1529 while (rest.slice(0, 3) === '/**') { 1530 const after = input[state.index + 4]; 1531 if (after && after !== '/') { 1532 break; 1533 } 1534 rest = rest.slice(3); 1535 consume('/**', 3); 1536 } 1537 1538 if (prior.type === 'bos' && eos()) { 1539 prev.type = 'globstar'; 1540 prev.value += value; 1541 prev.output = globstar(opts); 1542 state.output = prev.output; 1543 state.globstar = true; 1544 consume(value); 1545 continue; 1546 } 1547 1548 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { 1549 state.output = state.output.slice(0, -(prior.output + prev.output).length); 1550 prior.output = `(?:${prior.output}`; 1551 1552 prev.type = 'globstar'; 1553 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); 1554 prev.value += value; 1555 state.globstar = true; 1556 state.output += prior.output + prev.output; 1557 consume(value); 1558 continue; 1559 } 1560 1561 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { 1562 const end = rest[1] !== void 0 ? '|$' : ''; 1563 1564 state.output = state.output.slice(0, -(prior.output + prev.output).length); 1565 prior.output = `(?:${prior.output}`; 1566 1567 prev.type = 'globstar'; 1568 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; 1569 prev.value += value; 1570 1571 state.output += prior.output + prev.output; 1572 state.globstar = true; 1573 1574 consume(value + advance()); 1575 1576 push({ type: 'slash', value: '/', output: '' }); 1577 continue; 1578 } 1579 1580 if (prior.type === 'bos' && rest[0] === '/') { 1581 prev.type = 'globstar'; 1582 prev.value += value; 1583 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; 1584 state.output = prev.output; 1585 state.globstar = true; 1586 consume(value + advance()); 1587 push({ type: 'slash', value: '/', output: '' }); 1588 continue; 1589 } 1590 1591 // remove single star from output 1592 state.output = state.output.slice(0, -prev.output.length); 1593 1594 // reset previous token to globstar 1595 prev.type = 'globstar'; 1596 prev.output = globstar(opts); 1597 prev.value += value; 1598 1599 // reset output with globstar 1600 state.output += prev.output; 1601 state.globstar = true; 1602 consume(value); 1603 continue; 1604 } 1605 1606 const token = { type: 'star', value, output: star }; 1607 1608 if (opts.bash === true) { 1609 token.output = '.*?'; 1610 if (prev.type === 'bos' || prev.type === 'slash') { 1611 token.output = nodot + token.output; 1612 } 1613 push(token); 1614 continue; 1615 } 1616 1617 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { 1618 token.output = value; 1619 push(token); 1620 continue; 1621 } 1622 1623 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { 1624 if (prev.type === 'dot') { 1625 state.output += NO_DOT_SLASH; 1626 prev.output += NO_DOT_SLASH; 1627 1628 } else if (opts.dot === true) { 1629 state.output += NO_DOTS_SLASH; 1630 prev.output += NO_DOTS_SLASH; 1631 1632 } else { 1633 state.output += nodot; 1634 prev.output += nodot; 1635 } 1636 1637 if (peek() !== '*') { 1638 state.output += ONE_CHAR; 1639 prev.output += ONE_CHAR; 1640 } 1641 } 1642 1643 push(token); 1644 } 1645 1646 while (state.brackets > 0) { 1647 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); 1648 state.output = utils.escapeLast(state.output, '['); 1649 decrement('brackets'); 1650 } 1651 1652 while (state.parens > 0) { 1653 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); 1654 state.output = utils.escapeLast(state.output, '('); 1655 decrement('parens'); 1656 } 1657 1658 while (state.braces > 0) { 1659 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); 1660 state.output = utils.escapeLast(state.output, '{'); 1661 decrement('braces'); 1662 } 1663 1664 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { 1665 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); 1666 } 1667 1668 // rebuild the output if we had to backtrack at any point 1669 if (state.backtrack === true) { 1670 state.output = ''; 1671 1672 for (const token of state.tokens) { 1673 state.output += token.output != null ? token.output : token.value; 1674 1675 if (token.suffix) { 1676 state.output += token.suffix; 1677 } 1678 } 1679 } 1680 1681 return state; 1682 }; 1683 1684 /** 1685 * Fast paths for creating regular expressions for common glob patterns. 1686 * This can significantly speed up processing and has very little downside 1687 * impact when none of the fast paths match. 1688 */ 1689 1690 parse.fastpaths = (input, options) => { 1691 const opts = { ...options }; 1692 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 1693 const len = input.length; 1694 if (len > max) { 1695 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 1696 } 1697 1698 input = REPLACEMENTS[input] || input; 1699 const win32 = utils.isWindows(options); 1700 1701 // create constants based on platform, for windows or posix 1702 const { 1703 DOT_LITERAL, 1704 SLASH_LITERAL, 1705 ONE_CHAR, 1706 DOTS_SLASH, 1707 NO_DOT, 1708 NO_DOTS, 1709 NO_DOTS_SLASH, 1710 STAR, 1711 START_ANCHOR 1712 } = constants.globChars(win32); 1713 1714 const nodot = opts.dot ? NO_DOTS : NO_DOT; 1715 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; 1716 const capture = opts.capture ? '' : '?:'; 1717 const state = { negated: false, prefix: '' }; 1718 let star = opts.bash === true ? '.*?' : STAR; 1719 1720 if (opts.capture) { 1721 star = `(${star})`; 1722 } 1723 1724 const globstar = opts => { 1725 if (opts.noglobstar === true) return star; 1726 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 1727 }; 1728 1729 const create = str => { 1730 switch (str) { 1731 case '*': 1732 return `${nodot}${ONE_CHAR}${star}`; 1733 1734 case '.*': 1735 return `${DOT_LITERAL}${ONE_CHAR}${star}`; 1736 1737 case '*.*': 1738 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 1739 1740 case '*/*': 1741 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; 1742 1743 case '**': 1744 return nodot + globstar(opts); 1745 1746 case '**/*': 1747 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; 1748 1749 case '**/*.*': 1750 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 1751 1752 case '**/.*': 1753 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; 1754 1755 default: { 1756 const match = /^(.*?)\.(\w+)$/.exec(str); 1757 if (!match) return; 1758 1759 const source = create(match[1]); 1760 if (!source) return; 1761 1762 return source + DOT_LITERAL + match[2]; 1763 } 1764 } 1765 }; 1766 1767 const output = utils.removePrefix(input, state); 1768 let source = create(output); 1769 1770 if (source && opts.strictSlashes !== true) { 1771 source += `${SLASH_LITERAL}?`; 1772 } 1773 1774 return source; 1775 }; 1776 1777 parse_1$2 = parse; 1778 return parse_1$2; 1779 } 1780 1781 var picomatch_1$1; 1782 var hasRequiredPicomatch$3; 1783 1784 function requirePicomatch$3 () { 1785 if (hasRequiredPicomatch$3) return picomatch_1$1; 1786 hasRequiredPicomatch$3 = 1; 1787 1788 const path = require$$0$1; 1789 const scan = /*@__PURE__*/ requireScan$1(); 1790 const parse = /*@__PURE__*/ requireParse$2(); 1791 const utils = /*@__PURE__*/ requireUtils$2(); 1792 const constants = /*@__PURE__*/ requireConstants$3(); 1793 const isObject = val => val && typeof val === 'object' && !Array.isArray(val); 1794 1795 /** 1796 * Creates a matcher function from one or more glob patterns. The 1797 * returned function takes a string to match as its first argument, 1798 * and returns true if the string is a match. The returned matcher 1799 * function also takes a boolean as the second argument that, when true, 1800 * returns an object with additional information. 1801 * 1802 * ```js 1803 * const picomatch = require('picomatch'); 1804 * // picomatch(glob[, options]); 1805 * 1806 * const isMatch = picomatch('*.!(*a)'); 1807 * console.log(isMatch('a.a')); //=> false 1808 * console.log(isMatch('a.b')); //=> true 1809 * ``` 1810 * @name picomatch 1811 * @param {String|Array} `globs` One or more glob patterns. 1812 * @param {Object=} `options` 1813 * @return {Function=} Returns a matcher function. 1814 * @api public 1815 */ 1816 1817 const picomatch = (glob, options, returnState = false) => { 1818 if (Array.isArray(glob)) { 1819 const fns = glob.map(input => picomatch(input, options, returnState)); 1820 const arrayMatcher = str => { 1821 for (const isMatch of fns) { 1822 const state = isMatch(str); 1823 if (state) return state; 1824 } 1825 return false; 1826 }; 1827 return arrayMatcher; 1828 } 1829 1830 const isState = isObject(glob) && glob.tokens && glob.input; 1831 1832 if (glob === '' || (typeof glob !== 'string' && !isState)) { 1833 throw new TypeError('Expected pattern to be a non-empty string'); 1834 } 1835 1836 const opts = options || {}; 1837 const posix = utils.isWindows(options); 1838 const regex = isState 1839 ? picomatch.compileRe(glob, options) 1840 : picomatch.makeRe(glob, options, false, true); 1841 1842 const state = regex.state; 1843 delete regex.state; 1844 1845 let isIgnored = () => false; 1846 if (opts.ignore) { 1847 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; 1848 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); 1849 } 1850 1851 const matcher = (input, returnObject = false) => { 1852 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); 1853 const result = { glob, state, regex, posix, input, output, match, isMatch }; 1854 1855 if (typeof opts.onResult === 'function') { 1856 opts.onResult(result); 1857 } 1858 1859 if (isMatch === false) { 1860 result.isMatch = false; 1861 return returnObject ? result : false; 1862 } 1863 1864 if (isIgnored(input)) { 1865 if (typeof opts.onIgnore === 'function') { 1866 opts.onIgnore(result); 1867 } 1868 result.isMatch = false; 1869 return returnObject ? result : false; 1870 } 1871 1872 if (typeof opts.onMatch === 'function') { 1873 opts.onMatch(result); 1874 } 1875 return returnObject ? result : true; 1876 }; 1877 1878 if (returnState) { 1879 matcher.state = state; 1880 } 1881 1882 return matcher; 1883 }; 1884 1885 /** 1886 * Test `input` with the given `regex`. This is used by the main 1887 * `picomatch()` function to test the input string. 1888 * 1889 * ```js 1890 * const picomatch = require('picomatch'); 1891 * // picomatch.test(input, regex[, options]); 1892 * 1893 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); 1894 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } 1895 * ``` 1896 * @param {String} `input` String to test. 1897 * @param {RegExp} `regex` 1898 * @return {Object} Returns an object with matching info. 1899 * @api public 1900 */ 1901 1902 picomatch.test = (input, regex, options, { glob, posix } = {}) => { 1903 if (typeof input !== 'string') { 1904 throw new TypeError('Expected input to be a string'); 1905 } 1906 1907 if (input === '') { 1908 return { isMatch: false, output: '' }; 1909 } 1910 1911 const opts = options || {}; 1912 const format = opts.format || (posix ? utils.toPosixSlashes : null); 1913 let match = input === glob; 1914 let output = (match && format) ? format(input) : input; 1915 1916 if (match === false) { 1917 output = format ? format(input) : input; 1918 match = output === glob; 1919 } 1920 1921 if (match === false || opts.capture === true) { 1922 if (opts.matchBase === true || opts.basename === true) { 1923 match = picomatch.matchBase(input, regex, options, posix); 1924 } else { 1925 match = regex.exec(output); 1926 } 1927 } 1928 1929 return { isMatch: Boolean(match), match, output }; 1930 }; 1931 1932 /** 1933 * Match the basename of a filepath. 1934 * 1935 * ```js 1936 * const picomatch = require('picomatch'); 1937 * // picomatch.matchBase(input, glob[, options]); 1938 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true 1939 * ``` 1940 * @param {String} `input` String to test. 1941 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). 1942 * @return {Boolean} 1943 * @api public 1944 */ 1945 1946 picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { 1947 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); 1948 return regex.test(path.basename(input)); 1949 }; 1950 1951 /** 1952 * Returns true if **any** of the given glob `patterns` match the specified `string`. 1953 * 1954 * ```js 1955 * const picomatch = require('picomatch'); 1956 * // picomatch.isMatch(string, patterns[, options]); 1957 * 1958 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true 1959 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false 1960 * ``` 1961 * @param {String|Array} str The string to test. 1962 * @param {String|Array} patterns One or more glob patterns to use for matching. 1963 * @param {Object} [options] See available [options](#options). 1964 * @return {Boolean} Returns true if any patterns match `str` 1965 * @api public 1966 */ 1967 1968 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); 1969 1970 /** 1971 * Parse a glob pattern to create the source string for a regular 1972 * expression. 1973 * 1974 * ```js 1975 * const picomatch = require('picomatch'); 1976 * const result = picomatch.parse(pattern[, options]); 1977 * ``` 1978 * @param {String} `pattern` 1979 * @param {Object} `options` 1980 * @return {Object} Returns an object with useful properties and output to be used as a regex source string. 1981 * @api public 1982 */ 1983 1984 picomatch.parse = (pattern, options) => { 1985 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); 1986 return parse(pattern, { ...options, fastpaths: false }); 1987 }; 1988 1989 /** 1990 * Scan a glob pattern to separate the pattern into segments. 1991 * 1992 * ```js 1993 * const picomatch = require('picomatch'); 1994 * // picomatch.scan(input[, options]); 1995 * 1996 * const result = picomatch.scan('!./foo/*.js'); 1997 * console.log(result); 1998 * { prefix: '!./', 1999 * input: '!./foo/*.js', 2000 * start: 3, 2001 * base: 'foo', 2002 * glob: '*.js', 2003 * isBrace: false, 2004 * isBracket: false, 2005 * isGlob: true, 2006 * isExtglob: false, 2007 * isGlobstar: false, 2008 * negated: true } 2009 * ``` 2010 * @param {String} `input` Glob pattern to scan. 2011 * @param {Object} `options` 2012 * @return {Object} Returns an object with 2013 * @api public 2014 */ 2015 2016 picomatch.scan = (input, options) => scan(input, options); 2017 2018 /** 2019 * Compile a regular expression from the `state` object returned by the 2020 * [parse()](#parse) method. 2021 * 2022 * @param {Object} `state` 2023 * @param {Object} `options` 2024 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. 2025 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. 2026 * @return {RegExp} 2027 * @api public 2028 */ 2029 2030 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { 2031 if (returnOutput === true) { 2032 return state.output; 2033 } 2034 2035 const opts = options || {}; 2036 const prepend = opts.contains ? '' : '^'; 2037 const append = opts.contains ? '' : '$'; 2038 2039 let source = `${prepend}(?:${state.output})${append}`; 2040 if (state && state.negated === true) { 2041 source = `^(?!${source}).*$`; 2042 } 2043 2044 const regex = picomatch.toRegex(source, options); 2045 if (returnState === true) { 2046 regex.state = state; 2047 } 2048 2049 return regex; 2050 }; 2051 2052 /** 2053 * Create a regular expression from a parsed glob pattern. 2054 * 2055 * ```js 2056 * const picomatch = require('picomatch'); 2057 * const state = picomatch.parse('*.js'); 2058 * // picomatch.compileRe(state[, options]); 2059 * 2060 * console.log(picomatch.compileRe(state)); 2061 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 2062 * ``` 2063 * @param {String} `state` The object returned from the `.parse` method. 2064 * @param {Object} `options` 2065 * @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. 2066 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. 2067 * @return {RegExp} Returns a regex created from the given pattern. 2068 * @api public 2069 */ 2070 2071 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { 2072 if (!input || typeof input !== 'string') { 2073 throw new TypeError('Expected a non-empty string'); 2074 } 2075 2076 let parsed = { negated: false, fastpaths: true }; 2077 2078 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { 2079 parsed.output = parse.fastpaths(input, options); 2080 } 2081 2082 if (!parsed.output) { 2083 parsed = parse(input, options); 2084 } 2085 2086 return picomatch.compileRe(parsed, options, returnOutput, returnState); 2087 }; 2088 2089 /** 2090 * Create a regular expression from the given regex source string. 2091 * 2092 * ```js 2093 * const picomatch = require('picomatch'); 2094 * // picomatch.toRegex(source[, options]); 2095 * 2096 * const { output } = picomatch.parse('*.js'); 2097 * console.log(picomatch.toRegex(output)); 2098 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 2099 * ``` 2100 * @param {String} `source` Regular expression source string. 2101 * @param {Object} `options` 2102 * @return {RegExp} 2103 * @api public 2104 */ 2105 2106 picomatch.toRegex = (source, options) => { 2107 try { 2108 const opts = options || {}; 2109 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); 2110 } catch (err) { 2111 if (options && options.debug === true) throw err; 2112 return /$^/; 2113 } 2114 }; 2115 2116 /** 2117 * Picomatch constants. 2118 * @return {Object} 2119 */ 2120 2121 picomatch.constants = constants; 2122 2123 /** 2124 * Expose "picomatch" 2125 */ 2126 2127 picomatch_1$1 = picomatch; 2128 return picomatch_1$1; 2129 } 2130 2131 var picomatch$1; 2132 var hasRequiredPicomatch$2; 2133 2134 function requirePicomatch$2 () { 2135 if (hasRequiredPicomatch$2) return picomatch$1; 2136 hasRequiredPicomatch$2 = 1; 2137 2138 picomatch$1 = /*@__PURE__*/ requirePicomatch$3(); 2139 return picomatch$1; 2140 } 2141 2142 var readdirp_1; 2143 var hasRequiredReaddirp; 2144 2145 function requireReaddirp () { 2146 if (hasRequiredReaddirp) return readdirp_1; 2147 hasRequiredReaddirp = 1; 2148 2149 const fs = require$$0$2; 2150 const { Readable } = require$$1; 2151 const sysPath = require$$0$1; 2152 const { promisify } = require$$2; 2153 const picomatch = /*@__PURE__*/ requirePicomatch$2(); 2154 2155 const readdir = promisify(fs.readdir); 2156 const stat = promisify(fs.stat); 2157 const lstat = promisify(fs.lstat); 2158 const realpath = promisify(fs.realpath); 2159 2160 /** 2161 * @typedef {Object} EntryInfo 2162 * @property {String} path 2163 * @property {String} fullPath 2164 * @property {fs.Stats=} stats 2165 * @property {fs.Dirent=} dirent 2166 * @property {String} basename 2167 */ 2168 2169 const BANG = '!'; 2170 const RECURSIVE_ERROR_CODE = 'READDIRP_RECURSIVE_ERROR'; 2171 const NORMAL_FLOW_ERRORS = new Set(['ENOENT', 'EPERM', 'EACCES', 'ELOOP', RECURSIVE_ERROR_CODE]); 2172 const FILE_TYPE = 'files'; 2173 const DIR_TYPE = 'directories'; 2174 const FILE_DIR_TYPE = 'files_directories'; 2175 const EVERYTHING_TYPE = 'all'; 2176 const ALL_TYPES = [FILE_TYPE, DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE]; 2177 2178 const isNormalFlowError = error => NORMAL_FLOW_ERRORS.has(error.code); 2179 const [maj, min] = process.versions.node.split('.').slice(0, 2).map(n => Number.parseInt(n, 10)); 2180 const wantBigintFsStats = process.platform === 'win32' && (maj > 10 || (maj === 10 && min >= 5)); 2181 2182 const normalizeFilter = filter => { 2183 if (filter === undefined) return; 2184 if (typeof filter === 'function') return filter; 2185 2186 if (typeof filter === 'string') { 2187 const glob = picomatch(filter.trim()); 2188 return entry => glob(entry.basename); 2189 } 2190 2191 if (Array.isArray(filter)) { 2192 const positive = []; 2193 const negative = []; 2194 for (const item of filter) { 2195 const trimmed = item.trim(); 2196 if (trimmed.charAt(0) === BANG) { 2197 negative.push(picomatch(trimmed.slice(1))); 2198 } else { 2199 positive.push(picomatch(trimmed)); 2200 } 2201 } 2202 2203 if (negative.length > 0) { 2204 if (positive.length > 0) { 2205 return entry => 2206 positive.some(f => f(entry.basename)) && !negative.some(f => f(entry.basename)); 2207 } 2208 return entry => !negative.some(f => f(entry.basename)); 2209 } 2210 return entry => positive.some(f => f(entry.basename)); 2211 } 2212 }; 2213 2214 class ReaddirpStream extends Readable { 2215 static get defaultOptions() { 2216 return { 2217 root: '.', 2218 /* eslint-disable no-unused-vars */ 2219 fileFilter: (path) => true, 2220 directoryFilter: (path) => true, 2221 /* eslint-enable no-unused-vars */ 2222 type: FILE_TYPE, 2223 lstat: false, 2224 depth: 2147483648, 2225 alwaysStat: false 2226 }; 2227 } 2228 2229 constructor(options = {}) { 2230 super({ 2231 objectMode: true, 2232 autoDestroy: true, 2233 highWaterMark: options.highWaterMark || 4096 2234 }); 2235 const opts = { ...ReaddirpStream.defaultOptions, ...options }; 2236 const { root, type } = opts; 2237 2238 this._fileFilter = normalizeFilter(opts.fileFilter); 2239 this._directoryFilter = normalizeFilter(opts.directoryFilter); 2240 2241 const statMethod = opts.lstat ? lstat : stat; 2242 // Use bigint stats if it's windows and stat() supports options (node 10+). 2243 if (wantBigintFsStats) { 2244 this._stat = path => statMethod(path, { bigint: true }); 2245 } else { 2246 this._stat = statMethod; 2247 } 2248 2249 this._maxDepth = opts.depth; 2250 this._wantsDir = [DIR_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); 2251 this._wantsFile = [FILE_TYPE, FILE_DIR_TYPE, EVERYTHING_TYPE].includes(type); 2252 this._wantsEverything = type === EVERYTHING_TYPE; 2253 this._root = sysPath.resolve(root); 2254 this._isDirent = ('Dirent' in fs) && !opts.alwaysStat; 2255 this._statsProp = this._isDirent ? 'dirent' : 'stats'; 2256 this._rdOptions = { encoding: 'utf8', withFileTypes: this._isDirent }; 2257 2258 // Launch stream with one parent, the root dir. 2259 this.parents = [this._exploreDir(root, 1)]; 2260 this.reading = false; 2261 this.parent = undefined; 2262 } 2263 2264 async _read(batch) { 2265 if (this.reading) return; 2266 this.reading = true; 2267 2268 try { 2269 while (!this.destroyed && batch > 0) { 2270 const { path, depth, files = [] } = this.parent || {}; 2271 2272 if (files.length > 0) { 2273 const slice = files.splice(0, batch).map(dirent => this._formatEntry(dirent, path)); 2274 for (const entry of await Promise.all(slice)) { 2275 if (this.destroyed) return; 2276 2277 const entryType = await this._getEntryType(entry); 2278 if (entryType === 'directory' && this._directoryFilter(entry)) { 2279 if (depth <= this._maxDepth) { 2280 this.parents.push(this._exploreDir(entry.fullPath, depth + 1)); 2281 } 2282 2283 if (this._wantsDir) { 2284 this.push(entry); 2285 batch--; 2286 } 2287 } else if ((entryType === 'file' || this._includeAsFile(entry)) && this._fileFilter(entry)) { 2288 if (this._wantsFile) { 2289 this.push(entry); 2290 batch--; 2291 } 2292 } 2293 } 2294 } else { 2295 const parent = this.parents.pop(); 2296 if (!parent) { 2297 this.push(null); 2298 break; 2299 } 2300 this.parent = await parent; 2301 if (this.destroyed) return; 2302 } 2303 } 2304 } catch (error) { 2305 this.destroy(error); 2306 } finally { 2307 this.reading = false; 2308 } 2309 } 2310 2311 async _exploreDir(path, depth) { 2312 let files; 2313 try { 2314 files = await readdir(path, this._rdOptions); 2315 } catch (error) { 2316 this._onError(error); 2317 } 2318 return { files, depth, path }; 2319 } 2320 2321 async _formatEntry(dirent, path) { 2322 let entry; 2323 try { 2324 const basename = this._isDirent ? dirent.name : dirent; 2325 const fullPath = sysPath.resolve(sysPath.join(path, basename)); 2326 entry = { path: sysPath.relative(this._root, fullPath), fullPath, basename }; 2327 entry[this._statsProp] = this._isDirent ? dirent : await this._stat(fullPath); 2328 } catch (err) { 2329 this._onError(err); 2330 } 2331 return entry; 2332 } 2333 2334 _onError(err) { 2335 if (isNormalFlowError(err) && !this.destroyed) { 2336 this.emit('warn', err); 2337 } else { 2338 this.destroy(err); 2339 } 2340 } 2341 2342 async _getEntryType(entry) { 2343 // entry may be undefined, because a warning or an error were emitted 2344 // and the statsProp is undefined 2345 const stats = entry && entry[this._statsProp]; 2346 if (!stats) { 2347 return; 2348 } 2349 if (stats.isFile()) { 2350 return 'file'; 2351 } 2352 if (stats.isDirectory()) { 2353 return 'directory'; 2354 } 2355 if (stats && stats.isSymbolicLink()) { 2356 const full = entry.fullPath; 2357 try { 2358 const entryRealPath = await realpath(full); 2359 const entryRealPathStats = await lstat(entryRealPath); 2360 if (entryRealPathStats.isFile()) { 2361 return 'file'; 2362 } 2363 if (entryRealPathStats.isDirectory()) { 2364 const len = entryRealPath.length; 2365 if (full.startsWith(entryRealPath) && full.substr(len, 1) === sysPath.sep) { 2366 const recursiveError = new Error( 2367 `Circular symlink detected: "${full}" points to "${entryRealPath}"` 2368 ); 2369 recursiveError.code = RECURSIVE_ERROR_CODE; 2370 return this._onError(recursiveError); 2371 } 2372 return 'directory'; 2373 } 2374 } catch (error) { 2375 this._onError(error); 2376 } 2377 } 2378 } 2379 2380 _includeAsFile(entry) { 2381 const stats = entry && entry[this._statsProp]; 2382 2383 return stats && this._wantsEverything && !stats.isDirectory(); 2384 } 2385 } 2386 2387 /** 2388 * @typedef {Object} ReaddirpArguments 2389 * @property {Function=} fileFilter 2390 * @property {Function=} directoryFilter 2391 * @property {String=} type 2392 * @property {Number=} depth 2393 * @property {String=} root 2394 * @property {Boolean=} lstat 2395 * @property {Boolean=} bigint 2396 */ 2397 2398 /** 2399 * Main function which ends up calling readdirRec and reads all files and directories in given root recursively. 2400 * @param {String} root Root directory 2401 * @param {ReaddirpArguments=} options Options to specify root (start directory), filters and recursion depth 2402 */ 2403 const readdirp = (root, options = {}) => { 2404 let type = options.entryType || options.type; 2405 if (type === 'both') type = FILE_DIR_TYPE; // backwards-compatibility 2406 if (type) options.type = type; 2407 if (!root) { 2408 throw new Error('readdirp: root argument is required. Usage: readdirp(root, options)'); 2409 } else if (typeof root !== 'string') { 2410 throw new TypeError('readdirp: root argument must be a string. Usage: readdirp(root, options)'); 2411 } else if (type && !ALL_TYPES.includes(type)) { 2412 throw new Error(`readdirp: Invalid type passed. Use one of ${ALL_TYPES.join(', ')}`); 2413 } 2414 2415 options.root = root; 2416 return new ReaddirpStream(options); 2417 }; 2418 2419 const readdirpPromise = (root, options = {}) => { 2420 return new Promise((resolve, reject) => { 2421 const files = []; 2422 readdirp(root, options) 2423 .on('data', entry => files.push(entry)) 2424 .on('end', () => resolve(files)) 2425 .on('error', error => reject(error)); 2426 }); 2427 }; 2428 2429 readdirp.promise = readdirpPromise; 2430 readdirp.ReaddirpStream = ReaddirpStream; 2431 readdirp.default = readdirp; 2432 2433 readdirp_1 = readdirp; 2434 return readdirp_1; 2435 } 2436 2437 var anymatch = {exports: {}}; 2438 2439 var utils$1 = {}; 2440 2441 var constants$2; 2442 var hasRequiredConstants$2; 2443 2444 function requireConstants$2 () { 2445 if (hasRequiredConstants$2) return constants$2; 2446 hasRequiredConstants$2 = 1; 2447 2448 const path = require$$0$1; 2449 const WIN_SLASH = '\\\\/'; 2450 const WIN_NO_SLASH = `[^${WIN_SLASH}]`; 2451 2452 /** 2453 * Posix glob regex 2454 */ 2455 2456 const DOT_LITERAL = '\\.'; 2457 const PLUS_LITERAL = '\\+'; 2458 const QMARK_LITERAL = '\\?'; 2459 const SLASH_LITERAL = '\\/'; 2460 const ONE_CHAR = '(?=.)'; 2461 const QMARK = '[^/]'; 2462 const END_ANCHOR = `(?:${SLASH_LITERAL}|$)`; 2463 const START_ANCHOR = `(?:^|${SLASH_LITERAL})`; 2464 const DOTS_SLASH = `${DOT_LITERAL}{1,2}${END_ANCHOR}`; 2465 const NO_DOT = `(?!${DOT_LITERAL})`; 2466 const NO_DOTS = `(?!${START_ANCHOR}${DOTS_SLASH})`; 2467 const NO_DOT_SLASH = `(?!${DOT_LITERAL}{0,1}${END_ANCHOR})`; 2468 const NO_DOTS_SLASH = `(?!${DOTS_SLASH})`; 2469 const QMARK_NO_DOT = `[^.${SLASH_LITERAL}]`; 2470 const STAR = `${QMARK}*?`; 2471 2472 const POSIX_CHARS = { 2473 DOT_LITERAL, 2474 PLUS_LITERAL, 2475 QMARK_LITERAL, 2476 SLASH_LITERAL, 2477 ONE_CHAR, 2478 QMARK, 2479 END_ANCHOR, 2480 DOTS_SLASH, 2481 NO_DOT, 2482 NO_DOTS, 2483 NO_DOT_SLASH, 2484 NO_DOTS_SLASH, 2485 QMARK_NO_DOT, 2486 STAR, 2487 START_ANCHOR 2488 }; 2489 2490 /** 2491 * Windows glob regex 2492 */ 2493 2494 const WINDOWS_CHARS = { 2495 ...POSIX_CHARS, 2496 2497 SLASH_LITERAL: `[${WIN_SLASH}]`, 2498 QMARK: WIN_NO_SLASH, 2499 STAR: `${WIN_NO_SLASH}*?`, 2500 DOTS_SLASH: `${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$)`, 2501 NO_DOT: `(?!${DOT_LITERAL})`, 2502 NO_DOTS: `(?!(?:^|[${WIN_SLASH}])${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 2503 NO_DOT_SLASH: `(?!${DOT_LITERAL}{0,1}(?:[${WIN_SLASH}]|$))`, 2504 NO_DOTS_SLASH: `(?!${DOT_LITERAL}{1,2}(?:[${WIN_SLASH}]|$))`, 2505 QMARK_NO_DOT: `[^.${WIN_SLASH}]`, 2506 START_ANCHOR: `(?:^|[${WIN_SLASH}])`, 2507 END_ANCHOR: `(?:[${WIN_SLASH}]|$)` 2508 }; 2509 2510 /** 2511 * POSIX Bracket Regex 2512 */ 2513 2514 const POSIX_REGEX_SOURCE = { 2515 alnum: 'a-zA-Z0-9', 2516 alpha: 'a-zA-Z', 2517 ascii: '\\x00-\\x7F', 2518 blank: ' \\t', 2519 cntrl: '\\x00-\\x1F\\x7F', 2520 digit: '0-9', 2521 graph: '\\x21-\\x7E', 2522 lower: 'a-z', 2523 print: '\\x20-\\x7E ', 2524 punct: '\\-!"#$%&\'()\\*+,./:;<=>?@[\\]^_`{|}~', 2525 space: ' \\t\\r\\n\\v\\f', 2526 upper: 'A-Z', 2527 word: 'A-Za-z0-9_', 2528 xdigit: 'A-Fa-f0-9' 2529 }; 2530 2531 constants$2 = { 2532 MAX_LENGTH: 1024 * 64, 2533 POSIX_REGEX_SOURCE, 2534 2535 // regular expressions 2536 REGEX_BACKSLASH: /\\(?![*+?^${}(|)[\]])/g, 2537 REGEX_NON_SPECIAL_CHARS: /^[^@![\].,$*+?^{}()|\\/]+/, 2538 REGEX_SPECIAL_CHARS: /[-*+?.^${}(|)[\]]/, 2539 REGEX_SPECIAL_CHARS_BACKREF: /(\\?)((\W)(\3*))/g, 2540 REGEX_SPECIAL_CHARS_GLOBAL: /([-*+?.^${}(|)[\]])/g, 2541 REGEX_REMOVE_BACKSLASH: /(?:\[.*?[^\\]\]|\\(?=.))/g, 2542 2543 // Replace globs with equivalent patterns to reduce parsing time. 2544 REPLACEMENTS: { 2545 '***': '*', 2546 '**/**': '**', 2547 '**/**/**': '**' 2548 }, 2549 2550 // Digits 2551 CHAR_0: 48, /* 0 */ 2552 CHAR_9: 57, /* 9 */ 2553 2554 // Alphabet chars. 2555 CHAR_UPPERCASE_A: 65, /* A */ 2556 CHAR_LOWERCASE_A: 97, /* a */ 2557 CHAR_UPPERCASE_Z: 90, /* Z */ 2558 CHAR_LOWERCASE_Z: 122, /* z */ 2559 2560 CHAR_LEFT_PARENTHESES: 40, /* ( */ 2561 CHAR_RIGHT_PARENTHESES: 41, /* ) */ 2562 2563 CHAR_ASTERISK: 42, /* * */ 2564 2565 // Non-alphabetic chars. 2566 CHAR_AMPERSAND: 38, /* & */ 2567 CHAR_AT: 64, /* @ */ 2568 CHAR_BACKWARD_SLASH: 92, /* \ */ 2569 CHAR_CARRIAGE_RETURN: 13, /* \r */ 2570 CHAR_CIRCUMFLEX_ACCENT: 94, /* ^ */ 2571 CHAR_COLON: 58, /* : */ 2572 CHAR_COMMA: 44, /* , */ 2573 CHAR_DOT: 46, /* . */ 2574 CHAR_DOUBLE_QUOTE: 34, /* " */ 2575 CHAR_EQUAL: 61, /* = */ 2576 CHAR_EXCLAMATION_MARK: 33, /* ! */ 2577 CHAR_FORM_FEED: 12, /* \f */ 2578 CHAR_FORWARD_SLASH: 47, /* / */ 2579 CHAR_GRAVE_ACCENT: 96, /* ` */ 2580 CHAR_HASH: 35, /* # */ 2581 CHAR_HYPHEN_MINUS: 45, /* - */ 2582 CHAR_LEFT_ANGLE_BRACKET: 60, /* < */ 2583 CHAR_LEFT_CURLY_BRACE: 123, /* { */ 2584 CHAR_LEFT_SQUARE_BRACKET: 91, /* [ */ 2585 CHAR_LINE_FEED: 10, /* \n */ 2586 CHAR_NO_BREAK_SPACE: 160, /* \u00A0 */ 2587 CHAR_PERCENT: 37, /* % */ 2588 CHAR_PLUS: 43, /* + */ 2589 CHAR_QUESTION_MARK: 63, /* ? */ 2590 CHAR_RIGHT_ANGLE_BRACKET: 62, /* > */ 2591 CHAR_RIGHT_CURLY_BRACE: 125, /* } */ 2592 CHAR_RIGHT_SQUARE_BRACKET: 93, /* ] */ 2593 CHAR_SEMICOLON: 59, /* ; */ 2594 CHAR_SINGLE_QUOTE: 39, /* ' */ 2595 CHAR_SPACE: 32, /* */ 2596 CHAR_TAB: 9, /* \t */ 2597 CHAR_UNDERSCORE: 95, /* _ */ 2598 CHAR_VERTICAL_LINE: 124, /* | */ 2599 CHAR_ZERO_WIDTH_NOBREAK_SPACE: 65279, /* \uFEFF */ 2600 2601 SEP: path.sep, 2602 2603 /** 2604 * Create EXTGLOB_CHARS 2605 */ 2606 2607 extglobChars(chars) { 2608 return { 2609 '!': { type: 'negate', open: '(?:(?!(?:', close: `))${chars.STAR})` }, 2610 '?': { type: 'qmark', open: '(?:', close: ')?' }, 2611 '+': { type: 'plus', open: '(?:', close: ')+' }, 2612 '*': { type: 'star', open: '(?:', close: ')*' }, 2613 '@': { type: 'at', open: '(?:', close: ')' } 2614 }; 2615 }, 2616 2617 /** 2618 * Create GLOB_CHARS 2619 */ 2620 2621 globChars(win32) { 2622 return win32 === true ? WINDOWS_CHARS : POSIX_CHARS; 2623 } 2624 }; 2625 return constants$2; 2626 } 2627 2628 var hasRequiredUtils$1; 2629 2630 function requireUtils$1 () { 2631 if (hasRequiredUtils$1) return utils$1; 2632 hasRequiredUtils$1 = 1; 2633 (function (exports) { 2634 2635 const path = require$$0$1; 2636 const win32 = process.platform === 'win32'; 2637 const { 2638 REGEX_BACKSLASH, 2639 REGEX_REMOVE_BACKSLASH, 2640 REGEX_SPECIAL_CHARS, 2641 REGEX_SPECIAL_CHARS_GLOBAL 2642 } = /*@__PURE__*/ requireConstants$2(); 2643 2644 exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 2645 exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); 2646 exports.isRegexChar = str => str.length === 1 && exports.hasRegexChars(str); 2647 exports.escapeRegex = str => str.replace(REGEX_SPECIAL_CHARS_GLOBAL, '\\$1'); 2648 exports.toPosixSlashes = str => str.replace(REGEX_BACKSLASH, '/'); 2649 2650 exports.removeBackslashes = str => { 2651 return str.replace(REGEX_REMOVE_BACKSLASH, match => { 2652 return match === '\\' ? '' : match; 2653 }); 2654 }; 2655 2656 exports.supportsLookbehinds = () => { 2657 const segs = process.version.slice(1).split('.').map(Number); 2658 if (segs.length === 3 && segs[0] >= 9 || (segs[0] === 8 && segs[1] >= 10)) { 2659 return true; 2660 } 2661 return false; 2662 }; 2663 2664 exports.isWindows = options => { 2665 if (options && typeof options.windows === 'boolean') { 2666 return options.windows; 2667 } 2668 return win32 === true || path.sep === '\\'; 2669 }; 2670 2671 exports.escapeLast = (input, char, lastIdx) => { 2672 const idx = input.lastIndexOf(char, lastIdx); 2673 if (idx === -1) return input; 2674 if (input[idx - 1] === '\\') return exports.escapeLast(input, char, idx - 1); 2675 return `${input.slice(0, idx)}\\${input.slice(idx)}`; 2676 }; 2677 2678 exports.removePrefix = (input, state = {}) => { 2679 let output = input; 2680 if (output.startsWith('./')) { 2681 output = output.slice(2); 2682 state.prefix = './'; 2683 } 2684 return output; 2685 }; 2686 2687 exports.wrapOutput = (input, state = {}, options = {}) => { 2688 const prepend = options.contains ? '' : '^'; 2689 const append = options.contains ? '' : '$'; 2690 2691 let output = `${prepend}(?:${input})${append}`; 2692 if (state.negated === true) { 2693 output = `(?:^(?!${output}).*$)`; 2694 } 2695 return output; 2696 }; 2697 } (utils$1)); 2698 return utils$1; 2699 } 2700 2701 var scan_1; 2702 var hasRequiredScan; 2703 2704 function requireScan () { 2705 if (hasRequiredScan) return scan_1; 2706 hasRequiredScan = 1; 2707 2708 const utils = /*@__PURE__*/ requireUtils$1(); 2709 const { 2710 CHAR_ASTERISK, /* * */ 2711 CHAR_AT, /* @ */ 2712 CHAR_BACKWARD_SLASH, /* \ */ 2713 CHAR_COMMA, /* , */ 2714 CHAR_DOT, /* . */ 2715 CHAR_EXCLAMATION_MARK, /* ! */ 2716 CHAR_FORWARD_SLASH, /* / */ 2717 CHAR_LEFT_CURLY_BRACE, /* { */ 2718 CHAR_LEFT_PARENTHESES, /* ( */ 2719 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 2720 CHAR_PLUS, /* + */ 2721 CHAR_QUESTION_MARK, /* ? */ 2722 CHAR_RIGHT_CURLY_BRACE, /* } */ 2723 CHAR_RIGHT_PARENTHESES, /* ) */ 2724 CHAR_RIGHT_SQUARE_BRACKET /* ] */ 2725 } = /*@__PURE__*/ requireConstants$2(); 2726 2727 const isPathSeparator = code => { 2728 return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; 2729 }; 2730 2731 const depth = token => { 2732 if (token.isPrefix !== true) { 2733 token.depth = token.isGlobstar ? Infinity : 1; 2734 } 2735 }; 2736 2737 /** 2738 * Quickly scans a glob pattern and returns an object with a handful of 2739 * useful properties, like `isGlob`, `path` (the leading non-glob, if it exists), 2740 * `glob` (the actual pattern), `negated` (true if the path starts with `!` but not 2741 * with `!(`) and `negatedExtglob` (true if the path starts with `!(`). 2742 * 2743 * ```js 2744 * const pm = require('picomatch'); 2745 * console.log(pm.scan('foo/bar/*.js')); 2746 * { isGlob: true, input: 'foo/bar/*.js', base: 'foo/bar', glob: '*.js' } 2747 * ``` 2748 * @param {String} `str` 2749 * @param {Object} `options` 2750 * @return {Object} Returns an object with tokens and regex source string. 2751 * @api public 2752 */ 2753 2754 const scan = (input, options) => { 2755 const opts = options || {}; 2756 2757 const length = input.length - 1; 2758 const scanToEnd = opts.parts === true || opts.scanToEnd === true; 2759 const slashes = []; 2760 const tokens = []; 2761 const parts = []; 2762 2763 let str = input; 2764 let index = -1; 2765 let start = 0; 2766 let lastIndex = 0; 2767 let isBrace = false; 2768 let isBracket = false; 2769 let isGlob = false; 2770 let isExtglob = false; 2771 let isGlobstar = false; 2772 let braceEscaped = false; 2773 let backslashes = false; 2774 let negated = false; 2775 let negatedExtglob = false; 2776 let finished = false; 2777 let braces = 0; 2778 let prev; 2779 let code; 2780 let token = { value: '', depth: 0, isGlob: false }; 2781 2782 const eos = () => index >= length; 2783 const peek = () => str.charCodeAt(index + 1); 2784 const advance = () => { 2785 prev = code; 2786 return str.charCodeAt(++index); 2787 }; 2788 2789 while (index < length) { 2790 code = advance(); 2791 let next; 2792 2793 if (code === CHAR_BACKWARD_SLASH) { 2794 backslashes = token.backslashes = true; 2795 code = advance(); 2796 2797 if (code === CHAR_LEFT_CURLY_BRACE) { 2798 braceEscaped = true; 2799 } 2800 continue; 2801 } 2802 2803 if (braceEscaped === true || code === CHAR_LEFT_CURLY_BRACE) { 2804 braces++; 2805 2806 while (eos() !== true && (code = advance())) { 2807 if (code === CHAR_BACKWARD_SLASH) { 2808 backslashes = token.backslashes = true; 2809 advance(); 2810 continue; 2811 } 2812 2813 if (code === CHAR_LEFT_CURLY_BRACE) { 2814 braces++; 2815 continue; 2816 } 2817 2818 if (braceEscaped !== true && code === CHAR_DOT && (code = advance()) === CHAR_DOT) { 2819 isBrace = token.isBrace = true; 2820 isGlob = token.isGlob = true; 2821 finished = true; 2822 2823 if (scanToEnd === true) { 2824 continue; 2825 } 2826 2827 break; 2828 } 2829 2830 if (braceEscaped !== true && code === CHAR_COMMA) { 2831 isBrace = token.isBrace = true; 2832 isGlob = token.isGlob = true; 2833 finished = true; 2834 2835 if (scanToEnd === true) { 2836 continue; 2837 } 2838 2839 break; 2840 } 2841 2842 if (code === CHAR_RIGHT_CURLY_BRACE) { 2843 braces--; 2844 2845 if (braces === 0) { 2846 braceEscaped = false; 2847 isBrace = token.isBrace = true; 2848 finished = true; 2849 break; 2850 } 2851 } 2852 } 2853 2854 if (scanToEnd === true) { 2855 continue; 2856 } 2857 2858 break; 2859 } 2860 2861 if (code === CHAR_FORWARD_SLASH) { 2862 slashes.push(index); 2863 tokens.push(token); 2864 token = { value: '', depth: 0, isGlob: false }; 2865 2866 if (finished === true) continue; 2867 if (prev === CHAR_DOT && index === (start + 1)) { 2868 start += 2; 2869 continue; 2870 } 2871 2872 lastIndex = index + 1; 2873 continue; 2874 } 2875 2876 if (opts.noext !== true) { 2877 const isExtglobChar = code === CHAR_PLUS 2878 || code === CHAR_AT 2879 || code === CHAR_ASTERISK 2880 || code === CHAR_QUESTION_MARK 2881 || code === CHAR_EXCLAMATION_MARK; 2882 2883 if (isExtglobChar === true && peek() === CHAR_LEFT_PARENTHESES) { 2884 isGlob = token.isGlob = true; 2885 isExtglob = token.isExtglob = true; 2886 finished = true; 2887 if (code === CHAR_EXCLAMATION_MARK && index === start) { 2888 negatedExtglob = true; 2889 } 2890 2891 if (scanToEnd === true) { 2892 while (eos() !== true && (code = advance())) { 2893 if (code === CHAR_BACKWARD_SLASH) { 2894 backslashes = token.backslashes = true; 2895 code = advance(); 2896 continue; 2897 } 2898 2899 if (code === CHAR_RIGHT_PARENTHESES) { 2900 isGlob = token.isGlob = true; 2901 finished = true; 2902 break; 2903 } 2904 } 2905 continue; 2906 } 2907 break; 2908 } 2909 } 2910 2911 if (code === CHAR_ASTERISK) { 2912 if (prev === CHAR_ASTERISK) isGlobstar = token.isGlobstar = true; 2913 isGlob = token.isGlob = true; 2914 finished = true; 2915 2916 if (scanToEnd === true) { 2917 continue; 2918 } 2919 break; 2920 } 2921 2922 if (code === CHAR_QUESTION_MARK) { 2923 isGlob = token.isGlob = true; 2924 finished = true; 2925 2926 if (scanToEnd === true) { 2927 continue; 2928 } 2929 break; 2930 } 2931 2932 if (code === CHAR_LEFT_SQUARE_BRACKET) { 2933 while (eos() !== true && (next = advance())) { 2934 if (next === CHAR_BACKWARD_SLASH) { 2935 backslashes = token.backslashes = true; 2936 advance(); 2937 continue; 2938 } 2939 2940 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 2941 isBracket = token.isBracket = true; 2942 isGlob = token.isGlob = true; 2943 finished = true; 2944 break; 2945 } 2946 } 2947 2948 if (scanToEnd === true) { 2949 continue; 2950 } 2951 2952 break; 2953 } 2954 2955 if (opts.nonegate !== true && code === CHAR_EXCLAMATION_MARK && index === start) { 2956 negated = token.negated = true; 2957 start++; 2958 continue; 2959 } 2960 2961 if (opts.noparen !== true && code === CHAR_LEFT_PARENTHESES) { 2962 isGlob = token.isGlob = true; 2963 2964 if (scanToEnd === true) { 2965 while (eos() !== true && (code = advance())) { 2966 if (code === CHAR_LEFT_PARENTHESES) { 2967 backslashes = token.backslashes = true; 2968 code = advance(); 2969 continue; 2970 } 2971 2972 if (code === CHAR_RIGHT_PARENTHESES) { 2973 finished = true; 2974 break; 2975 } 2976 } 2977 continue; 2978 } 2979 break; 2980 } 2981 2982 if (isGlob === true) { 2983 finished = true; 2984 2985 if (scanToEnd === true) { 2986 continue; 2987 } 2988 2989 break; 2990 } 2991 } 2992 2993 if (opts.noext === true) { 2994 isExtglob = false; 2995 isGlob = false; 2996 } 2997 2998 let base = str; 2999 let prefix = ''; 3000 let glob = ''; 3001 3002 if (start > 0) { 3003 prefix = str.slice(0, start); 3004 str = str.slice(start); 3005 lastIndex -= start; 3006 } 3007 3008 if (base && isGlob === true && lastIndex > 0) { 3009 base = str.slice(0, lastIndex); 3010 glob = str.slice(lastIndex); 3011 } else if (isGlob === true) { 3012 base = ''; 3013 glob = str; 3014 } else { 3015 base = str; 3016 } 3017 3018 if (base && base !== '' && base !== '/' && base !== str) { 3019 if (isPathSeparator(base.charCodeAt(base.length - 1))) { 3020 base = base.slice(0, -1); 3021 } 3022 } 3023 3024 if (opts.unescape === true) { 3025 if (glob) glob = utils.removeBackslashes(glob); 3026 3027 if (base && backslashes === true) { 3028 base = utils.removeBackslashes(base); 3029 } 3030 } 3031 3032 const state = { 3033 prefix, 3034 input, 3035 start, 3036 base, 3037 glob, 3038 isBrace, 3039 isBracket, 3040 isGlob, 3041 isExtglob, 3042 isGlobstar, 3043 negated, 3044 negatedExtglob 3045 }; 3046 3047 if (opts.tokens === true) { 3048 state.maxDepth = 0; 3049 if (!isPathSeparator(code)) { 3050 tokens.push(token); 3051 } 3052 state.tokens = tokens; 3053 } 3054 3055 if (opts.parts === true || opts.tokens === true) { 3056 let prevIndex; 3057 3058 for (let idx = 0; idx < slashes.length; idx++) { 3059 const n = prevIndex ? prevIndex + 1 : start; 3060 const i = slashes[idx]; 3061 const value = input.slice(n, i); 3062 if (opts.tokens) { 3063 if (idx === 0 && start !== 0) { 3064 tokens[idx].isPrefix = true; 3065 tokens[idx].value = prefix; 3066 } else { 3067 tokens[idx].value = value; 3068 } 3069 depth(tokens[idx]); 3070 state.maxDepth += tokens[idx].depth; 3071 } 3072 if (idx !== 0 || value !== '') { 3073 parts.push(value); 3074 } 3075 prevIndex = i; 3076 } 3077 3078 if (prevIndex && prevIndex + 1 < input.length) { 3079 const value = input.slice(prevIndex + 1); 3080 parts.push(value); 3081 3082 if (opts.tokens) { 3083 tokens[tokens.length - 1].value = value; 3084 depth(tokens[tokens.length - 1]); 3085 state.maxDepth += tokens[tokens.length - 1].depth; 3086 } 3087 } 3088 3089 state.slashes = slashes; 3090 state.parts = parts; 3091 } 3092 3093 return state; 3094 }; 3095 3096 scan_1 = scan; 3097 return scan_1; 3098 } 3099 3100 var parse_1$1; 3101 var hasRequiredParse$1; 3102 3103 function requireParse$1 () { 3104 if (hasRequiredParse$1) return parse_1$1; 3105 hasRequiredParse$1 = 1; 3106 3107 const constants = /*@__PURE__*/ requireConstants$2(); 3108 const utils = /*@__PURE__*/ requireUtils$1(); 3109 3110 /** 3111 * Constants 3112 */ 3113 3114 const { 3115 MAX_LENGTH, 3116 POSIX_REGEX_SOURCE, 3117 REGEX_NON_SPECIAL_CHARS, 3118 REGEX_SPECIAL_CHARS_BACKREF, 3119 REPLACEMENTS 3120 } = constants; 3121 3122 /** 3123 * Helpers 3124 */ 3125 3126 const expandRange = (args, options) => { 3127 if (typeof options.expandRange === 'function') { 3128 return options.expandRange(...args, options); 3129 } 3130 3131 args.sort(); 3132 const value = `[${args.join('-')}]`; 3133 3134 return value; 3135 }; 3136 3137 /** 3138 * Create the message for a syntax error 3139 */ 3140 3141 const syntaxError = (type, char) => { 3142 return `Missing ${type}: "${char}" - use "\\\\${char}" to match literal characters`; 3143 }; 3144 3145 /** 3146 * Parse the given input string. 3147 * @param {String} input 3148 * @param {Object} options 3149 * @return {Object} 3150 */ 3151 3152 const parse = (input, options) => { 3153 if (typeof input !== 'string') { 3154 throw new TypeError('Expected a string'); 3155 } 3156 3157 input = REPLACEMENTS[input] || input; 3158 3159 const opts = { ...options }; 3160 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 3161 3162 let len = input.length; 3163 if (len > max) { 3164 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 3165 } 3166 3167 const bos = { type: 'bos', value: '', output: opts.prepend || '' }; 3168 const tokens = [bos]; 3169 3170 const capture = opts.capture ? '' : '?:'; 3171 const win32 = utils.isWindows(options); 3172 3173 // create constants based on platform, for windows or posix 3174 const PLATFORM_CHARS = constants.globChars(win32); 3175 const EXTGLOB_CHARS = constants.extglobChars(PLATFORM_CHARS); 3176 3177 const { 3178 DOT_LITERAL, 3179 PLUS_LITERAL, 3180 SLASH_LITERAL, 3181 ONE_CHAR, 3182 DOTS_SLASH, 3183 NO_DOT, 3184 NO_DOT_SLASH, 3185 NO_DOTS_SLASH, 3186 QMARK, 3187 QMARK_NO_DOT, 3188 STAR, 3189 START_ANCHOR 3190 } = PLATFORM_CHARS; 3191 3192 const globstar = opts => { 3193 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 3194 }; 3195 3196 const nodot = opts.dot ? '' : NO_DOT; 3197 const qmarkNoDot = opts.dot ? QMARK : QMARK_NO_DOT; 3198 let star = opts.bash === true ? globstar(opts) : STAR; 3199 3200 if (opts.capture) { 3201 star = `(${star})`; 3202 } 3203 3204 // minimatch options support 3205 if (typeof opts.noext === 'boolean') { 3206 opts.noextglob = opts.noext; 3207 } 3208 3209 const state = { 3210 input, 3211 index: -1, 3212 start: 0, 3213 dot: opts.dot === true, 3214 consumed: '', 3215 output: '', 3216 prefix: '', 3217 backtrack: false, 3218 negated: false, 3219 brackets: 0, 3220 braces: 0, 3221 parens: 0, 3222 quotes: 0, 3223 globstar: false, 3224 tokens 3225 }; 3226 3227 input = utils.removePrefix(input, state); 3228 len = input.length; 3229 3230 const extglobs = []; 3231 const braces = []; 3232 const stack = []; 3233 let prev = bos; 3234 let value; 3235 3236 /** 3237 * Tokenizing helpers 3238 */ 3239 3240 const eos = () => state.index === len - 1; 3241 const peek = state.peek = (n = 1) => input[state.index + n]; 3242 const advance = state.advance = () => input[++state.index] || ''; 3243 const remaining = () => input.slice(state.index + 1); 3244 const consume = (value = '', num = 0) => { 3245 state.consumed += value; 3246 state.index += num; 3247 }; 3248 3249 const append = token => { 3250 state.output += token.output != null ? token.output : token.value; 3251 consume(token.value); 3252 }; 3253 3254 const negate = () => { 3255 let count = 1; 3256 3257 while (peek() === '!' && (peek(2) !== '(' || peek(3) === '?')) { 3258 advance(); 3259 state.start++; 3260 count++; 3261 } 3262 3263 if (count % 2 === 0) { 3264 return false; 3265 } 3266 3267 state.negated = true; 3268 state.start++; 3269 return true; 3270 }; 3271 3272 const increment = type => { 3273 state[type]++; 3274 stack.push(type); 3275 }; 3276 3277 const decrement = type => { 3278 state[type]--; 3279 stack.pop(); 3280 }; 3281 3282 /** 3283 * Push tokens onto the tokens array. This helper speeds up 3284 * tokenizing by 1) helping us avoid backtracking as much as possible, 3285 * and 2) helping us avoid creating extra tokens when consecutive 3286 * characters are plain text. This improves performance and simplifies 3287 * lookbehinds. 3288 */ 3289 3290 const push = tok => { 3291 if (prev.type === 'globstar') { 3292 const isBrace = state.braces > 0 && (tok.type === 'comma' || tok.type === 'brace'); 3293 const isExtglob = tok.extglob === true || (extglobs.length && (tok.type === 'pipe' || tok.type === 'paren')); 3294 3295 if (tok.type !== 'slash' && tok.type !== 'paren' && !isBrace && !isExtglob) { 3296 state.output = state.output.slice(0, -prev.output.length); 3297 prev.type = 'star'; 3298 prev.value = '*'; 3299 prev.output = star; 3300 state.output += prev.output; 3301 } 3302 } 3303 3304 if (extglobs.length && tok.type !== 'paren') { 3305 extglobs[extglobs.length - 1].inner += tok.value; 3306 } 3307 3308 if (tok.value || tok.output) append(tok); 3309 if (prev && prev.type === 'text' && tok.type === 'text') { 3310 prev.value += tok.value; 3311 prev.output = (prev.output || '') + tok.value; 3312 return; 3313 } 3314 3315 tok.prev = prev; 3316 tokens.push(tok); 3317 prev = tok; 3318 }; 3319 3320 const extglobOpen = (type, value) => { 3321 const token = { ...EXTGLOB_CHARS[value], conditions: 1, inner: '' }; 3322 3323 token.prev = prev; 3324 token.parens = state.parens; 3325 token.output = state.output; 3326 const output = (opts.capture ? '(' : '') + token.open; 3327 3328 increment('parens'); 3329 push({ type, value, output: state.output ? '' : ONE_CHAR }); 3330 push({ type: 'paren', extglob: true, value: advance(), output }); 3331 extglobs.push(token); 3332 }; 3333 3334 const extglobClose = token => { 3335 let output = token.close + (opts.capture ? ')' : ''); 3336 let rest; 3337 3338 if (token.type === 'negate') { 3339 let extglobStar = star; 3340 3341 if (token.inner && token.inner.length > 1 && token.inner.includes('/')) { 3342 extglobStar = globstar(opts); 3343 } 3344 3345 if (extglobStar !== star || eos() || /^\)+$/.test(remaining())) { 3346 output = token.close = `)$))${extglobStar}`; 3347 } 3348 3349 if (token.inner.includes('*') && (rest = remaining()) && /^\.[^\\/.]+$/.test(rest)) { 3350 // Any non-magical string (`.ts`) or even nested expression (`.{ts,tsx}`) can follow after the closing parenthesis. 3351 // In this case, we need to parse the string and use it in the output of the original pattern. 3352 // Suitable patterns: `/!(*.d).ts`, `/!(*.d).{ts,tsx}`, `**/!(*-dbg).@(js)`. 3353 // 3354 // Disabling the `fastpaths` option due to a problem with parsing strings as `.ts` in the pattern like `**/!(*.d).ts`. 3355 const expression = parse(rest, { ...options, fastpaths: false }).output; 3356 3357 output = token.close = `)${expression})${extglobStar})`; 3358 } 3359 3360 if (token.prev.type === 'bos') { 3361 state.negatedExtglob = true; 3362 } 3363 } 3364 3365 push({ type: 'paren', extglob: true, value, output }); 3366 decrement('parens'); 3367 }; 3368 3369 /** 3370 * Fast paths 3371 */ 3372 3373 if (opts.fastpaths !== false && !/(^[*!]|[/()[\]{}"])/.test(input)) { 3374 let backslashes = false; 3375 3376 let output = input.replace(REGEX_SPECIAL_CHARS_BACKREF, (m, esc, chars, first, rest, index) => { 3377 if (first === '\\') { 3378 backslashes = true; 3379 return m; 3380 } 3381 3382 if (first === '?') { 3383 if (esc) { 3384 return esc + first + (rest ? QMARK.repeat(rest.length) : ''); 3385 } 3386 if (index === 0) { 3387 return qmarkNoDot + (rest ? QMARK.repeat(rest.length) : ''); 3388 } 3389 return QMARK.repeat(chars.length); 3390 } 3391 3392 if (first === '.') { 3393 return DOT_LITERAL.repeat(chars.length); 3394 } 3395 3396 if (first === '*') { 3397 if (esc) { 3398 return esc + first + (rest ? star : ''); 3399 } 3400 return star; 3401 } 3402 return esc ? m : `\\${m}`; 3403 }); 3404 3405 if (backslashes === true) { 3406 if (opts.unescape === true) { 3407 output = output.replace(/\\/g, ''); 3408 } else { 3409 output = output.replace(/\\+/g, m => { 3410 return m.length % 2 === 0 ? '\\\\' : (m ? '\\' : ''); 3411 }); 3412 } 3413 } 3414 3415 if (output === input && opts.contains === true) { 3416 state.output = input; 3417 return state; 3418 } 3419 3420 state.output = utils.wrapOutput(output, state, options); 3421 return state; 3422 } 3423 3424 /** 3425 * Tokenize input until we reach end-of-string 3426 */ 3427 3428 while (!eos()) { 3429 value = advance(); 3430 3431 if (value === '\u0000') { 3432 continue; 3433 } 3434 3435 /** 3436 * Escaped characters 3437 */ 3438 3439 if (value === '\\') { 3440 const next = peek(); 3441 3442 if (next === '/' && opts.bash !== true) { 3443 continue; 3444 } 3445 3446 if (next === '.' || next === ';') { 3447 continue; 3448 } 3449 3450 if (!next) { 3451 value += '\\'; 3452 push({ type: 'text', value }); 3453 continue; 3454 } 3455 3456 // collapse slashes to reduce potential for exploits 3457 const match = /^\\+/.exec(remaining()); 3458 let slashes = 0; 3459 3460 if (match && match[0].length > 2) { 3461 slashes = match[0].length; 3462 state.index += slashes; 3463 if (slashes % 2 !== 0) { 3464 value += '\\'; 3465 } 3466 } 3467 3468 if (opts.unescape === true) { 3469 value = advance(); 3470 } else { 3471 value += advance(); 3472 } 3473 3474 if (state.brackets === 0) { 3475 push({ type: 'text', value }); 3476 continue; 3477 } 3478 } 3479 3480 /** 3481 * If we're inside a regex character class, continue 3482 * until we reach the closing bracket. 3483 */ 3484 3485 if (state.brackets > 0 && (value !== ']' || prev.value === '[' || prev.value === '[^')) { 3486 if (opts.posix !== false && value === ':') { 3487 const inner = prev.value.slice(1); 3488 if (inner.includes('[')) { 3489 prev.posix = true; 3490 3491 if (inner.includes(':')) { 3492 const idx = prev.value.lastIndexOf('['); 3493 const pre = prev.value.slice(0, idx); 3494 const rest = prev.value.slice(idx + 2); 3495 const posix = POSIX_REGEX_SOURCE[rest]; 3496 if (posix) { 3497 prev.value = pre + posix; 3498 state.backtrack = true; 3499 advance(); 3500 3501 if (!bos.output && tokens.indexOf(prev) === 1) { 3502 bos.output = ONE_CHAR; 3503 } 3504 continue; 3505 } 3506 } 3507 } 3508 } 3509 3510 if ((value === '[' && peek() !== ':') || (value === '-' && peek() === ']')) { 3511 value = `\\${value}`; 3512 } 3513 3514 if (value === ']' && (prev.value === '[' || prev.value === '[^')) { 3515 value = `\\${value}`; 3516 } 3517 3518 if (opts.posix === true && value === '!' && prev.value === '[') { 3519 value = '^'; 3520 } 3521 3522 prev.value += value; 3523 append({ value }); 3524 continue; 3525 } 3526 3527 /** 3528 * If we're inside a quoted string, continue 3529 * until we reach the closing double quote. 3530 */ 3531 3532 if (state.quotes === 1 && value !== '"') { 3533 value = utils.escapeRegex(value); 3534 prev.value += value; 3535 append({ value }); 3536 continue; 3537 } 3538 3539 /** 3540 * Double quotes 3541 */ 3542 3543 if (value === '"') { 3544 state.quotes = state.quotes === 1 ? 0 : 1; 3545 if (opts.keepQuotes === true) { 3546 push({ type: 'text', value }); 3547 } 3548 continue; 3549 } 3550 3551 /** 3552 * Parentheses 3553 */ 3554 3555 if (value === '(') { 3556 increment('parens'); 3557 push({ type: 'paren', value }); 3558 continue; 3559 } 3560 3561 if (value === ')') { 3562 if (state.parens === 0 && opts.strictBrackets === true) { 3563 throw new SyntaxError(syntaxError('opening', '(')); 3564 } 3565 3566 const extglob = extglobs[extglobs.length - 1]; 3567 if (extglob && state.parens === extglob.parens + 1) { 3568 extglobClose(extglobs.pop()); 3569 continue; 3570 } 3571 3572 push({ type: 'paren', value, output: state.parens ? ')' : '\\)' }); 3573 decrement('parens'); 3574 continue; 3575 } 3576 3577 /** 3578 * Square brackets 3579 */ 3580 3581 if (value === '[') { 3582 if (opts.nobracket === true || !remaining().includes(']')) { 3583 if (opts.nobracket !== true && opts.strictBrackets === true) { 3584 throw new SyntaxError(syntaxError('closing', ']')); 3585 } 3586 3587 value = `\\${value}`; 3588 } else { 3589 increment('brackets'); 3590 } 3591 3592 push({ type: 'bracket', value }); 3593 continue; 3594 } 3595 3596 if (value === ']') { 3597 if (opts.nobracket === true || (prev && prev.type === 'bracket' && prev.value.length === 1)) { 3598 push({ type: 'text', value, output: `\\${value}` }); 3599 continue; 3600 } 3601 3602 if (state.brackets === 0) { 3603 if (opts.strictBrackets === true) { 3604 throw new SyntaxError(syntaxError('opening', '[')); 3605 } 3606 3607 push({ type: 'text', value, output: `\\${value}` }); 3608 continue; 3609 } 3610 3611 decrement('brackets'); 3612 3613 const prevValue = prev.value.slice(1); 3614 if (prev.posix !== true && prevValue[0] === '^' && !prevValue.includes('/')) { 3615 value = `/${value}`; 3616 } 3617 3618 prev.value += value; 3619 append({ value }); 3620 3621 // when literal brackets are explicitly disabled 3622 // assume we should match with a regex character class 3623 if (opts.literalBrackets === false || utils.hasRegexChars(prevValue)) { 3624 continue; 3625 } 3626 3627 const escaped = utils.escapeRegex(prev.value); 3628 state.output = state.output.slice(0, -prev.value.length); 3629 3630 // when literal brackets are explicitly enabled 3631 // assume we should escape the brackets to match literal characters 3632 if (opts.literalBrackets === true) { 3633 state.output += escaped; 3634 prev.value = escaped; 3635 continue; 3636 } 3637 3638 // when the user specifies nothing, try to match both 3639 prev.value = `(${capture}${escaped}|${prev.value})`; 3640 state.output += prev.value; 3641 continue; 3642 } 3643 3644 /** 3645 * Braces 3646 */ 3647 3648 if (value === '{' && opts.nobrace !== true) { 3649 increment('braces'); 3650 3651 const open = { 3652 type: 'brace', 3653 value, 3654 output: '(', 3655 outputIndex: state.output.length, 3656 tokensIndex: state.tokens.length 3657 }; 3658 3659 braces.push(open); 3660 push(open); 3661 continue; 3662 } 3663 3664 if (value === '}') { 3665 const brace = braces[braces.length - 1]; 3666 3667 if (opts.nobrace === true || !brace) { 3668 push({ type: 'text', value, output: value }); 3669 continue; 3670 } 3671 3672 let output = ')'; 3673 3674 if (brace.dots === true) { 3675 const arr = tokens.slice(); 3676 const range = []; 3677 3678 for (let i = arr.length - 1; i >= 0; i--) { 3679 tokens.pop(); 3680 if (arr[i].type === 'brace') { 3681 break; 3682 } 3683 if (arr[i].type !== 'dots') { 3684 range.unshift(arr[i].value); 3685 } 3686 } 3687 3688 output = expandRange(range, opts); 3689 state.backtrack = true; 3690 } 3691 3692 if (brace.comma !== true && brace.dots !== true) { 3693 const out = state.output.slice(0, brace.outputIndex); 3694 const toks = state.tokens.slice(brace.tokensIndex); 3695 brace.value = brace.output = '\\{'; 3696 value = output = '\\}'; 3697 state.output = out; 3698 for (const t of toks) { 3699 state.output += (t.output || t.value); 3700 } 3701 } 3702 3703 push({ type: 'brace', value, output }); 3704 decrement('braces'); 3705 braces.pop(); 3706 continue; 3707 } 3708 3709 /** 3710 * Pipes 3711 */ 3712 3713 if (value === '|') { 3714 if (extglobs.length > 0) { 3715 extglobs[extglobs.length - 1].conditions++; 3716 } 3717 push({ type: 'text', value }); 3718 continue; 3719 } 3720 3721 /** 3722 * Commas 3723 */ 3724 3725 if (value === ',') { 3726 let output = value; 3727 3728 const brace = braces[braces.length - 1]; 3729 if (brace && stack[stack.length - 1] === 'braces') { 3730 brace.comma = true; 3731 output = '|'; 3732 } 3733 3734 push({ type: 'comma', value, output }); 3735 continue; 3736 } 3737 3738 /** 3739 * Slashes 3740 */ 3741 3742 if (value === '/') { 3743 // if the beginning of the glob is "./", advance the start 3744 // to the current index, and don't add the "./" characters 3745 // to the state. This greatly simplifies lookbehinds when 3746 // checking for BOS characters like "!" and "." (not "./") 3747 if (prev.type === 'dot' && state.index === state.start + 1) { 3748 state.start = state.index + 1; 3749 state.consumed = ''; 3750 state.output = ''; 3751 tokens.pop(); 3752 prev = bos; // reset "prev" to the first token 3753 continue; 3754 } 3755 3756 push({ type: 'slash', value, output: SLASH_LITERAL }); 3757 continue; 3758 } 3759 3760 /** 3761 * Dots 3762 */ 3763 3764 if (value === '.') { 3765 if (state.braces > 0 && prev.type === 'dot') { 3766 if (prev.value === '.') prev.output = DOT_LITERAL; 3767 const brace = braces[braces.length - 1]; 3768 prev.type = 'dots'; 3769 prev.output += value; 3770 prev.value += value; 3771 brace.dots = true; 3772 continue; 3773 } 3774 3775 if ((state.braces + state.parens) === 0 && prev.type !== 'bos' && prev.type !== 'slash') { 3776 push({ type: 'text', value, output: DOT_LITERAL }); 3777 continue; 3778 } 3779 3780 push({ type: 'dot', value, output: DOT_LITERAL }); 3781 continue; 3782 } 3783 3784 /** 3785 * Question marks 3786 */ 3787 3788 if (value === '?') { 3789 const isGroup = prev && prev.value === '('; 3790 if (!isGroup && opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 3791 extglobOpen('qmark', value); 3792 continue; 3793 } 3794 3795 if (prev && prev.type === 'paren') { 3796 const next = peek(); 3797 let output = value; 3798 3799 if (next === '<' && !utils.supportsLookbehinds()) { 3800 throw new Error('Node.js v10 or higher is required for regex lookbehinds'); 3801 } 3802 3803 if ((prev.value === '(' && !/[!=<:]/.test(next)) || (next === '<' && !/<([!=]|\w+>)/.test(remaining()))) { 3804 output = `\\${value}`; 3805 } 3806 3807 push({ type: 'text', value, output }); 3808 continue; 3809 } 3810 3811 if (opts.dot !== true && (prev.type === 'slash' || prev.type === 'bos')) { 3812 push({ type: 'qmark', value, output: QMARK_NO_DOT }); 3813 continue; 3814 } 3815 3816 push({ type: 'qmark', value, output: QMARK }); 3817 continue; 3818 } 3819 3820 /** 3821 * Exclamation 3822 */ 3823 3824 if (value === '!') { 3825 if (opts.noextglob !== true && peek() === '(') { 3826 if (peek(2) !== '?' || !/[!=<:]/.test(peek(3))) { 3827 extglobOpen('negate', value); 3828 continue; 3829 } 3830 } 3831 3832 if (opts.nonegate !== true && state.index === 0) { 3833 negate(); 3834 continue; 3835 } 3836 } 3837 3838 /** 3839 * Plus 3840 */ 3841 3842 if (value === '+') { 3843 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 3844 extglobOpen('plus', value); 3845 continue; 3846 } 3847 3848 if ((prev && prev.value === '(') || opts.regex === false) { 3849 push({ type: 'plus', value, output: PLUS_LITERAL }); 3850 continue; 3851 } 3852 3853 if ((prev && (prev.type === 'bracket' || prev.type === 'paren' || prev.type === 'brace')) || state.parens > 0) { 3854 push({ type: 'plus', value }); 3855 continue; 3856 } 3857 3858 push({ type: 'plus', value: PLUS_LITERAL }); 3859 continue; 3860 } 3861 3862 /** 3863 * Plain text 3864 */ 3865 3866 if (value === '@') { 3867 if (opts.noextglob !== true && peek() === '(' && peek(2) !== '?') { 3868 push({ type: 'at', extglob: true, value, output: '' }); 3869 continue; 3870 } 3871 3872 push({ type: 'text', value }); 3873 continue; 3874 } 3875 3876 /** 3877 * Plain text 3878 */ 3879 3880 if (value !== '*') { 3881 if (value === '$' || value === '^') { 3882 value = `\\${value}`; 3883 } 3884 3885 const match = REGEX_NON_SPECIAL_CHARS.exec(remaining()); 3886 if (match) { 3887 value += match[0]; 3888 state.index += match[0].length; 3889 } 3890 3891 push({ type: 'text', value }); 3892 continue; 3893 } 3894 3895 /** 3896 * Stars 3897 */ 3898 3899 if (prev && (prev.type === 'globstar' || prev.star === true)) { 3900 prev.type = 'star'; 3901 prev.star = true; 3902 prev.value += value; 3903 prev.output = star; 3904 state.backtrack = true; 3905 state.globstar = true; 3906 consume(value); 3907 continue; 3908 } 3909 3910 let rest = remaining(); 3911 if (opts.noextglob !== true && /^\([^?]/.test(rest)) { 3912 extglobOpen('star', value); 3913 continue; 3914 } 3915 3916 if (prev.type === 'star') { 3917 if (opts.noglobstar === true) { 3918 consume(value); 3919 continue; 3920 } 3921 3922 const prior = prev.prev; 3923 const before = prior.prev; 3924 const isStart = prior.type === 'slash' || prior.type === 'bos'; 3925 const afterStar = before && (before.type === 'star' || before.type === 'globstar'); 3926 3927 if (opts.bash === true && (!isStart || (rest[0] && rest[0] !== '/'))) { 3928 push({ type: 'star', value, output: '' }); 3929 continue; 3930 } 3931 3932 const isBrace = state.braces > 0 && (prior.type === 'comma' || prior.type === 'brace'); 3933 const isExtglob = extglobs.length && (prior.type === 'pipe' || prior.type === 'paren'); 3934 if (!isStart && prior.type !== 'paren' && !isBrace && !isExtglob) { 3935 push({ type: 'star', value, output: '' }); 3936 continue; 3937 } 3938 3939 // strip consecutive `/**/` 3940 while (rest.slice(0, 3) === '/**') { 3941 const after = input[state.index + 4]; 3942 if (after && after !== '/') { 3943 break; 3944 } 3945 rest = rest.slice(3); 3946 consume('/**', 3); 3947 } 3948 3949 if (prior.type === 'bos' && eos()) { 3950 prev.type = 'globstar'; 3951 prev.value += value; 3952 prev.output = globstar(opts); 3953 state.output = prev.output; 3954 state.globstar = true; 3955 consume(value); 3956 continue; 3957 } 3958 3959 if (prior.type === 'slash' && prior.prev.type !== 'bos' && !afterStar && eos()) { 3960 state.output = state.output.slice(0, -(prior.output + prev.output).length); 3961 prior.output = `(?:${prior.output}`; 3962 3963 prev.type = 'globstar'; 3964 prev.output = globstar(opts) + (opts.strictSlashes ? ')' : '|$)'); 3965 prev.value += value; 3966 state.globstar = true; 3967 state.output += prior.output + prev.output; 3968 consume(value); 3969 continue; 3970 } 3971 3972 if (prior.type === 'slash' && prior.prev.type !== 'bos' && rest[0] === '/') { 3973 const end = rest[1] !== void 0 ? '|$' : ''; 3974 3975 state.output = state.output.slice(0, -(prior.output + prev.output).length); 3976 prior.output = `(?:${prior.output}`; 3977 3978 prev.type = 'globstar'; 3979 prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`; 3980 prev.value += value; 3981 3982 state.output += prior.output + prev.output; 3983 state.globstar = true; 3984 3985 consume(value + advance()); 3986 3987 push({ type: 'slash', value: '/', output: '' }); 3988 continue; 3989 } 3990 3991 if (prior.type === 'bos' && rest[0] === '/') { 3992 prev.type = 'globstar'; 3993 prev.value += value; 3994 prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`; 3995 state.output = prev.output; 3996 state.globstar = true; 3997 consume(value + advance()); 3998 push({ type: 'slash', value: '/', output: '' }); 3999 continue; 4000 } 4001 4002 // remove single star from output 4003 state.output = state.output.slice(0, -prev.output.length); 4004 4005 // reset previous token to globstar 4006 prev.type = 'globstar'; 4007 prev.output = globstar(opts); 4008 prev.value += value; 4009 4010 // reset output with globstar 4011 state.output += prev.output; 4012 state.globstar = true; 4013 consume(value); 4014 continue; 4015 } 4016 4017 const token = { type: 'star', value, output: star }; 4018 4019 if (opts.bash === true) { 4020 token.output = '.*?'; 4021 if (prev.type === 'bos' || prev.type === 'slash') { 4022 token.output = nodot + token.output; 4023 } 4024 push(token); 4025 continue; 4026 } 4027 4028 if (prev && (prev.type === 'bracket' || prev.type === 'paren') && opts.regex === true) { 4029 token.output = value; 4030 push(token); 4031 continue; 4032 } 4033 4034 if (state.index === state.start || prev.type === 'slash' || prev.type === 'dot') { 4035 if (prev.type === 'dot') { 4036 state.output += NO_DOT_SLASH; 4037 prev.output += NO_DOT_SLASH; 4038 4039 } else if (opts.dot === true) { 4040 state.output += NO_DOTS_SLASH; 4041 prev.output += NO_DOTS_SLASH; 4042 4043 } else { 4044 state.output += nodot; 4045 prev.output += nodot; 4046 } 4047 4048 if (peek() !== '*') { 4049 state.output += ONE_CHAR; 4050 prev.output += ONE_CHAR; 4051 } 4052 } 4053 4054 push(token); 4055 } 4056 4057 while (state.brackets > 0) { 4058 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ']')); 4059 state.output = utils.escapeLast(state.output, '['); 4060 decrement('brackets'); 4061 } 4062 4063 while (state.parens > 0) { 4064 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', ')')); 4065 state.output = utils.escapeLast(state.output, '('); 4066 decrement('parens'); 4067 } 4068 4069 while (state.braces > 0) { 4070 if (opts.strictBrackets === true) throw new SyntaxError(syntaxError('closing', '}')); 4071 state.output = utils.escapeLast(state.output, '{'); 4072 decrement('braces'); 4073 } 4074 4075 if (opts.strictSlashes !== true && (prev.type === 'star' || prev.type === 'bracket')) { 4076 push({ type: 'maybe_slash', value: '', output: `${SLASH_LITERAL}?` }); 4077 } 4078 4079 // rebuild the output if we had to backtrack at any point 4080 if (state.backtrack === true) { 4081 state.output = ''; 4082 4083 for (const token of state.tokens) { 4084 state.output += token.output != null ? token.output : token.value; 4085 4086 if (token.suffix) { 4087 state.output += token.suffix; 4088 } 4089 } 4090 } 4091 4092 return state; 4093 }; 4094 4095 /** 4096 * Fast paths for creating regular expressions for common glob patterns. 4097 * This can significantly speed up processing and has very little downside 4098 * impact when none of the fast paths match. 4099 */ 4100 4101 parse.fastpaths = (input, options) => { 4102 const opts = { ...options }; 4103 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 4104 const len = input.length; 4105 if (len > max) { 4106 throw new SyntaxError(`Input length: ${len}, exceeds maximum allowed length: ${max}`); 4107 } 4108 4109 input = REPLACEMENTS[input] || input; 4110 const win32 = utils.isWindows(options); 4111 4112 // create constants based on platform, for windows or posix 4113 const { 4114 DOT_LITERAL, 4115 SLASH_LITERAL, 4116 ONE_CHAR, 4117 DOTS_SLASH, 4118 NO_DOT, 4119 NO_DOTS, 4120 NO_DOTS_SLASH, 4121 STAR, 4122 START_ANCHOR 4123 } = constants.globChars(win32); 4124 4125 const nodot = opts.dot ? NO_DOTS : NO_DOT; 4126 const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT; 4127 const capture = opts.capture ? '' : '?:'; 4128 const state = { negated: false, prefix: '' }; 4129 let star = opts.bash === true ? '.*?' : STAR; 4130 4131 if (opts.capture) { 4132 star = `(${star})`; 4133 } 4134 4135 const globstar = opts => { 4136 if (opts.noglobstar === true) return star; 4137 return `(${capture}(?:(?!${START_ANCHOR}${opts.dot ? DOTS_SLASH : DOT_LITERAL}).)*?)`; 4138 }; 4139 4140 const create = str => { 4141 switch (str) { 4142 case '*': 4143 return `${nodot}${ONE_CHAR}${star}`; 4144 4145 case '.*': 4146 return `${DOT_LITERAL}${ONE_CHAR}${star}`; 4147 4148 case '*.*': 4149 return `${nodot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 4150 4151 case '*/*': 4152 return `${nodot}${star}${SLASH_LITERAL}${ONE_CHAR}${slashDot}${star}`; 4153 4154 case '**': 4155 return nodot + globstar(opts); 4156 4157 case '**/*': 4158 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${ONE_CHAR}${star}`; 4159 4160 case '**/*.*': 4161 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${slashDot}${star}${DOT_LITERAL}${ONE_CHAR}${star}`; 4162 4163 case '**/.*': 4164 return `(?:${nodot}${globstar(opts)}${SLASH_LITERAL})?${DOT_LITERAL}${ONE_CHAR}${star}`; 4165 4166 default: { 4167 const match = /^(.*?)\.(\w+)$/.exec(str); 4168 if (!match) return; 4169 4170 const source = create(match[1]); 4171 if (!source) return; 4172 4173 return source + DOT_LITERAL + match[2]; 4174 } 4175 } 4176 }; 4177 4178 const output = utils.removePrefix(input, state); 4179 let source = create(output); 4180 4181 if (source && opts.strictSlashes !== true) { 4182 source += `${SLASH_LITERAL}?`; 4183 } 4184 4185 return source; 4186 }; 4187 4188 parse_1$1 = parse; 4189 return parse_1$1; 4190 } 4191 4192 var picomatch_1; 4193 var hasRequiredPicomatch$1; 4194 4195 function requirePicomatch$1 () { 4196 if (hasRequiredPicomatch$1) return picomatch_1; 4197 hasRequiredPicomatch$1 = 1; 4198 4199 const path = require$$0$1; 4200 const scan = /*@__PURE__*/ requireScan(); 4201 const parse = /*@__PURE__*/ requireParse$1(); 4202 const utils = /*@__PURE__*/ requireUtils$1(); 4203 const constants = /*@__PURE__*/ requireConstants$2(); 4204 const isObject = val => val && typeof val === 'object' && !Array.isArray(val); 4205 4206 /** 4207 * Creates a matcher function from one or more glob patterns. The 4208 * returned function takes a string to match as its first argument, 4209 * and returns true if the string is a match. The returned matcher 4210 * function also takes a boolean as the second argument that, when true, 4211 * returns an object with additional information. 4212 * 4213 * ```js 4214 * const picomatch = require('picomatch'); 4215 * // picomatch(glob[, options]); 4216 * 4217 * const isMatch = picomatch('*.!(*a)'); 4218 * console.log(isMatch('a.a')); //=> false 4219 * console.log(isMatch('a.b')); //=> true 4220 * ``` 4221 * @name picomatch 4222 * @param {String|Array} `globs` One or more glob patterns. 4223 * @param {Object=} `options` 4224 * @return {Function=} Returns a matcher function. 4225 * @api public 4226 */ 4227 4228 const picomatch = (glob, options, returnState = false) => { 4229 if (Array.isArray(glob)) { 4230 const fns = glob.map(input => picomatch(input, options, returnState)); 4231 const arrayMatcher = str => { 4232 for (const isMatch of fns) { 4233 const state = isMatch(str); 4234 if (state) return state; 4235 } 4236 return false; 4237 }; 4238 return arrayMatcher; 4239 } 4240 4241 const isState = isObject(glob) && glob.tokens && glob.input; 4242 4243 if (glob === '' || (typeof glob !== 'string' && !isState)) { 4244 throw new TypeError('Expected pattern to be a non-empty string'); 4245 } 4246 4247 const opts = options || {}; 4248 const posix = utils.isWindows(options); 4249 const regex = isState 4250 ? picomatch.compileRe(glob, options) 4251 : picomatch.makeRe(glob, options, false, true); 4252 4253 const state = regex.state; 4254 delete regex.state; 4255 4256 let isIgnored = () => false; 4257 if (opts.ignore) { 4258 const ignoreOpts = { ...options, ignore: null, onMatch: null, onResult: null }; 4259 isIgnored = picomatch(opts.ignore, ignoreOpts, returnState); 4260 } 4261 4262 const matcher = (input, returnObject = false) => { 4263 const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix }); 4264 const result = { glob, state, regex, posix, input, output, match, isMatch }; 4265 4266 if (typeof opts.onResult === 'function') { 4267 opts.onResult(result); 4268 } 4269 4270 if (isMatch === false) { 4271 result.isMatch = false; 4272 return returnObject ? result : false; 4273 } 4274 4275 if (isIgnored(input)) { 4276 if (typeof opts.onIgnore === 'function') { 4277 opts.onIgnore(result); 4278 } 4279 result.isMatch = false; 4280 return returnObject ? result : false; 4281 } 4282 4283 if (typeof opts.onMatch === 'function') { 4284 opts.onMatch(result); 4285 } 4286 return returnObject ? result : true; 4287 }; 4288 4289 if (returnState) { 4290 matcher.state = state; 4291 } 4292 4293 return matcher; 4294 }; 4295 4296 /** 4297 * Test `input` with the given `regex`. This is used by the main 4298 * `picomatch()` function to test the input string. 4299 * 4300 * ```js 4301 * const picomatch = require('picomatch'); 4302 * // picomatch.test(input, regex[, options]); 4303 * 4304 * console.log(picomatch.test('foo/bar', /^(?:([^/]*?)\/([^/]*?))$/)); 4305 * // { isMatch: true, match: [ 'foo/', 'foo', 'bar' ], output: 'foo/bar' } 4306 * ``` 4307 * @param {String} `input` String to test. 4308 * @param {RegExp} `regex` 4309 * @return {Object} Returns an object with matching info. 4310 * @api public 4311 */ 4312 4313 picomatch.test = (input, regex, options, { glob, posix } = {}) => { 4314 if (typeof input !== 'string') { 4315 throw new TypeError('Expected input to be a string'); 4316 } 4317 4318 if (input === '') { 4319 return { isMatch: false, output: '' }; 4320 } 4321 4322 const opts = options || {}; 4323 const format = opts.format || (posix ? utils.toPosixSlashes : null); 4324 let match = input === glob; 4325 let output = (match && format) ? format(input) : input; 4326 4327 if (match === false) { 4328 output = format ? format(input) : input; 4329 match = output === glob; 4330 } 4331 4332 if (match === false || opts.capture === true) { 4333 if (opts.matchBase === true || opts.basename === true) { 4334 match = picomatch.matchBase(input, regex, options, posix); 4335 } else { 4336 match = regex.exec(output); 4337 } 4338 } 4339 4340 return { isMatch: Boolean(match), match, output }; 4341 }; 4342 4343 /** 4344 * Match the basename of a filepath. 4345 * 4346 * ```js 4347 * const picomatch = require('picomatch'); 4348 * // picomatch.matchBase(input, glob[, options]); 4349 * console.log(picomatch.matchBase('foo/bar.js', '*.js'); // true 4350 * ``` 4351 * @param {String} `input` String to test. 4352 * @param {RegExp|String} `glob` Glob pattern or regex created by [.makeRe](#makeRe). 4353 * @return {Boolean} 4354 * @api public 4355 */ 4356 4357 picomatch.matchBase = (input, glob, options, posix = utils.isWindows(options)) => { 4358 const regex = glob instanceof RegExp ? glob : picomatch.makeRe(glob, options); 4359 return regex.test(path.basename(input)); 4360 }; 4361 4362 /** 4363 * Returns true if **any** of the given glob `patterns` match the specified `string`. 4364 * 4365 * ```js 4366 * const picomatch = require('picomatch'); 4367 * // picomatch.isMatch(string, patterns[, options]); 4368 * 4369 * console.log(picomatch.isMatch('a.a', ['b.*', '*.a'])); //=> true 4370 * console.log(picomatch.isMatch('a.a', 'b.*')); //=> false 4371 * ``` 4372 * @param {String|Array} str The string to test. 4373 * @param {String|Array} patterns One or more glob patterns to use for matching. 4374 * @param {Object} [options] See available [options](#options). 4375 * @return {Boolean} Returns true if any patterns match `str` 4376 * @api public 4377 */ 4378 4379 picomatch.isMatch = (str, patterns, options) => picomatch(patterns, options)(str); 4380 4381 /** 4382 * Parse a glob pattern to create the source string for a regular 4383 * expression. 4384 * 4385 * ```js 4386 * const picomatch = require('picomatch'); 4387 * const result = picomatch.parse(pattern[, options]); 4388 * ``` 4389 * @param {String} `pattern` 4390 * @param {Object} `options` 4391 * @return {Object} Returns an object with useful properties and output to be used as a regex source string. 4392 * @api public 4393 */ 4394 4395 picomatch.parse = (pattern, options) => { 4396 if (Array.isArray(pattern)) return pattern.map(p => picomatch.parse(p, options)); 4397 return parse(pattern, { ...options, fastpaths: false }); 4398 }; 4399 4400 /** 4401 * Scan a glob pattern to separate the pattern into segments. 4402 * 4403 * ```js 4404 * const picomatch = require('picomatch'); 4405 * // picomatch.scan(input[, options]); 4406 * 4407 * const result = picomatch.scan('!./foo/*.js'); 4408 * console.log(result); 4409 * { prefix: '!./', 4410 * input: '!./foo/*.js', 4411 * start: 3, 4412 * base: 'foo', 4413 * glob: '*.js', 4414 * isBrace: false, 4415 * isBracket: false, 4416 * isGlob: true, 4417 * isExtglob: false, 4418 * isGlobstar: false, 4419 * negated: true } 4420 * ``` 4421 * @param {String} `input` Glob pattern to scan. 4422 * @param {Object} `options` 4423 * @return {Object} Returns an object with 4424 * @api public 4425 */ 4426 4427 picomatch.scan = (input, options) => scan(input, options); 4428 4429 /** 4430 * Compile a regular expression from the `state` object returned by the 4431 * [parse()](#parse) method. 4432 * 4433 * @param {Object} `state` 4434 * @param {Object} `options` 4435 * @param {Boolean} `returnOutput` Intended for implementors, this argument allows you to return the raw output from the parser. 4436 * @param {Boolean} `returnState` Adds the state to a `state` property on the returned regex. Useful for implementors and debugging. 4437 * @return {RegExp} 4438 * @api public 4439 */ 4440 4441 picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => { 4442 if (returnOutput === true) { 4443 return state.output; 4444 } 4445 4446 const opts = options || {}; 4447 const prepend = opts.contains ? '' : '^'; 4448 const append = opts.contains ? '' : '$'; 4449 4450 let source = `${prepend}(?:${state.output})${append}`; 4451 if (state && state.negated === true) { 4452 source = `^(?!${source}).*$`; 4453 } 4454 4455 const regex = picomatch.toRegex(source, options); 4456 if (returnState === true) { 4457 regex.state = state; 4458 } 4459 4460 return regex; 4461 }; 4462 4463 /** 4464 * Create a regular expression from a parsed glob pattern. 4465 * 4466 * ```js 4467 * const picomatch = require('picomatch'); 4468 * const state = picomatch.parse('*.js'); 4469 * // picomatch.compileRe(state[, options]); 4470 * 4471 * console.log(picomatch.compileRe(state)); 4472 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 4473 * ``` 4474 * @param {String} `state` The object returned from the `.parse` method. 4475 * @param {Object} `options` 4476 * @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. 4477 * @param {Boolean} `returnState` Implementors may use this argument to return the state from the parsed glob with the returned regular expression. 4478 * @return {RegExp} Returns a regex created from the given pattern. 4479 * @api public 4480 */ 4481 4482 picomatch.makeRe = (input, options = {}, returnOutput = false, returnState = false) => { 4483 if (!input || typeof input !== 'string') { 4484 throw new TypeError('Expected a non-empty string'); 4485 } 4486 4487 let parsed = { negated: false, fastpaths: true }; 4488 4489 if (options.fastpaths !== false && (input[0] === '.' || input[0] === '*')) { 4490 parsed.output = parse.fastpaths(input, options); 4491 } 4492 4493 if (!parsed.output) { 4494 parsed = parse(input, options); 4495 } 4496 4497 return picomatch.compileRe(parsed, options, returnOutput, returnState); 4498 }; 4499 4500 /** 4501 * Create a regular expression from the given regex source string. 4502 * 4503 * ```js 4504 * const picomatch = require('picomatch'); 4505 * // picomatch.toRegex(source[, options]); 4506 * 4507 * const { output } = picomatch.parse('*.js'); 4508 * console.log(picomatch.toRegex(output)); 4509 * //=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/ 4510 * ``` 4511 * @param {String} `source` Regular expression source string. 4512 * @param {Object} `options` 4513 * @return {RegExp} 4514 * @api public 4515 */ 4516 4517 picomatch.toRegex = (source, options) => { 4518 try { 4519 const opts = options || {}; 4520 return new RegExp(source, opts.flags || (opts.nocase ? 'i' : '')); 4521 } catch (err) { 4522 if (options && options.debug === true) throw err; 4523 return /$^/; 4524 } 4525 }; 4526 4527 /** 4528 * Picomatch constants. 4529 * @return {Object} 4530 */ 4531 4532 picomatch.constants = constants; 4533 4534 /** 4535 * Expose "picomatch" 4536 */ 4537 4538 picomatch_1 = picomatch; 4539 return picomatch_1; 4540 } 4541 4542 var picomatch; 4543 var hasRequiredPicomatch; 4544 4545 function requirePicomatch () { 4546 if (hasRequiredPicomatch) return picomatch; 4547 hasRequiredPicomatch = 1; 4548 4549 picomatch = /*@__PURE__*/ requirePicomatch$1(); 4550 return picomatch; 4551 } 315 4552 316 4553 /*! … … 321 4558 */ 322 4559 323 var normalizePath$2 = function(path, stripTrailing) { 324 if (typeof path !== 'string') { 325 throw new TypeError('expected path to be a string'); 326 } 327 328 if (path === '\\' || path === '/') return '/'; 329 330 var len = path.length; 331 if (len <= 1) return path; 332 333 // ensure that win32 namespaces has two leading slashes, so that the path is 334 // handled properly by the win32 version of path.parse() after being normalized 335 // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces 336 var prefix = ''; 337 if (len > 4 && path[3] === '\\') { 338 var ch = path[2]; 339 if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') { 340 path = path.slice(2); 341 prefix = '//'; 342 } 343 } 344 345 var segs = path.split(/[/\\]+/); 346 if (stripTrailing !== false && segs[segs.length - 1] === '') { 347 segs.pop(); 348 } 349 return prefix + segs.join('/'); 350 }; 351 352 var anymatch_1 = anymatch$2.exports; 353 354 Object.defineProperty(anymatch_1, "__esModule", { value: true }); 355 356 const picomatch = picomatch$2; 357 const normalizePath$1 = normalizePath$2; 358 359 /** 360 * @typedef {(testString: string) => boolean} AnymatchFn 361 * @typedef {string|RegExp|AnymatchFn} AnymatchPattern 362 * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher 363 */ 364 const BANG$1 = '!'; 365 const DEFAULT_OPTIONS = {returnIndex: false}; 366 const arrify$1 = (item) => Array.isArray(item) ? item : [item]; 367 368 /** 369 * @param {AnymatchPattern} matcher 370 * @param {object} options 371 * @returns {AnymatchFn} 372 */ 373 const createPattern = (matcher, options) => { 374 if (typeof matcher === 'function') { 375 return matcher; 376 } 377 if (typeof matcher === 'string') { 378 const glob = picomatch(matcher, options); 379 return (string) => matcher === string || glob(string); 380 } 381 if (matcher instanceof RegExp) { 382 return (string) => matcher.test(string); 383 } 384 return (string) => false; 385 }; 386 387 /** 388 * @param {Array<Function>} patterns 389 * @param {Array<Function>} negPatterns 390 * @param {String|Array} args 391 * @param {Boolean} returnIndex 392 * @returns {boolean|number} 393 */ 394 const matchPatterns = (patterns, negPatterns, args, returnIndex) => { 395 const isList = Array.isArray(args); 396 const _path = isList ? args[0] : args; 397 if (!isList && typeof _path !== 'string') { 398 throw new TypeError('anymatch: second argument must be a string: got ' + 399 Object.prototype.toString.call(_path)) 400 } 401 const path = normalizePath$1(_path, false); 402 403 for (let index = 0; index < negPatterns.length; index++) { 404 const nglob = negPatterns[index]; 405 if (nglob(path)) { 406 return returnIndex ? -1 : false; 407 } 408 } 409 410 const applied = isList && [path].concat(args.slice(1)); 411 for (let index = 0; index < patterns.length; index++) { 412 const pattern = patterns[index]; 413 if (isList ? pattern(...applied) : pattern(path)) { 414 return returnIndex ? index : true; 415 } 416 } 417 418 return returnIndex ? -1 : false; 419 }; 420 421 /** 422 * @param {AnymatchMatcher} matchers 423 * @param {Array|string} testString 424 * @param {object} options 425 * @returns {boolean|number|Function} 426 */ 427 const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => { 428 if (matchers == null) { 429 throw new TypeError('anymatch: specify first argument'); 430 } 431 const opts = typeof options === 'boolean' ? {returnIndex: options} : options; 432 const returnIndex = opts.returnIndex || false; 433 434 // Early cache for matchers. 435 const mtchers = arrify$1(matchers); 436 const negatedGlobs = mtchers 437 .filter(item => typeof item === 'string' && item.charAt(0) === BANG$1) 438 .map(item => item.slice(1)) 439 .map(item => picomatch(item, opts)); 440 const patterns = mtchers 441 .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG$1)) 442 .map(matcher => createPattern(matcher, opts)); 443 444 if (testString == null) { 445 return (testString, ri = false) => { 446 const returnIndex = typeof ri === 'boolean' ? ri : false; 447 return matchPatterns(patterns, negatedGlobs, testString, returnIndex); 448 } 449 } 450 451 return matchPatterns(patterns, negatedGlobs, testString, returnIndex); 452 }; 453 454 anymatch$1.default = anymatch$1; 455 anymatch$2.exports = anymatch$1; 456 457 var anymatchExports = anymatch$2.exports; 4560 var normalizePath; 4561 var hasRequiredNormalizePath; 4562 4563 function requireNormalizePath () { 4564 if (hasRequiredNormalizePath) return normalizePath; 4565 hasRequiredNormalizePath = 1; 4566 normalizePath = function(path, stripTrailing) { 4567 if (typeof path !== 'string') { 4568 throw new TypeError('expected path to be a string'); 4569 } 4570 4571 if (path === '\\' || path === '/') return '/'; 4572 4573 var len = path.length; 4574 if (len <= 1) return path; 4575 4576 // ensure that win32 namespaces has two leading slashes, so that the path is 4577 // handled properly by the win32 version of path.parse() after being normalized 4578 // https://msdn.microsoft.com/library/windows/desktop/aa365247(v=vs.85).aspx#namespaces 4579 var prefix = ''; 4580 if (len > 4 && path[3] === '\\') { 4581 var ch = path[2]; 4582 if ((ch === '?' || ch === '.') && path.slice(0, 2) === '\\\\') { 4583 path = path.slice(2); 4584 prefix = '//'; 4585 } 4586 } 4587 4588 var segs = path.split(/[/\\]+/); 4589 if (stripTrailing !== false && segs[segs.length - 1] === '') { 4590 segs.pop(); 4591 } 4592 return prefix + segs.join('/'); 4593 }; 4594 return normalizePath; 4595 } 4596 4597 var anymatch_1 = anymatch.exports; 4598 4599 var hasRequiredAnymatch; 4600 4601 function requireAnymatch () { 4602 if (hasRequiredAnymatch) return anymatch.exports; 4603 hasRequiredAnymatch = 1; 4604 4605 Object.defineProperty(anymatch_1, "__esModule", { value: true }); 4606 4607 const picomatch = /*@__PURE__*/ requirePicomatch(); 4608 const normalizePath = /*@__PURE__*/ requireNormalizePath(); 4609 4610 /** 4611 * @typedef {(testString: string) => boolean} AnymatchFn 4612 * @typedef {string|RegExp|AnymatchFn} AnymatchPattern 4613 * @typedef {AnymatchPattern|AnymatchPattern[]} AnymatchMatcher 4614 */ 4615 const BANG = '!'; 4616 const DEFAULT_OPTIONS = {returnIndex: false}; 4617 const arrify = (item) => Array.isArray(item) ? item : [item]; 4618 4619 /** 4620 * @param {AnymatchPattern} matcher 4621 * @param {object} options 4622 * @returns {AnymatchFn} 4623 */ 4624 const createPattern = (matcher, options) => { 4625 if (typeof matcher === 'function') { 4626 return matcher; 4627 } 4628 if (typeof matcher === 'string') { 4629 const glob = picomatch(matcher, options); 4630 return (string) => matcher === string || glob(string); 4631 } 4632 if (matcher instanceof RegExp) { 4633 return (string) => matcher.test(string); 4634 } 4635 return (string) => false; 4636 }; 4637 4638 /** 4639 * @param {Array<Function>} patterns 4640 * @param {Array<Function>} negPatterns 4641 * @param {String|Array} args 4642 * @param {Boolean} returnIndex 4643 * @returns {boolean|number} 4644 */ 4645 const matchPatterns = (patterns, negPatterns, args, returnIndex) => { 4646 const isList = Array.isArray(args); 4647 const _path = isList ? args[0] : args; 4648 if (!isList && typeof _path !== 'string') { 4649 throw new TypeError('anymatch: second argument must be a string: got ' + 4650 Object.prototype.toString.call(_path)) 4651 } 4652 const path = normalizePath(_path, false); 4653 4654 for (let index = 0; index < negPatterns.length; index++) { 4655 const nglob = negPatterns[index]; 4656 if (nglob(path)) { 4657 return returnIndex ? -1 : false; 4658 } 4659 } 4660 4661 const applied = isList && [path].concat(args.slice(1)); 4662 for (let index = 0; index < patterns.length; index++) { 4663 const pattern = patterns[index]; 4664 if (isList ? pattern(...applied) : pattern(path)) { 4665 return returnIndex ? index : true; 4666 } 4667 } 4668 4669 return returnIndex ? -1 : false; 4670 }; 4671 4672 /** 4673 * @param {AnymatchMatcher} matchers 4674 * @param {Array|string} testString 4675 * @param {object} options 4676 * @returns {boolean|number|Function} 4677 */ 4678 const anymatch$1 = (matchers, testString, options = DEFAULT_OPTIONS) => { 4679 if (matchers == null) { 4680 throw new TypeError('anymatch: specify first argument'); 4681 } 4682 const opts = typeof options === 'boolean' ? {returnIndex: options} : options; 4683 const returnIndex = opts.returnIndex || false; 4684 4685 // Early cache for matchers. 4686 const mtchers = arrify(matchers); 4687 const negatedGlobs = mtchers 4688 .filter(item => typeof item === 'string' && item.charAt(0) === BANG) 4689 .map(item => item.slice(1)) 4690 .map(item => picomatch(item, opts)); 4691 const patterns = mtchers 4692 .filter(item => typeof item !== 'string' || (typeof item === 'string' && item.charAt(0) !== BANG)) 4693 .map(matcher => createPattern(matcher, opts)); 4694 4695 if (testString == null) { 4696 return (testString, ri = false) => { 4697 const returnIndex = typeof ri === 'boolean' ? ri : false; 4698 return matchPatterns(patterns, negatedGlobs, testString, returnIndex); 4699 } 4700 } 4701 4702 return matchPatterns(patterns, negatedGlobs, testString, returnIndex); 4703 }; 4704 4705 anymatch$1.default = anymatch$1; 4706 anymatch.exports = anymatch$1; 4707 return anymatch.exports; 4708 } 458 4709 459 4710 /*! … … 464 4715 */ 465 4716 466 var isExtglob$1 = function isExtglob(str) { 467 if (typeof str !== 'string' || str === '') { 468 return false; 469 } 470 471 var match; 472 while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { 473 if (match[2]) return true; 474 str = str.slice(match.index + match[0].length); 475 } 476 477 return false; 478 }; 4717 var isExtglob; 4718 var hasRequiredIsExtglob; 4719 4720 function requireIsExtglob () { 4721 if (hasRequiredIsExtglob) return isExtglob; 4722 hasRequiredIsExtglob = 1; 4723 isExtglob = function isExtglob(str) { 4724 if (typeof str !== 'string' || str === '') { 4725 return false; 4726 } 4727 4728 var match; 4729 while ((match = /(\\).|([@?!+*]\(.*\))/g.exec(str))) { 4730 if (match[2]) return true; 4731 str = str.slice(match.index + match[0].length); 4732 } 4733 4734 return false; 4735 }; 4736 return isExtglob; 4737 } 479 4738 480 4739 /*! … … 485 4744 */ 486 4745 487 var isExtglob = isExtglob$1; 488 var chars = { '{': '}', '(': ')', '[': ']'}; 489 var strictCheck = function(str) { 490 if (str[0] === '!') { 491 return true; 492 } 493 var index = 0; 494 var pipeIndex = -2; 495 var closeSquareIndex = -2; 496 var closeCurlyIndex = -2; 497 var closeParenIndex = -2; 498 var backSlashIndex = -2; 499 while (index < str.length) { 500 if (str[index] === '*') { 501 return true; 502 } 503 504 if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) { 505 return true; 506 } 507 508 if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') { 509 if (closeSquareIndex < index) { 510 closeSquareIndex = str.indexOf(']', index); 511 } 512 if (closeSquareIndex > index) { 513 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { 514 return true; 515 } 516 backSlashIndex = str.indexOf('\\', index); 517 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { 518 return true; 519 } 520 } 521 } 522 523 if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') { 524 closeCurlyIndex = str.indexOf('}', index); 525 if (closeCurlyIndex > index) { 526 backSlashIndex = str.indexOf('\\', index); 527 if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) { 528 return true; 529 } 530 } 531 } 532 533 if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') { 534 closeParenIndex = str.indexOf(')', index); 535 if (closeParenIndex > index) { 536 backSlashIndex = str.indexOf('\\', index); 537 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { 538 return true; 539 } 540 } 541 } 542 543 if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') { 544 if (pipeIndex < index) { 545 pipeIndex = str.indexOf('|', index); 546 } 547 if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') { 548 closeParenIndex = str.indexOf(')', pipeIndex); 549 if (closeParenIndex > pipeIndex) { 550 backSlashIndex = str.indexOf('\\', pipeIndex); 551 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { 552 return true; 553 } 554 } 555 } 556 } 557 558 if (str[index] === '\\') { 559 var open = str[index + 1]; 560 index += 2; 561 var close = chars[open]; 562 563 if (close) { 564 var n = str.indexOf(close, index); 565 if (n !== -1) { 566 index = n + 1; 567 } 568 } 569 570 if (str[index] === '!') { 571 return true; 572 } 573 } else { 574 index++; 575 } 576 } 577 return false; 578 }; 579 580 var relaxedCheck = function(str) { 581 if (str[0] === '!') { 582 return true; 583 } 584 var index = 0; 585 while (index < str.length) { 586 if (/[*?{}()[\]]/.test(str[index])) { 587 return true; 588 } 589 590 if (str[index] === '\\') { 591 var open = str[index + 1]; 592 index += 2; 593 var close = chars[open]; 594 595 if (close) { 596 var n = str.indexOf(close, index); 597 if (n !== -1) { 598 index = n + 1; 599 } 600 } 601 602 if (str[index] === '!') { 603 return true; 604 } 605 } else { 606 index++; 607 } 608 } 609 return false; 610 }; 611 612 var isGlob$2 = function isGlob(str, options) { 613 if (typeof str !== 'string' || str === '') { 614 return false; 615 } 616 617 if (isExtglob(str)) { 618 return true; 619 } 620 621 var check = strictCheck; 622 623 // optionally relax check 624 if (options && options.strict === false) { 625 check = relaxedCheck; 626 } 627 628 return check(str); 629 }; 630 631 var isGlob$1 = isGlob$2; 632 var pathPosixDirname = require$$0$2.posix.dirname; 633 var isWin32 = require$$2$1.platform() === 'win32'; 634 635 var slash = '/'; 636 var backslash = /\\/g; 637 var enclosure = /[\{\[].*[\}\]]$/; 638 var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; 639 var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; 640 641 /** 642 * @param {string} str 643 * @param {Object} opts 644 * @param {boolean} [opts.flipBackslashes=true] 645 * @returns {string} 646 */ 647 var globParent$1 = function globParent(str, opts) { 648 var options = Object.assign({ flipBackslashes: true }, opts); 649 650 // flip windows path separators 651 if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { 652 str = str.replace(backslash, slash); 653 } 654 655 // special case for strings ending in enclosure containing path separator 656 if (enclosure.test(str)) { 657 str += slash; 658 } 659 660 // preserves full path in case of trailing path separator 661 str += 'a'; 662 663 // remove path parts that are globby 664 do { 665 str = pathPosixDirname(str); 666 } while (isGlob$1(str) || globby.test(str)); 667 668 // remove escape chars and return result 669 return str.replace(escaped, '$1'); 670 }; 671 672 var utils$3 = {}; 673 674 (function (exports) { 675 676 exports.isInteger = num => { 677 if (typeof num === 'number') { 678 return Number.isInteger(num); 679 } 680 if (typeof num === 'string' && num.trim() !== '') { 681 return Number.isInteger(Number(num)); 4746 var isGlob; 4747 var hasRequiredIsGlob; 4748 4749 function requireIsGlob () { 4750 if (hasRequiredIsGlob) return isGlob; 4751 hasRequiredIsGlob = 1; 4752 var isExtglob = /*@__PURE__*/ requireIsExtglob(); 4753 var chars = { '{': '}', '(': ')', '[': ']'}; 4754 var strictCheck = function(str) { 4755 if (str[0] === '!') { 4756 return true; 4757 } 4758 var index = 0; 4759 var pipeIndex = -2; 4760 var closeSquareIndex = -2; 4761 var closeCurlyIndex = -2; 4762 var closeParenIndex = -2; 4763 var backSlashIndex = -2; 4764 while (index < str.length) { 4765 if (str[index] === '*') { 4766 return true; 4767 } 4768 4769 if (str[index + 1] === '?' && /[\].+)]/.test(str[index])) { 4770 return true; 4771 } 4772 4773 if (closeSquareIndex !== -1 && str[index] === '[' && str[index + 1] !== ']') { 4774 if (closeSquareIndex < index) { 4775 closeSquareIndex = str.indexOf(']', index); 4776 } 4777 if (closeSquareIndex > index) { 4778 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { 4779 return true; 4780 } 4781 backSlashIndex = str.indexOf('\\', index); 4782 if (backSlashIndex === -1 || backSlashIndex > closeSquareIndex) { 4783 return true; 4784 } 4785 } 4786 } 4787 4788 if (closeCurlyIndex !== -1 && str[index] === '{' && str[index + 1] !== '}') { 4789 closeCurlyIndex = str.indexOf('}', index); 4790 if (closeCurlyIndex > index) { 4791 backSlashIndex = str.indexOf('\\', index); 4792 if (backSlashIndex === -1 || backSlashIndex > closeCurlyIndex) { 4793 return true; 4794 } 4795 } 4796 } 4797 4798 if (closeParenIndex !== -1 && str[index] === '(' && str[index + 1] === '?' && /[:!=]/.test(str[index + 2]) && str[index + 3] !== ')') { 4799 closeParenIndex = str.indexOf(')', index); 4800 if (closeParenIndex > index) { 4801 backSlashIndex = str.indexOf('\\', index); 4802 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { 4803 return true; 4804 } 4805 } 4806 } 4807 4808 if (pipeIndex !== -1 && str[index] === '(' && str[index + 1] !== '|') { 4809 if (pipeIndex < index) { 4810 pipeIndex = str.indexOf('|', index); 4811 } 4812 if (pipeIndex !== -1 && str[pipeIndex + 1] !== ')') { 4813 closeParenIndex = str.indexOf(')', pipeIndex); 4814 if (closeParenIndex > pipeIndex) { 4815 backSlashIndex = str.indexOf('\\', pipeIndex); 4816 if (backSlashIndex === -1 || backSlashIndex > closeParenIndex) { 4817 return true; 4818 } 4819 } 4820 } 4821 } 4822 4823 if (str[index] === '\\') { 4824 var open = str[index + 1]; 4825 index += 2; 4826 var close = chars[open]; 4827 4828 if (close) { 4829 var n = str.indexOf(close, index); 4830 if (n !== -1) { 4831 index = n + 1; 4832 } 4833 } 4834 4835 if (str[index] === '!') { 4836 return true; 4837 } 4838 } else { 4839 index++; 4840 } 682 4841 } 683 4842 return false; 684 4843 }; 685 4844 686 /** 687 * Find a node of the given type 688 */ 689 690 exports.find = (node, type) => node.nodes.find(node => node.type === type); 691 692 /** 693 * Find a node of the given type 694 */ 695 696 exports.exceedsLimit = (min, max, step = 1, limit) => { 697 if (limit === false) return false; 698 if (!exports.isInteger(min) || !exports.isInteger(max)) return false; 699 return ((Number(max) - Number(min)) / Number(step)) >= limit; 700 }; 701 702 /** 703 * Escape the given node with '\\' before node.value 704 */ 705 706 exports.escapeNode = (block, n = 0, type) => { 707 const node = block.nodes[n]; 708 if (!node) return; 709 710 if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { 711 if (node.escaped !== true) { 712 node.value = '\\' + node.value; 713 node.escaped = true; 714 } 715 } 716 }; 717 718 /** 719 * Returns true if the given brace node should be enclosed in literal braces 720 */ 721 722 exports.encloseBrace = node => { 723 if (node.type !== 'brace') return false; 724 if ((node.commas >> 0 + node.ranges >> 0) === 0) { 725 node.invalid = true; 4845 var relaxedCheck = function(str) { 4846 if (str[0] === '!') { 726 4847 return true; 4848 } 4849 var index = 0; 4850 while (index < str.length) { 4851 if (/[*?{}()[\]]/.test(str[index])) { 4852 return true; 4853 } 4854 4855 if (str[index] === '\\') { 4856 var open = str[index + 1]; 4857 index += 2; 4858 var close = chars[open]; 4859 4860 if (close) { 4861 var n = str.indexOf(close, index); 4862 if (n !== -1) { 4863 index = n + 1; 4864 } 4865 } 4866 4867 if (str[index] === '!') { 4868 return true; 4869 } 4870 } else { 4871 index++; 4872 } 727 4873 } 728 4874 return false; 729 4875 }; 730 4876 731 /** 732 * Returns true if a brace node is invalid. 733 */ 734 735 exports.isInvalidBrace = block => { 736 if (block.type !== 'brace') return false; 737 if (block.invalid === true || block.dollar) return true; 738 if ((block.commas >> 0 + block.ranges >> 0) === 0) { 739 block.invalid = true; 4877 isGlob = function isGlob(str, options) { 4878 if (typeof str !== 'string' || str === '') { 4879 return false; 4880 } 4881 4882 if (isExtglob(str)) { 740 4883 return true; 741 4884 } 742 if (block.open !== true || block.close !== true) { 743 block.invalid = true; 744 return true; 745 } 746 return false; 4885 4886 var check = strictCheck; 4887 4888 // optionally relax check 4889 if (options && options.strict === false) { 4890 check = relaxedCheck; 4891 } 4892 4893 return check(str); 747 4894 }; 748 749 /** 750 * Returns true if a node is an open or close node 751 */ 752 753 exports.isOpenOrClose = node => { 754 if (node.type === 'open' || node.type === 'close') { 755 return true; 756 } 757 return node.open === true || node.close === true; 4895 return isGlob; 4896 } 4897 4898 var globParent; 4899 var hasRequiredGlobParent; 4900 4901 function requireGlobParent () { 4902 if (hasRequiredGlobParent) return globParent; 4903 hasRequiredGlobParent = 1; 4904 4905 var isGlob = /*@__PURE__*/ requireIsGlob(); 4906 var pathPosixDirname = require$$0$1.posix.dirname; 4907 var isWin32 = require$$2$1.platform() === 'win32'; 4908 4909 var slash = '/'; 4910 var backslash = /\\/g; 4911 var enclosure = /[\{\[].*[\}\]]$/; 4912 var globby = /(^|[^\\])([\{\[]|\([^\)]+$)/; 4913 var escaped = /\\([\!\*\?\|\[\]\(\)\{\}])/g; 4914 4915 /** 4916 * @param {string} str 4917 * @param {Object} opts 4918 * @param {boolean} [opts.flipBackslashes=true] 4919 * @returns {string} 4920 */ 4921 globParent = function globParent(str, opts) { 4922 var options = Object.assign({ flipBackslashes: true }, opts); 4923 4924 // flip windows path separators 4925 if (options.flipBackslashes && isWin32 && str.indexOf(slash) < 0) { 4926 str = str.replace(backslash, slash); 4927 } 4928 4929 // special case for strings ending in enclosure containing path separator 4930 if (enclosure.test(str)) { 4931 str += slash; 4932 } 4933 4934 // preserves full path in case of trailing path separator 4935 str += 'a'; 4936 4937 // remove path parts that are globby 4938 do { 4939 str = pathPosixDirname(str); 4940 } while (isGlob(str) || globby.test(str)); 4941 4942 // remove escape chars and return result 4943 return str.replace(escaped, '$1'); 758 4944 }; 759 760 /** 761 * Reduce an array of text nodes. 762 */ 763 764 exports.reduce = nodes => nodes.reduce((acc, node) => { 765 if (node.type === 'text') acc.push(node.value); 766 if (node.type === 'range') node.type = 'text'; 767 return acc; 768 }, []); 769 770 /** 771 * Flatten an array 772 */ 773 774 exports.flatten = (...args) => { 775 const result = []; 776 777 const flat = arr => { 778 for (let i = 0; i < arr.length; i++) { 779 const ele = arr[i]; 780 781 if (Array.isArray(ele)) { 782 flat(ele); 783 continue; 784 } 785 786 if (ele !== undefined) { 787 result.push(ele); 788 } 789 } 790 return result; 4945 return globParent; 4946 } 4947 4948 var utils = {}; 4949 4950 var hasRequiredUtils; 4951 4952 function requireUtils () { 4953 if (hasRequiredUtils) return utils; 4954 hasRequiredUtils = 1; 4955 (function (exports) { 4956 4957 exports.isInteger = num => { 4958 if (typeof num === 'number') { 4959 return Number.isInteger(num); 4960 } 4961 if (typeof num === 'string' && num.trim() !== '') { 4962 return Number.isInteger(Number(num)); 4963 } 4964 return false; 4965 }; 4966 4967 /** 4968 * Find a node of the given type 4969 */ 4970 4971 exports.find = (node, type) => node.nodes.find(node => node.type === type); 4972 4973 /** 4974 * Find a node of the given type 4975 */ 4976 4977 exports.exceedsLimit = (min, max, step = 1, limit) => { 4978 if (limit === false) return false; 4979 if (!exports.isInteger(min) || !exports.isInteger(max)) return false; 4980 return ((Number(max) - Number(min)) / Number(step)) >= limit; 4981 }; 4982 4983 /** 4984 * Escape the given node with '\\' before node.value 4985 */ 4986 4987 exports.escapeNode = (block, n = 0, type) => { 4988 const node = block.nodes[n]; 4989 if (!node) return; 4990 4991 if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { 4992 if (node.escaped !== true) { 4993 node.value = '\\' + node.value; 4994 node.escaped = true; 4995 } 4996 } 4997 }; 4998 4999 /** 5000 * Returns true if the given brace node should be enclosed in literal braces 5001 */ 5002 5003 exports.encloseBrace = node => { 5004 if (node.type !== 'brace') return false; 5005 if ((node.commas >> 0 + node.ranges >> 0) === 0) { 5006 node.invalid = true; 5007 return true; 5008 } 5009 return false; 5010 }; 5011 5012 /** 5013 * Returns true if a brace node is invalid. 5014 */ 5015 5016 exports.isInvalidBrace = block => { 5017 if (block.type !== 'brace') return false; 5018 if (block.invalid === true || block.dollar) return true; 5019 if ((block.commas >> 0 + block.ranges >> 0) === 0) { 5020 block.invalid = true; 5021 return true; 5022 } 5023 if (block.open !== true || block.close !== true) { 5024 block.invalid = true; 5025 return true; 5026 } 5027 return false; 5028 }; 5029 5030 /** 5031 * Returns true if a node is an open or close node 5032 */ 5033 5034 exports.isOpenOrClose = node => { 5035 if (node.type === 'open' || node.type === 'close') { 5036 return true; 5037 } 5038 return node.open === true || node.close === true; 5039 }; 5040 5041 /** 5042 * Reduce an array of text nodes. 5043 */ 5044 5045 exports.reduce = nodes => nodes.reduce((acc, node) => { 5046 if (node.type === 'text') acc.push(node.value); 5047 if (node.type === 'range') node.type = 'text'; 5048 return acc; 5049 }, []); 5050 5051 /** 5052 * Flatten an array 5053 */ 5054 5055 exports.flatten = (...args) => { 5056 const result = []; 5057 5058 const flat = arr => { 5059 for (let i = 0; i < arr.length; i++) { 5060 const ele = arr[i]; 5061 5062 if (Array.isArray(ele)) { 5063 flat(ele); 5064 continue; 5065 } 5066 5067 if (ele !== undefined) { 5068 result.push(ele); 5069 } 5070 } 5071 return result; 5072 }; 5073 5074 flat(args); 5075 return result; 5076 }; 5077 } (utils)); 5078 return utils; 5079 } 5080 5081 var stringify; 5082 var hasRequiredStringify; 5083 5084 function requireStringify () { 5085 if (hasRequiredStringify) return stringify; 5086 hasRequiredStringify = 1; 5087 5088 const utils = /*@__PURE__*/ requireUtils(); 5089 5090 stringify = (ast, options = {}) => { 5091 const stringify = (node, parent = {}) => { 5092 const invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); 5093 const invalidNode = node.invalid === true && options.escapeInvalid === true; 5094 let output = ''; 5095 5096 if (node.value) { 5097 if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { 5098 return '\\' + node.value; 5099 } 5100 return node.value; 5101 } 5102 5103 if (node.value) { 5104 return node.value; 5105 } 5106 5107 if (node.nodes) { 5108 for (const child of node.nodes) { 5109 output += stringify(child); 5110 } 5111 } 5112 return output; 791 5113 }; 792 5114 793 flat(args); 794 return result; 795 }; 796 } (utils$3)); 797 798 const utils$2 = utils$3; 799 800 var stringify$4 = (ast, options = {}) => { 801 const stringify = (node, parent = {}) => { 802 const invalidBlock = options.escapeInvalid && utils$2.isInvalidBrace(parent); 803 const invalidNode = node.invalid === true && options.escapeInvalid === true; 804 let output = ''; 805 806 if (node.value) { 807 if ((invalidBlock || invalidNode) && utils$2.isOpenOrClose(node)) { 808 return '\\' + node.value; 809 } 810 return node.value; 811 } 812 813 if (node.value) { 814 return node.value; 815 } 816 817 if (node.nodes) { 818 for (const child of node.nodes) { 819 output += stringify(child); 820 } 821 } 822 return output; 823 }; 824 825 return stringify(ast); 826 }; 5115 return stringify(ast); 5116 }; 5117 return stringify; 5118 } 827 5119 828 5120 /*! … … 833 5125 */ 834 5126 835 var isNumber$2 = function(num) { 836 if (typeof num === 'number') { 837 return num - num === 0; 838 } 839 if (typeof num === 'string' && num.trim() !== '') { 840 return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); 841 } 842 return false; 843 }; 5127 var isNumber; 5128 var hasRequiredIsNumber; 5129 5130 function requireIsNumber () { 5131 if (hasRequiredIsNumber) return isNumber; 5132 hasRequiredIsNumber = 1; 5133 5134 isNumber = function(num) { 5135 if (typeof num === 'number') { 5136 return num - num === 0; 5137 } 5138 if (typeof num === 'string' && num.trim() !== '') { 5139 return Number.isFinite ? Number.isFinite(+num) : isFinite(+num); 5140 } 5141 return false; 5142 }; 5143 return isNumber; 5144 } 844 5145 845 5146 /*! … … 850 5151 */ 851 5152 852 const isNumber$1 = isNumber$2; 853 854 const toRegexRange$1 = (min, max, options) => { 855 if (isNumber$1(min) === false) { 856 throw new TypeError('toRegexRange: expected the first argument to be a number'); 857 } 858 859 if (max === void 0 || min === max) { 860 return String(min); 861 } 862 863 if (isNumber$1(max) === false) { 864 throw new TypeError('toRegexRange: expected the second argument to be a number.'); 865 } 866 867 let opts = { relaxZeros: true, ...options }; 868 if (typeof opts.strictZeros === 'boolean') { 869 opts.relaxZeros = opts.strictZeros === false; 870 } 871 872 let relax = String(opts.relaxZeros); 873 let shorthand = String(opts.shorthand); 874 let capture = String(opts.capture); 875 let wrap = String(opts.wrap); 876 let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; 877 878 if (toRegexRange$1.cache.hasOwnProperty(cacheKey)) { 879 return toRegexRange$1.cache[cacheKey].result; 880 } 881 882 let a = Math.min(min, max); 883 let b = Math.max(min, max); 884 885 if (Math.abs(a - b) === 1) { 886 let result = min + '|' + max; 887 if (opts.capture) { 888 return `(${result})`; 889 } 890 if (opts.wrap === false) { 891 return result; 892 } 893 return `(?:${result})`; 894 } 895 896 let isPadded = hasPadding(min) || hasPadding(max); 897 let state = { min, max, a, b }; 898 let positives = []; 899 let negatives = []; 900 901 if (isPadded) { 902 state.isPadded = isPadded; 903 state.maxLen = String(state.max).length; 904 } 905 906 if (a < 0) { 907 let newMin = b < 0 ? Math.abs(b) : 1; 908 negatives = splitToPatterns(newMin, Math.abs(a), state, opts); 909 a = state.a = 0; 910 } 911 912 if (b >= 0) { 913 positives = splitToPatterns(a, b, state, opts); 914 } 915 916 state.negatives = negatives; 917 state.positives = positives; 918 state.result = collatePatterns(negatives, positives); 919 920 if (opts.capture === true) { 921 state.result = `(${state.result})`; 922 } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { 923 state.result = `(?:${state.result})`; 924 } 925 926 toRegexRange$1.cache[cacheKey] = state; 927 return state.result; 928 }; 929 930 function collatePatterns(neg, pos, options) { 931 let onlyNegative = filterPatterns(neg, pos, '-', false) || []; 932 let onlyPositive = filterPatterns(pos, neg, '', false) || []; 933 let intersected = filterPatterns(neg, pos, '-?', true) || []; 934 let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); 935 return subpatterns.join('|'); 5153 var toRegexRange_1; 5154 var hasRequiredToRegexRange; 5155 5156 function requireToRegexRange () { 5157 if (hasRequiredToRegexRange) return toRegexRange_1; 5158 hasRequiredToRegexRange = 1; 5159 5160 const isNumber = /*@__PURE__*/ requireIsNumber(); 5161 5162 const toRegexRange = (min, max, options) => { 5163 if (isNumber(min) === false) { 5164 throw new TypeError('toRegexRange: expected the first argument to be a number'); 5165 } 5166 5167 if (max === void 0 || min === max) { 5168 return String(min); 5169 } 5170 5171 if (isNumber(max) === false) { 5172 throw new TypeError('toRegexRange: expected the second argument to be a number.'); 5173 } 5174 5175 let opts = { relaxZeros: true, ...options }; 5176 if (typeof opts.strictZeros === 'boolean') { 5177 opts.relaxZeros = opts.strictZeros === false; 5178 } 5179 5180 let relax = String(opts.relaxZeros); 5181 let shorthand = String(opts.shorthand); 5182 let capture = String(opts.capture); 5183 let wrap = String(opts.wrap); 5184 let cacheKey = min + ':' + max + '=' + relax + shorthand + capture + wrap; 5185 5186 if (toRegexRange.cache.hasOwnProperty(cacheKey)) { 5187 return toRegexRange.cache[cacheKey].result; 5188 } 5189 5190 let a = Math.min(min, max); 5191 let b = Math.max(min, max); 5192 5193 if (Math.abs(a - b) === 1) { 5194 let result = min + '|' + max; 5195 if (opts.capture) { 5196 return `(${result})`; 5197 } 5198 if (opts.wrap === false) { 5199 return result; 5200 } 5201 return `(?:${result})`; 5202 } 5203 5204 let isPadded = hasPadding(min) || hasPadding(max); 5205 let state = { min, max, a, b }; 5206 let positives = []; 5207 let negatives = []; 5208 5209 if (isPadded) { 5210 state.isPadded = isPadded; 5211 state.maxLen = String(state.max).length; 5212 } 5213 5214 if (a < 0) { 5215 let newMin = b < 0 ? Math.abs(b) : 1; 5216 negatives = splitToPatterns(newMin, Math.abs(a), state, opts); 5217 a = state.a = 0; 5218 } 5219 5220 if (b >= 0) { 5221 positives = splitToPatterns(a, b, state, opts); 5222 } 5223 5224 state.negatives = negatives; 5225 state.positives = positives; 5226 state.result = collatePatterns(negatives, positives); 5227 5228 if (opts.capture === true) { 5229 state.result = `(${state.result})`; 5230 } else if (opts.wrap !== false && (positives.length + negatives.length) > 1) { 5231 state.result = `(?:${state.result})`; 5232 } 5233 5234 toRegexRange.cache[cacheKey] = state; 5235 return state.result; 5236 }; 5237 5238 function collatePatterns(neg, pos, options) { 5239 let onlyNegative = filterPatterns(neg, pos, '-', false) || []; 5240 let onlyPositive = filterPatterns(pos, neg, '', false) || []; 5241 let intersected = filterPatterns(neg, pos, '-?', true) || []; 5242 let subpatterns = onlyNegative.concat(intersected).concat(onlyPositive); 5243 return subpatterns.join('|'); 5244 } 5245 5246 function splitToRanges(min, max) { 5247 let nines = 1; 5248 let zeros = 1; 5249 5250 let stop = countNines(min, nines); 5251 let stops = new Set([max]); 5252 5253 while (min <= stop && stop <= max) { 5254 stops.add(stop); 5255 nines += 1; 5256 stop = countNines(min, nines); 5257 } 5258 5259 stop = countZeros(max + 1, zeros) - 1; 5260 5261 while (min < stop && stop <= max) { 5262 stops.add(stop); 5263 zeros += 1; 5264 stop = countZeros(max + 1, zeros) - 1; 5265 } 5266 5267 stops = [...stops]; 5268 stops.sort(compare); 5269 return stops; 5270 } 5271 5272 /** 5273 * Convert a range to a regex pattern 5274 * @param {Number} `start` 5275 * @param {Number} `stop` 5276 * @return {String} 5277 */ 5278 5279 function rangeToPattern(start, stop, options) { 5280 if (start === stop) { 5281 return { pattern: start, count: [], digits: 0 }; 5282 } 5283 5284 let zipped = zip(start, stop); 5285 let digits = zipped.length; 5286 let pattern = ''; 5287 let count = 0; 5288 5289 for (let i = 0; i < digits; i++) { 5290 let [startDigit, stopDigit] = zipped[i]; 5291 5292 if (startDigit === stopDigit) { 5293 pattern += startDigit; 5294 5295 } else if (startDigit !== '0' || stopDigit !== '9') { 5296 pattern += toCharacterClass(startDigit, stopDigit); 5297 5298 } else { 5299 count++; 5300 } 5301 } 5302 5303 if (count) { 5304 pattern += options.shorthand === true ? '\\d' : '[0-9]'; 5305 } 5306 5307 return { pattern, count: [count], digits }; 5308 } 5309 5310 function splitToPatterns(min, max, tok, options) { 5311 let ranges = splitToRanges(min, max); 5312 let tokens = []; 5313 let start = min; 5314 let prev; 5315 5316 for (let i = 0; i < ranges.length; i++) { 5317 let max = ranges[i]; 5318 let obj = rangeToPattern(String(start), String(max), options); 5319 let zeros = ''; 5320 5321 if (!tok.isPadded && prev && prev.pattern === obj.pattern) { 5322 if (prev.count.length > 1) { 5323 prev.count.pop(); 5324 } 5325 5326 prev.count.push(obj.count[0]); 5327 prev.string = prev.pattern + toQuantifier(prev.count); 5328 start = max + 1; 5329 continue; 5330 } 5331 5332 if (tok.isPadded) { 5333 zeros = padZeros(max, tok, options); 5334 } 5335 5336 obj.string = zeros + obj.pattern + toQuantifier(obj.count); 5337 tokens.push(obj); 5338 start = max + 1; 5339 prev = obj; 5340 } 5341 5342 return tokens; 5343 } 5344 5345 function filterPatterns(arr, comparison, prefix, intersection, options) { 5346 let result = []; 5347 5348 for (let ele of arr) { 5349 let { string } = ele; 5350 5351 // only push if _both_ are negative... 5352 if (!intersection && !contains(comparison, 'string', string)) { 5353 result.push(prefix + string); 5354 } 5355 5356 // or _both_ are positive 5357 if (intersection && contains(comparison, 'string', string)) { 5358 result.push(prefix + string); 5359 } 5360 } 5361 return result; 5362 } 5363 5364 /** 5365 * Zip strings 5366 */ 5367 5368 function zip(a, b) { 5369 let arr = []; 5370 for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]); 5371 return arr; 5372 } 5373 5374 function compare(a, b) { 5375 return a > b ? 1 : b > a ? -1 : 0; 5376 } 5377 5378 function contains(arr, key, val) { 5379 return arr.some(ele => ele[key] === val); 5380 } 5381 5382 function countNines(min, len) { 5383 return Number(String(min).slice(0, -len) + '9'.repeat(len)); 5384 } 5385 5386 function countZeros(integer, zeros) { 5387 return integer - (integer % Math.pow(10, zeros)); 5388 } 5389 5390 function toQuantifier(digits) { 5391 let [start = 0, stop = ''] = digits; 5392 if (stop || start > 1) { 5393 return `{${start + (stop ? ',' + stop : '')}}`; 5394 } 5395 return ''; 5396 } 5397 5398 function toCharacterClass(a, b, options) { 5399 return `[${a}${(b - a === 1) ? '' : '-'}${b}]`; 5400 } 5401 5402 function hasPadding(str) { 5403 return /^-?(0+)\d/.test(str); 5404 } 5405 5406 function padZeros(value, tok, options) { 5407 if (!tok.isPadded) { 5408 return value; 5409 } 5410 5411 let diff = Math.abs(tok.maxLen - String(value).length); 5412 let relax = options.relaxZeros !== false; 5413 5414 switch (diff) { 5415 case 0: 5416 return ''; 5417 case 1: 5418 return relax ? '0?' : '0'; 5419 case 2: 5420 return relax ? '0{0,2}' : '00'; 5421 default: { 5422 return relax ? `0{0,${diff}}` : `0{${diff}}`; 5423 } 5424 } 5425 } 5426 5427 /** 5428 * Cache 5429 */ 5430 5431 toRegexRange.cache = {}; 5432 toRegexRange.clearCache = () => (toRegexRange.cache = {}); 5433 5434 /** 5435 * Expose `toRegexRange` 5436 */ 5437 5438 toRegexRange_1 = toRegexRange; 5439 return toRegexRange_1; 936 5440 } 937 938 function splitToRanges(min, max) {939 let nines = 1;940 let zeros = 1;941 942 let stop = countNines(min, nines);943 let stops = new Set([max]);944 945 while (min <= stop && stop <= max) {946 stops.add(stop);947 nines += 1;948 stop = countNines(min, nines);949 }950 951 stop = countZeros(max + 1, zeros) - 1;952 953 while (min < stop && stop <= max) {954 stops.add(stop);955 zeros += 1;956 stop = countZeros(max + 1, zeros) - 1;957 }958 959 stops = [...stops];960 stops.sort(compare);961 return stops;962 }963 964 /**965 * Convert a range to a regex pattern966 * @param {Number} `start`967 * @param {Number} `stop`968 * @return {String}969 */970 971 function rangeToPattern(start, stop, options) {972 if (start === stop) {973 return { pattern: start, count: [], digits: 0 };974 }975 976 let zipped = zip(start, stop);977 let digits = zipped.length;978 let pattern = '';979 let count = 0;980 981 for (let i = 0; i < digits; i++) {982 let [startDigit, stopDigit] = zipped[i];983 984 if (startDigit === stopDigit) {985 pattern += startDigit;986 987 } else if (startDigit !== '0' || stopDigit !== '9') {988 pattern += toCharacterClass(startDigit, stopDigit);989 990 } else {991 count++;992 }993 }994 995 if (count) {996 pattern += options.shorthand === true ? '\\d' : '[0-9]';997 }998 999 return { pattern, count: [count], digits };1000 }1001 1002 function splitToPatterns(min, max, tok, options) {1003 let ranges = splitToRanges(min, max);1004 let tokens = [];1005 let start = min;1006 let prev;1007 1008 for (let i = 0; i < ranges.length; i++) {1009 let max = ranges[i];1010 let obj = rangeToPattern(String(start), String(max), options);1011 let zeros = '';1012 1013 if (!tok.isPadded && prev && prev.pattern === obj.pattern) {1014 if (prev.count.length > 1) {1015 prev.count.pop();1016 }1017 1018 prev.count.push(obj.count[0]);1019 prev.string = prev.pattern + toQuantifier(prev.count);1020 start = max + 1;1021 continue;1022 }1023 1024 if (tok.isPadded) {1025 zeros = padZeros(max, tok, options);1026 }1027 1028 obj.string = zeros + obj.pattern + toQuantifier(obj.count);1029 tokens.push(obj);1030 start = max + 1;1031 prev = obj;1032 }1033 1034 return tokens;1035 }1036 1037 function filterPatterns(arr, comparison, prefix, intersection, options) {1038 let result = [];1039 1040 for (let ele of arr) {1041 let { string } = ele;1042 1043 // only push if _both_ are negative...1044 if (!intersection && !contains(comparison, 'string', string)) {1045 result.push(prefix + string);1046 }1047 1048 // or _both_ are positive1049 if (intersection && contains(comparison, 'string', string)) {1050 result.push(prefix + string);1051 }1052 }1053 return result;1054 }1055 1056 /**1057 * Zip strings1058 */1059 1060 function zip(a, b) {1061 let arr = [];1062 for (let i = 0; i < a.length; i++) arr.push([a[i], b[i]]);1063 return arr;1064 }1065 1066 function compare(a, b) {1067 return a > b ? 1 : b > a ? -1 : 0;1068 }1069 1070 function contains(arr, key, val) {1071 return arr.some(ele => ele[key] === val);1072 }1073 1074 function countNines(min, len) {1075 return Number(String(min).slice(0, -len) + '9'.repeat(len));1076 }1077 1078 function countZeros(integer, zeros) {1079 return integer - (integer % Math.pow(10, zeros));1080 }1081 1082 function toQuantifier(digits) {1083 let [start = 0, stop = ''] = digits;1084 if (stop || start > 1) {1085 return `{${start + (stop ? ',' + stop : '')}}`;1086 }1087 return '';1088 }1089 1090 function toCharacterClass(a, b, options) {1091 return `[${a}${(b - a === 1) ? '' : '-'}${b}]`;1092 }1093 1094 function hasPadding(str) {1095 return /^-?(0+)\d/.test(str);1096 }1097 1098 function padZeros(value, tok, options) {1099 if (!tok.isPadded) {1100 return value;1101 }1102 1103 let diff = Math.abs(tok.maxLen - String(value).length);1104 let relax = options.relaxZeros !== false;1105 1106 switch (diff) {1107 case 0:1108 return '';1109 case 1:1110 return relax ? '0?' : '0';1111 case 2:1112 return relax ? '0{0,2}' : '00';1113 default: {1114 return relax ? `0{0,${diff}}` : `0{${diff}}`;1115 }1116 }1117 }1118 1119 /**1120 * Cache1121 */1122 1123 toRegexRange$1.cache = {};1124 toRegexRange$1.clearCache = () => (toRegexRange$1.cache = {});1125 1126 /**1127 * Expose `toRegexRange`1128 */1129 1130 var toRegexRange_1 = toRegexRange$1;1131 5441 1132 5442 /*! … … 1137 5447 */ 1138 5448 1139 const util = require$$2; 1140 const toRegexRange = toRegexRange_1; 1141 1142 const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 1143 1144 const transform = toNumber => { 1145 return value => toNumber === true ? Number(value) : String(value); 1146 }; 1147 1148 const isValidValue = value => { 1149 return typeof value === 'number' || (typeof value === 'string' && value !== ''); 1150 }; 1151 1152 const isNumber = num => Number.isInteger(+num); 1153 1154 const zeros = input => { 1155 let value = `${input}`; 1156 let index = -1; 1157 if (value[0] === '-') value = value.slice(1); 1158 if (value === '0') return false; 1159 while (value[++index] === '0'); 1160 return index > 0; 1161 }; 1162 1163 const stringify$3 = (start, end, options) => { 1164 if (typeof start === 'string' || typeof end === 'string') { 1165 return true; 1166 } 1167 return options.stringify === true; 1168 }; 1169 1170 const pad = (input, maxLength, toNumber) => { 1171 if (maxLength > 0) { 1172 let dash = input[0] === '-' ? '-' : ''; 1173 if (dash) input = input.slice(1); 1174 input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); 1175 } 1176 if (toNumber === false) { 1177 return String(input); 1178 } 1179 return input; 1180 }; 1181 1182 const toMaxLen = (input, maxLength) => { 1183 let negative = input[0] === '-' ? '-' : ''; 1184 if (negative) { 1185 input = input.slice(1); 1186 maxLength--; 1187 } 1188 while (input.length < maxLength) input = '0' + input; 1189 return negative ? ('-' + input) : input; 1190 }; 1191 1192 const toSequence = (parts, options, maxLen) => { 1193 parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); 1194 parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); 1195 1196 let prefix = options.capture ? '' : '?:'; 1197 let positives = ''; 1198 let negatives = ''; 1199 let result; 1200 1201 if (parts.positives.length) { 1202 positives = parts.positives.map(v => toMaxLen(String(v), maxLen)).join('|'); 1203 } 1204 1205 if (parts.negatives.length) { 1206 negatives = `-(${prefix}${parts.negatives.map(v => toMaxLen(String(v), maxLen)).join('|')})`; 1207 } 1208 1209 if (positives && negatives) { 1210 result = `${positives}|${negatives}`; 1211 } else { 1212 result = positives || negatives; 1213 } 1214 1215 if (options.wrap) { 1216 return `(${prefix}${result})`; 1217 } 1218 1219 return result; 1220 }; 1221 1222 const toRange = (a, b, isNumbers, options) => { 1223 if (isNumbers) { 1224 return toRegexRange(a, b, { wrap: false, ...options }); 1225 } 1226 1227 let start = String.fromCharCode(a); 1228 if (a === b) return start; 1229 1230 let stop = String.fromCharCode(b); 1231 return `[${start}-${stop}]`; 1232 }; 1233 1234 const toRegex = (start, end, options) => { 1235 if (Array.isArray(start)) { 1236 let wrap = options.wrap === true; 1237 let prefix = options.capture ? '' : '?:'; 1238 return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); 1239 } 1240 return toRegexRange(start, end, options); 1241 }; 1242 1243 const rangeError = (...args) => { 1244 return new RangeError('Invalid range arguments: ' + util.inspect(...args)); 1245 }; 1246 1247 const invalidRange = (start, end, options) => { 1248 if (options.strictRanges === true) throw rangeError([start, end]); 1249 return []; 1250 }; 1251 1252 const invalidStep = (step, options) => { 1253 if (options.strictRanges === true) { 1254 throw new TypeError(`Expected step "${step}" to be a number`); 1255 } 1256 return []; 1257 }; 1258 1259 const fillNumbers = (start, end, step = 1, options = {}) => { 1260 let a = Number(start); 1261 let b = Number(end); 1262 1263 if (!Number.isInteger(a) || !Number.isInteger(b)) { 1264 if (options.strictRanges === true) throw rangeError([start, end]); 1265 return []; 1266 } 1267 1268 // fix negative zero 1269 if (a === 0) a = 0; 1270 if (b === 0) b = 0; 1271 1272 let descending = a > b; 1273 let startString = String(start); 1274 let endString = String(end); 1275 let stepString = String(step); 1276 step = Math.max(Math.abs(step), 1); 1277 1278 let padded = zeros(startString) || zeros(endString) || zeros(stepString); 1279 let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; 1280 let toNumber = padded === false && stringify$3(start, end, options) === false; 1281 let format = options.transform || transform(toNumber); 1282 1283 if (options.toRegex && step === 1) { 1284 return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); 1285 } 1286 1287 let parts = { negatives: [], positives: [] }; 1288 let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); 1289 let range = []; 1290 let index = 0; 1291 1292 while (descending ? a >= b : a <= b) { 1293 if (options.toRegex === true && step > 1) { 1294 push(a); 1295 } else { 1296 range.push(pad(format(a, index), maxLen, toNumber)); 1297 } 1298 a = descending ? a - step : a + step; 1299 index++; 1300 } 1301 1302 if (options.toRegex === true) { 1303 return step > 1 1304 ? toSequence(parts, options, maxLen) 1305 : toRegex(range, null, { wrap: false, ...options }); 1306 } 1307 1308 return range; 1309 }; 1310 1311 const fillLetters = (start, end, step = 1, options = {}) => { 1312 if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { 1313 return invalidRange(start, end, options); 1314 } 1315 1316 let format = options.transform || (val => String.fromCharCode(val)); 1317 let a = `${start}`.charCodeAt(0); 1318 let b = `${end}`.charCodeAt(0); 1319 1320 let descending = a > b; 1321 let min = Math.min(a, b); 1322 let max = Math.max(a, b); 1323 1324 if (options.toRegex && step === 1) { 1325 return toRange(min, max, false, options); 1326 } 1327 1328 let range = []; 1329 let index = 0; 1330 1331 while (descending ? a >= b : a <= b) { 1332 range.push(format(a, index)); 1333 a = descending ? a - step : a + step; 1334 index++; 1335 } 1336 1337 if (options.toRegex === true) { 1338 return toRegex(range, null, { wrap: false, options }); 1339 } 1340 1341 return range; 1342 }; 1343 1344 const fill$2 = (start, end, step, options = {}) => { 1345 if (end == null && isValidValue(start)) { 1346 return [start]; 1347 } 1348 1349 if (!isValidValue(start) || !isValidValue(end)) { 1350 return invalidRange(start, end, options); 1351 } 1352 1353 if (typeof step === 'function') { 1354 return fill$2(start, end, 1, { transform: step }); 1355 } 1356 1357 if (isObject(step)) { 1358 return fill$2(start, end, 0, step); 1359 } 1360 1361 let opts = { ...options }; 1362 if (opts.capture === true) opts.wrap = true; 1363 step = step || opts.step || 1; 1364 1365 if (!isNumber(step)) { 1366 if (step != null && !isObject(step)) return invalidStep(step, opts); 1367 return fill$2(start, end, 1, step); 1368 } 1369 1370 if (isNumber(start) && isNumber(end)) { 1371 return fillNumbers(start, end, step, opts); 1372 } 1373 1374 return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); 1375 }; 1376 1377 var fillRange = fill$2; 1378 1379 const fill$1 = fillRange; 1380 const utils$1 = utils$3; 1381 1382 const compile$1 = (ast, options = {}) => { 1383 const walk = (node, parent = {}) => { 1384 const invalidBlock = utils$1.isInvalidBrace(parent); 1385 const invalidNode = node.invalid === true && options.escapeInvalid === true; 1386 const invalid = invalidBlock === true || invalidNode === true; 1387 const prefix = options.escapeInvalid === true ? '\\' : ''; 1388 let output = ''; 1389 1390 if (node.isOpen === true) { 1391 return prefix + node.value; 1392 } 1393 1394 if (node.isClose === true) { 1395 console.log('node.isClose', prefix, node.value); 1396 return prefix + node.value; 1397 } 1398 1399 if (node.type === 'open') { 1400 return invalid ? prefix + node.value : '('; 1401 } 1402 1403 if (node.type === 'close') { 1404 return invalid ? prefix + node.value : ')'; 1405 } 1406 1407 if (node.type === 'comma') { 1408 return node.prev.type === 'comma' ? '' : invalid ? node.value : '|'; 1409 } 1410 1411 if (node.value) { 1412 return node.value; 1413 } 1414 1415 if (node.nodes && node.ranges > 0) { 1416 const args = utils$1.reduce(node.nodes); 1417 const range = fill$1(...args, { ...options, wrap: false, toRegex: true, strictZeros: true }); 1418 1419 if (range.length !== 0) { 1420 return args.length > 1 && range.length > 1 ? `(${range})` : range; 1421 } 1422 } 1423 1424 if (node.nodes) { 1425 for (const child of node.nodes) { 1426 output += walk(child, node); 1427 } 1428 } 1429 1430 return output; 1431 }; 1432 1433 return walk(ast); 1434 }; 1435 1436 var compile_1 = compile$1; 1437 1438 const fill = fillRange; 1439 const stringify$2 = stringify$4; 1440 const utils = utils$3; 1441 1442 const append = (queue = '', stash = '', enclose = false) => { 1443 const result = []; 1444 1445 queue = [].concat(queue); 1446 stash = [].concat(stash); 1447 1448 if (!stash.length) return queue; 1449 if (!queue.length) { 1450 return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; 1451 } 1452 1453 for (const item of queue) { 1454 if (Array.isArray(item)) { 1455 for (const value of item) { 1456 result.push(append(value, stash, enclose)); 1457 } 1458 } else { 1459 for (let ele of stash) { 1460 if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; 1461 result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele); 1462 } 1463 } 1464 } 1465 return utils.flatten(result); 1466 }; 1467 1468 const expand$1 = (ast, options = {}) => { 1469 const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit; 1470 1471 const walk = (node, parent = {}) => { 1472 node.queue = []; 1473 1474 let p = parent; 1475 let q = parent.queue; 1476 1477 while (p.type !== 'brace' && p.type !== 'root' && p.parent) { 1478 p = p.parent; 1479 q = p.queue; 1480 } 1481 1482 if (node.invalid || node.dollar) { 1483 q.push(append(q.pop(), stringify$2(node, options))); 1484 return; 1485 } 1486 1487 if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { 1488 q.push(append(q.pop(), ['{}'])); 1489 return; 1490 } 1491 1492 if (node.nodes && node.ranges > 0) { 1493 const args = utils.reduce(node.nodes); 1494 1495 if (utils.exceedsLimit(...args, options.step, rangeLimit)) { 1496 throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); 1497 } 1498 1499 let range = fill(...args, options); 1500 if (range.length === 0) { 1501 range = stringify$2(node, options); 1502 } 1503 1504 q.push(append(q.pop(), range)); 1505 node.nodes = []; 1506 return; 1507 } 1508 1509 const enclose = utils.encloseBrace(node); 1510 let queue = node.queue; 1511 let block = node; 1512 1513 while (block.type !== 'brace' && block.type !== 'root' && block.parent) { 1514 block = block.parent; 1515 queue = block.queue; 1516 } 1517 1518 for (let i = 0; i < node.nodes.length; i++) { 1519 const child = node.nodes[i]; 1520 1521 if (child.type === 'comma' && node.type === 'brace') { 1522 if (i === 1) queue.push(''); 1523 queue.push(''); 1524 continue; 1525 } 1526 1527 if (child.type === 'close') { 1528 q.push(append(q.pop(), queue, enclose)); 1529 continue; 1530 } 1531 1532 if (child.value && child.type !== 'open') { 1533 queue.push(append(queue.pop(), child.value)); 1534 continue; 1535 } 1536 1537 if (child.nodes) { 1538 walk(child, node); 1539 } 1540 } 1541 1542 return queue; 1543 }; 1544 1545 return utils.flatten(walk(ast)); 1546 }; 1547 1548 var expand_1 = expand$1; 1549 1550 var constants$1 = { 1551 MAX_LENGTH: 10000, 1552 1553 // Digits 1554 CHAR_0: '0', /* 0 */ 1555 CHAR_9: '9', /* 9 */ 1556 1557 // Alphabet chars. 1558 CHAR_UPPERCASE_A: 'A', /* A */ 1559 CHAR_LOWERCASE_A: 'a', /* a */ 1560 CHAR_UPPERCASE_Z: 'Z', /* Z */ 1561 CHAR_LOWERCASE_Z: 'z', /* z */ 1562 1563 CHAR_LEFT_PARENTHESES: '(', /* ( */ 1564 CHAR_RIGHT_PARENTHESES: ')', /* ) */ 1565 1566 CHAR_ASTERISK: '*', /* * */ 1567 1568 // Non-alphabetic chars. 1569 CHAR_AMPERSAND: '&', /* & */ 1570 CHAR_AT: '@', /* @ */ 1571 CHAR_BACKSLASH: '\\', /* \ */ 1572 CHAR_BACKTICK: '`', /* ` */ 1573 CHAR_CARRIAGE_RETURN: '\r', /* \r */ 1574 CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ 1575 CHAR_COLON: ':', /* : */ 1576 CHAR_COMMA: ',', /* , */ 1577 CHAR_DOLLAR: '$', /* . */ 1578 CHAR_DOT: '.', /* . */ 1579 CHAR_DOUBLE_QUOTE: '"', /* " */ 1580 CHAR_EQUAL: '=', /* = */ 1581 CHAR_EXCLAMATION_MARK: '!', /* ! */ 1582 CHAR_FORM_FEED: '\f', /* \f */ 1583 CHAR_FORWARD_SLASH: '/', /* / */ 1584 CHAR_HASH: '#', /* # */ 1585 CHAR_HYPHEN_MINUS: '-', /* - */ 1586 CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ 1587 CHAR_LEFT_CURLY_BRACE: '{', /* { */ 1588 CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ 1589 CHAR_LINE_FEED: '\n', /* \n */ 1590 CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ 1591 CHAR_PERCENT: '%', /* % */ 1592 CHAR_PLUS: '+', /* + */ 1593 CHAR_QUESTION_MARK: '?', /* ? */ 1594 CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ 1595 CHAR_RIGHT_CURLY_BRACE: '}', /* } */ 1596 CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ 1597 CHAR_SEMICOLON: ';', /* ; */ 1598 CHAR_SINGLE_QUOTE: '\'', /* ' */ 1599 CHAR_SPACE: ' ', /* */ 1600 CHAR_TAB: '\t', /* \t */ 1601 CHAR_UNDERSCORE: '_', /* _ */ 1602 CHAR_VERTICAL_LINE: '|', /* | */ 1603 CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ 1604 }; 1605 1606 const stringify$1 = stringify$4; 1607 1608 /** 1609 * Constants 1610 */ 1611 1612 const { 1613 MAX_LENGTH, 1614 CHAR_BACKSLASH, /* \ */ 1615 CHAR_BACKTICK, /* ` */ 1616 CHAR_COMMA, /* , */ 1617 CHAR_DOT, /* . */ 1618 CHAR_LEFT_PARENTHESES, /* ( */ 1619 CHAR_RIGHT_PARENTHESES, /* ) */ 1620 CHAR_LEFT_CURLY_BRACE, /* { */ 1621 CHAR_RIGHT_CURLY_BRACE, /* } */ 1622 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 1623 CHAR_RIGHT_SQUARE_BRACKET, /* ] */ 1624 CHAR_DOUBLE_QUOTE, /* " */ 1625 CHAR_SINGLE_QUOTE, /* ' */ 1626 CHAR_NO_BREAK_SPACE, 1627 CHAR_ZERO_WIDTH_NOBREAK_SPACE 1628 } = constants$1; 1629 1630 /** 1631 * parse 1632 */ 1633 1634 const parse$1 = (input, options = {}) => { 1635 if (typeof input !== 'string') { 1636 throw new TypeError('Expected a string'); 1637 } 1638 1639 const opts = options || {}; 1640 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 1641 if (input.length > max) { 1642 throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); 1643 } 1644 1645 const ast = { type: 'root', input, nodes: [] }; 1646 const stack = [ast]; 1647 let block = ast; 1648 let prev = ast; 1649 let brackets = 0; 1650 const length = input.length; 1651 let index = 0; 1652 let depth = 0; 1653 let value; 1654 1655 /** 1656 * Helpers 1657 */ 1658 1659 const advance = () => input[index++]; 1660 const push = node => { 1661 if (node.type === 'text' && prev.type === 'dot') { 1662 prev.type = 'text'; 1663 } 1664 1665 if (prev && prev.type === 'text' && node.type === 'text') { 1666 prev.value += node.value; 1667 return; 1668 } 1669 1670 block.nodes.push(node); 1671 node.parent = block; 1672 node.prev = prev; 1673 prev = node; 1674 return node; 1675 }; 1676 1677 push({ type: 'bos' }); 1678 1679 while (index < length) { 1680 block = stack[stack.length - 1]; 1681 value = advance(); 1682 1683 /** 1684 * Invalid chars 1685 */ 1686 1687 if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { 1688 continue; 1689 } 1690 1691 /** 1692 * Escaped chars 1693 */ 1694 1695 if (value === CHAR_BACKSLASH) { 1696 push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); 1697 continue; 1698 } 1699 1700 /** 1701 * Right square bracket (literal): ']' 1702 */ 1703 1704 if (value === CHAR_RIGHT_SQUARE_BRACKET) { 1705 push({ type: 'text', value: '\\' + value }); 1706 continue; 1707 } 1708 1709 /** 1710 * Left square bracket: '[' 1711 */ 1712 1713 if (value === CHAR_LEFT_SQUARE_BRACKET) { 1714 brackets++; 1715 1716 let next; 1717 1718 while (index < length && (next = advance())) { 1719 value += next; 1720 1721 if (next === CHAR_LEFT_SQUARE_BRACKET) { 1722 brackets++; 1723 continue; 1724 } 1725 1726 if (next === CHAR_BACKSLASH) { 1727 value += advance(); 1728 continue; 1729 } 1730 1731 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 1732 brackets--; 1733 1734 if (brackets === 0) { 1735 break; 1736 } 1737 } 1738 } 1739 1740 push({ type: 'text', value }); 1741 continue; 1742 } 1743 1744 /** 1745 * Parentheses 1746 */ 1747 1748 if (value === CHAR_LEFT_PARENTHESES) { 1749 block = push({ type: 'paren', nodes: [] }); 1750 stack.push(block); 1751 push({ type: 'text', value }); 1752 continue; 1753 } 1754 1755 if (value === CHAR_RIGHT_PARENTHESES) { 1756 if (block.type !== 'paren') { 1757 push({ type: 'text', value }); 1758 continue; 1759 } 1760 block = stack.pop(); 1761 push({ type: 'text', value }); 1762 block = stack[stack.length - 1]; 1763 continue; 1764 } 1765 1766 /** 1767 * Quotes: '|"|` 1768 */ 1769 1770 if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { 1771 const open = value; 1772 let next; 1773 1774 if (options.keepQuotes !== true) { 1775 value = ''; 1776 } 1777 1778 while (index < length && (next = advance())) { 1779 if (next === CHAR_BACKSLASH) { 1780 value += next + advance(); 1781 continue; 1782 } 1783 1784 if (next === open) { 1785 if (options.keepQuotes === true) value += next; 1786 break; 1787 } 1788 1789 value += next; 1790 } 1791 1792 push({ type: 'text', value }); 1793 continue; 1794 } 1795 1796 /** 1797 * Left curly brace: '{' 1798 */ 1799 1800 if (value === CHAR_LEFT_CURLY_BRACE) { 1801 depth++; 1802 1803 const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; 1804 const brace = { 1805 type: 'brace', 1806 open: true, 1807 close: false, 1808 dollar, 1809 depth, 1810 commas: 0, 1811 ranges: 0, 1812 nodes: [] 1813 }; 1814 1815 block = push(brace); 1816 stack.push(block); 1817 push({ type: 'open', value }); 1818 continue; 1819 } 1820 1821 /** 1822 * Right curly brace: '}' 1823 */ 1824 1825 if (value === CHAR_RIGHT_CURLY_BRACE) { 1826 if (block.type !== 'brace') { 1827 push({ type: 'text', value }); 1828 continue; 1829 } 1830 1831 const type = 'close'; 1832 block = stack.pop(); 1833 block.close = true; 1834 1835 push({ type, value }); 1836 depth--; 1837 1838 block = stack[stack.length - 1]; 1839 continue; 1840 } 1841 1842 /** 1843 * Comma: ',' 1844 */ 1845 1846 if (value === CHAR_COMMA && depth > 0) { 1847 if (block.ranges > 0) { 1848 block.ranges = 0; 1849 const open = block.nodes.shift(); 1850 block.nodes = [open, { type: 'text', value: stringify$1(block) }]; 1851 } 1852 1853 push({ type: 'comma', value }); 1854 block.commas++; 1855 continue; 1856 } 1857 1858 /** 1859 * Dot: '.' 1860 */ 1861 1862 if (value === CHAR_DOT && depth > 0 && block.commas === 0) { 1863 const siblings = block.nodes; 1864 1865 if (depth === 0 || siblings.length === 0) { 1866 push({ type: 'text', value }); 1867 continue; 1868 } 1869 1870 if (prev.type === 'dot') { 1871 block.range = []; 1872 prev.value += value; 1873 prev.type = 'range'; 1874 1875 if (block.nodes.length !== 3 && block.nodes.length !== 5) { 1876 block.invalid = true; 1877 block.ranges = 0; 1878 prev.type = 'text'; 1879 continue; 1880 } 1881 1882 block.ranges++; 1883 block.args = []; 1884 continue; 1885 } 1886 1887 if (prev.type === 'range') { 1888 siblings.pop(); 1889 1890 const before = siblings[siblings.length - 1]; 1891 before.value += prev.value + value; 1892 prev = before; 1893 block.ranges--; 1894 continue; 1895 } 1896 1897 push({ type: 'dot', value }); 1898 continue; 1899 } 1900 1901 /** 1902 * Text 1903 */ 1904 1905 push({ type: 'text', value }); 1906 } 1907 1908 // Mark imbalanced braces and brackets as invalid 1909 do { 1910 block = stack.pop(); 1911 1912 if (block.type !== 'root') { 1913 block.nodes.forEach(node => { 1914 if (!node.nodes) { 1915 if (node.type === 'open') node.isOpen = true; 1916 if (node.type === 'close') node.isClose = true; 1917 if (!node.nodes) node.type = 'text'; 1918 node.invalid = true; 1919 } 1920 }); 1921 1922 // get the location of the block on parent.nodes (block's siblings) 1923 const parent = stack[stack.length - 1]; 1924 const index = parent.nodes.indexOf(block); 1925 // replace the (invalid) block with it's nodes 1926 parent.nodes.splice(index, 1, ...block.nodes); 1927 } 1928 } while (stack.length > 0); 1929 1930 push({ type: 'eos' }); 1931 return ast; 1932 }; 1933 1934 var parse_1 = parse$1; 1935 1936 const stringify = stringify$4; 1937 const compile = compile_1; 1938 const expand = expand_1; 1939 const parse = parse_1; 1940 1941 /** 1942 * Expand the given pattern or create a regex-compatible string. 1943 * 1944 * ```js 1945 * const braces = require('braces'); 1946 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] 1947 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] 1948 * ``` 1949 * @param {String} `str` 1950 * @param {Object} `options` 1951 * @return {String} 1952 * @api public 1953 */ 1954 1955 const braces$1 = (input, options = {}) => { 1956 let output = []; 1957 1958 if (Array.isArray(input)) { 1959 for (const pattern of input) { 1960 const result = braces$1.create(pattern, options); 1961 if (Array.isArray(result)) { 1962 output.push(...result); 1963 } else { 1964 output.push(result); 1965 } 1966 } 1967 } else { 1968 output = [].concat(braces$1.create(input, options)); 1969 } 1970 1971 if (options && options.expand === true && options.nodupes === true) { 1972 output = [...new Set(output)]; 1973 } 1974 return output; 1975 }; 1976 1977 /** 1978 * Parse the given `str` with the given `options`. 1979 * 1980 * ```js 1981 * // braces.parse(pattern, [, options]); 1982 * const ast = braces.parse('a/{b,c}/d'); 1983 * console.log(ast); 1984 * ``` 1985 * @param {String} pattern Brace pattern to parse 1986 * @param {Object} options 1987 * @return {Object} Returns an AST 1988 * @api public 1989 */ 1990 1991 braces$1.parse = (input, options = {}) => parse(input, options); 1992 1993 /** 1994 * Creates a braces string from an AST, or an AST node. 1995 * 1996 * ```js 1997 * const braces = require('braces'); 1998 * let ast = braces.parse('foo/{a,b}/bar'); 1999 * console.log(stringify(ast.nodes[2])); //=> '{a,b}' 2000 * ``` 2001 * @param {String} `input` Brace pattern or AST. 2002 * @param {Object} `options` 2003 * @return {Array} Returns an array of expanded values. 2004 * @api public 2005 */ 2006 2007 braces$1.stringify = (input, options = {}) => { 2008 if (typeof input === 'string') { 2009 return stringify(braces$1.parse(input, options), options); 2010 } 2011 return stringify(input, options); 2012 }; 2013 2014 /** 2015 * Compiles a brace pattern into a regex-compatible, optimized string. 2016 * This method is called by the main [braces](#braces) function by default. 2017 * 2018 * ```js 2019 * const braces = require('braces'); 2020 * console.log(braces.compile('a/{b,c}/d')); 2021 * //=> ['a/(b|c)/d'] 2022 * ``` 2023 * @param {String} `input` Brace pattern or AST. 2024 * @param {Object} `options` 2025 * @return {Array} Returns an array of expanded values. 2026 * @api public 2027 */ 2028 2029 braces$1.compile = (input, options = {}) => { 2030 if (typeof input === 'string') { 2031 input = braces$1.parse(input, options); 2032 } 2033 return compile(input, options); 2034 }; 2035 2036 /** 2037 * Expands a brace pattern into an array. This method is called by the 2038 * main [braces](#braces) function when `options.expand` is true. Before 2039 * using this method it's recommended that you read the [performance notes](#performance)) 2040 * and advantages of using [.compile](#compile) instead. 2041 * 2042 * ```js 2043 * const braces = require('braces'); 2044 * console.log(braces.expand('a/{b,c}/d')); 2045 * //=> ['a/b/d', 'a/c/d']; 2046 * ``` 2047 * @param {String} `pattern` Brace pattern 2048 * @param {Object} `options` 2049 * @return {Array} Returns an array of expanded values. 2050 * @api public 2051 */ 2052 2053 braces$1.expand = (input, options = {}) => { 2054 if (typeof input === 'string') { 2055 input = braces$1.parse(input, options); 2056 } 2057 2058 let result = expand(input, options); 2059 2060 // filter out empty strings if specified 2061 if (options.noempty === true) { 2062 result = result.filter(Boolean); 2063 } 2064 2065 // filter out duplicates if specified 2066 if (options.nodupes === true) { 2067 result = [...new Set(result)]; 2068 } 2069 2070 return result; 2071 }; 2072 2073 /** 2074 * Processes a brace pattern and returns either an expanded array 2075 * (if `options.expand` is true), a highly optimized regex-compatible string. 2076 * This method is called by the main [braces](#braces) function. 2077 * 2078 * ```js 2079 * const braces = require('braces'); 2080 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) 2081 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' 2082 * ``` 2083 * @param {String} `pattern` Brace pattern 2084 * @param {Object} `options` 2085 * @return {Array} Returns an array of expanded values. 2086 * @api public 2087 */ 2088 2089 braces$1.create = (input, options = {}) => { 2090 if (input === '' || input.length < 3) { 2091 return [input]; 2092 } 2093 2094 return options.expand !== true 2095 ? braces$1.compile(input, options) 2096 : braces$1.expand(input, options); 2097 }; 2098 2099 /** 2100 * Expose "braces" 2101 */ 2102 2103 var braces_1 = braces$1; 5449 var fillRange; 5450 var hasRequiredFillRange; 5451 5452 function requireFillRange () { 5453 if (hasRequiredFillRange) return fillRange; 5454 hasRequiredFillRange = 1; 5455 5456 const util = require$$2; 5457 const toRegexRange = /*@__PURE__*/ requireToRegexRange(); 5458 5459 const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); 5460 5461 const transform = toNumber => { 5462 return value => toNumber === true ? Number(value) : String(value); 5463 }; 5464 5465 const isValidValue = value => { 5466 return typeof value === 'number' || (typeof value === 'string' && value !== ''); 5467 }; 5468 5469 const isNumber = num => Number.isInteger(+num); 5470 5471 const zeros = input => { 5472 let value = `${input}`; 5473 let index = -1; 5474 if (value[0] === '-') value = value.slice(1); 5475 if (value === '0') return false; 5476 while (value[++index] === '0'); 5477 return index > 0; 5478 }; 5479 5480 const stringify = (start, end, options) => { 5481 if (typeof start === 'string' || typeof end === 'string') { 5482 return true; 5483 } 5484 return options.stringify === true; 5485 }; 5486 5487 const pad = (input, maxLength, toNumber) => { 5488 if (maxLength > 0) { 5489 let dash = input[0] === '-' ? '-' : ''; 5490 if (dash) input = input.slice(1); 5491 input = (dash + input.padStart(dash ? maxLength - 1 : maxLength, '0')); 5492 } 5493 if (toNumber === false) { 5494 return String(input); 5495 } 5496 return input; 5497 }; 5498 5499 const toMaxLen = (input, maxLength) => { 5500 let negative = input[0] === '-' ? '-' : ''; 5501 if (negative) { 5502 input = input.slice(1); 5503 maxLength--; 5504 } 5505 while (input.length < maxLength) input = '0' + input; 5506 return negative ? ('-' + input) : input; 5507 }; 5508 5509 const toSequence = (parts, options, maxLen) => { 5510 parts.negatives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); 5511 parts.positives.sort((a, b) => a < b ? -1 : a > b ? 1 : 0); 5512 5513 let prefix = options.capture ? '' : '?:'; 5514 let positives = ''; 5515 let negatives = ''; 5516 let result; 5517 5518 if (parts.positives.length) { 5519 positives = parts.positives.map(v => toMaxLen(String(v), maxLen)).join('|'); 5520 } 5521 5522 if (parts.negatives.length) { 5523 negatives = `-(${prefix}${parts.negatives.map(v => toMaxLen(String(v), maxLen)).join('|')})`; 5524 } 5525 5526 if (positives && negatives) { 5527 result = `${positives}|${negatives}`; 5528 } else { 5529 result = positives || negatives; 5530 } 5531 5532 if (options.wrap) { 5533 return `(${prefix}${result})`; 5534 } 5535 5536 return result; 5537 }; 5538 5539 const toRange = (a, b, isNumbers, options) => { 5540 if (isNumbers) { 5541 return toRegexRange(a, b, { wrap: false, ...options }); 5542 } 5543 5544 let start = String.fromCharCode(a); 5545 if (a === b) return start; 5546 5547 let stop = String.fromCharCode(b); 5548 return `[${start}-${stop}]`; 5549 }; 5550 5551 const toRegex = (start, end, options) => { 5552 if (Array.isArray(start)) { 5553 let wrap = options.wrap === true; 5554 let prefix = options.capture ? '' : '?:'; 5555 return wrap ? `(${prefix}${start.join('|')})` : start.join('|'); 5556 } 5557 return toRegexRange(start, end, options); 5558 }; 5559 5560 const rangeError = (...args) => { 5561 return new RangeError('Invalid range arguments: ' + util.inspect(...args)); 5562 }; 5563 5564 const invalidRange = (start, end, options) => { 5565 if (options.strictRanges === true) throw rangeError([start, end]); 5566 return []; 5567 }; 5568 5569 const invalidStep = (step, options) => { 5570 if (options.strictRanges === true) { 5571 throw new TypeError(`Expected step "${step}" to be a number`); 5572 } 5573 return []; 5574 }; 5575 5576 const fillNumbers = (start, end, step = 1, options = {}) => { 5577 let a = Number(start); 5578 let b = Number(end); 5579 5580 if (!Number.isInteger(a) || !Number.isInteger(b)) { 5581 if (options.strictRanges === true) throw rangeError([start, end]); 5582 return []; 5583 } 5584 5585 // fix negative zero 5586 if (a === 0) a = 0; 5587 if (b === 0) b = 0; 5588 5589 let descending = a > b; 5590 let startString = String(start); 5591 let endString = String(end); 5592 let stepString = String(step); 5593 step = Math.max(Math.abs(step), 1); 5594 5595 let padded = zeros(startString) || zeros(endString) || zeros(stepString); 5596 let maxLen = padded ? Math.max(startString.length, endString.length, stepString.length) : 0; 5597 let toNumber = padded === false && stringify(start, end, options) === false; 5598 let format = options.transform || transform(toNumber); 5599 5600 if (options.toRegex && step === 1) { 5601 return toRange(toMaxLen(start, maxLen), toMaxLen(end, maxLen), true, options); 5602 } 5603 5604 let parts = { negatives: [], positives: [] }; 5605 let push = num => parts[num < 0 ? 'negatives' : 'positives'].push(Math.abs(num)); 5606 let range = []; 5607 let index = 0; 5608 5609 while (descending ? a >= b : a <= b) { 5610 if (options.toRegex === true && step > 1) { 5611 push(a); 5612 } else { 5613 range.push(pad(format(a, index), maxLen, toNumber)); 5614 } 5615 a = descending ? a - step : a + step; 5616 index++; 5617 } 5618 5619 if (options.toRegex === true) { 5620 return step > 1 5621 ? toSequence(parts, options, maxLen) 5622 : toRegex(range, null, { wrap: false, ...options }); 5623 } 5624 5625 return range; 5626 }; 5627 5628 const fillLetters = (start, end, step = 1, options = {}) => { 5629 if ((!isNumber(start) && start.length > 1) || (!isNumber(end) && end.length > 1)) { 5630 return invalidRange(start, end, options); 5631 } 5632 5633 let format = options.transform || (val => String.fromCharCode(val)); 5634 let a = `${start}`.charCodeAt(0); 5635 let b = `${end}`.charCodeAt(0); 5636 5637 let descending = a > b; 5638 let min = Math.min(a, b); 5639 let max = Math.max(a, b); 5640 5641 if (options.toRegex && step === 1) { 5642 return toRange(min, max, false, options); 5643 } 5644 5645 let range = []; 5646 let index = 0; 5647 5648 while (descending ? a >= b : a <= b) { 5649 range.push(format(a, index)); 5650 a = descending ? a - step : a + step; 5651 index++; 5652 } 5653 5654 if (options.toRegex === true) { 5655 return toRegex(range, null, { wrap: false, options }); 5656 } 5657 5658 return range; 5659 }; 5660 5661 const fill = (start, end, step, options = {}) => { 5662 if (end == null && isValidValue(start)) { 5663 return [start]; 5664 } 5665 5666 if (!isValidValue(start) || !isValidValue(end)) { 5667 return invalidRange(start, end, options); 5668 } 5669 5670 if (typeof step === 'function') { 5671 return fill(start, end, 1, { transform: step }); 5672 } 5673 5674 if (isObject(step)) { 5675 return fill(start, end, 0, step); 5676 } 5677 5678 let opts = { ...options }; 5679 if (opts.capture === true) opts.wrap = true; 5680 step = step || opts.step || 1; 5681 5682 if (!isNumber(step)) { 5683 if (step != null && !isObject(step)) return invalidStep(step, opts); 5684 return fill(start, end, 1, step); 5685 } 5686 5687 if (isNumber(start) && isNumber(end)) { 5688 return fillNumbers(start, end, step, opts); 5689 } 5690 5691 return fillLetters(start, end, Math.max(Math.abs(step), 1), opts); 5692 }; 5693 5694 fillRange = fill; 5695 return fillRange; 5696 } 5697 5698 var compile_1; 5699 var hasRequiredCompile; 5700 5701 function requireCompile () { 5702 if (hasRequiredCompile) return compile_1; 5703 hasRequiredCompile = 1; 5704 5705 const fill = /*@__PURE__*/ requireFillRange(); 5706 const utils = /*@__PURE__*/ requireUtils(); 5707 5708 const compile = (ast, options = {}) => { 5709 const walk = (node, parent = {}) => { 5710 const invalidBlock = utils.isInvalidBrace(parent); 5711 const invalidNode = node.invalid === true && options.escapeInvalid === true; 5712 const invalid = invalidBlock === true || invalidNode === true; 5713 const prefix = options.escapeInvalid === true ? '\\' : ''; 5714 let output = ''; 5715 5716 if (node.isOpen === true) { 5717 return prefix + node.value; 5718 } 5719 5720 if (node.isClose === true) { 5721 console.log('node.isClose', prefix, node.value); 5722 return prefix + node.value; 5723 } 5724 5725 if (node.type === 'open') { 5726 return invalid ? prefix + node.value : '('; 5727 } 5728 5729 if (node.type === 'close') { 5730 return invalid ? prefix + node.value : ')'; 5731 } 5732 5733 if (node.type === 'comma') { 5734 return node.prev.type === 'comma' ? '' : invalid ? node.value : '|'; 5735 } 5736 5737 if (node.value) { 5738 return node.value; 5739 } 5740 5741 if (node.nodes && node.ranges > 0) { 5742 const args = utils.reduce(node.nodes); 5743 const range = fill(...args, { ...options, wrap: false, toRegex: true, strictZeros: true }); 5744 5745 if (range.length !== 0) { 5746 return args.length > 1 && range.length > 1 ? `(${range})` : range; 5747 } 5748 } 5749 5750 if (node.nodes) { 5751 for (const child of node.nodes) { 5752 output += walk(child, node); 5753 } 5754 } 5755 5756 return output; 5757 }; 5758 5759 return walk(ast); 5760 }; 5761 5762 compile_1 = compile; 5763 return compile_1; 5764 } 5765 5766 var expand_1; 5767 var hasRequiredExpand; 5768 5769 function requireExpand () { 5770 if (hasRequiredExpand) return expand_1; 5771 hasRequiredExpand = 1; 5772 5773 const fill = /*@__PURE__*/ requireFillRange(); 5774 const stringify = /*@__PURE__*/ requireStringify(); 5775 const utils = /*@__PURE__*/ requireUtils(); 5776 5777 const append = (queue = '', stash = '', enclose = false) => { 5778 const result = []; 5779 5780 queue = [].concat(queue); 5781 stash = [].concat(stash); 5782 5783 if (!stash.length) return queue; 5784 if (!queue.length) { 5785 return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; 5786 } 5787 5788 for (const item of queue) { 5789 if (Array.isArray(item)) { 5790 for (const value of item) { 5791 result.push(append(value, stash, enclose)); 5792 } 5793 } else { 5794 for (let ele of stash) { 5795 if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; 5796 result.push(Array.isArray(ele) ? append(item, ele, enclose) : item + ele); 5797 } 5798 } 5799 } 5800 return utils.flatten(result); 5801 }; 5802 5803 const expand = (ast, options = {}) => { 5804 const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit; 5805 5806 const walk = (node, parent = {}) => { 5807 node.queue = []; 5808 5809 let p = parent; 5810 let q = parent.queue; 5811 5812 while (p.type !== 'brace' && p.type !== 'root' && p.parent) { 5813 p = p.parent; 5814 q = p.queue; 5815 } 5816 5817 if (node.invalid || node.dollar) { 5818 q.push(append(q.pop(), stringify(node, options))); 5819 return; 5820 } 5821 5822 if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { 5823 q.push(append(q.pop(), ['{}'])); 5824 return; 5825 } 5826 5827 if (node.nodes && node.ranges > 0) { 5828 const args = utils.reduce(node.nodes); 5829 5830 if (utils.exceedsLimit(...args, options.step, rangeLimit)) { 5831 throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); 5832 } 5833 5834 let range = fill(...args, options); 5835 if (range.length === 0) { 5836 range = stringify(node, options); 5837 } 5838 5839 q.push(append(q.pop(), range)); 5840 node.nodes = []; 5841 return; 5842 } 5843 5844 const enclose = utils.encloseBrace(node); 5845 let queue = node.queue; 5846 let block = node; 5847 5848 while (block.type !== 'brace' && block.type !== 'root' && block.parent) { 5849 block = block.parent; 5850 queue = block.queue; 5851 } 5852 5853 for (let i = 0; i < node.nodes.length; i++) { 5854 const child = node.nodes[i]; 5855 5856 if (child.type === 'comma' && node.type === 'brace') { 5857 if (i === 1) queue.push(''); 5858 queue.push(''); 5859 continue; 5860 } 5861 5862 if (child.type === 'close') { 5863 q.push(append(q.pop(), queue, enclose)); 5864 continue; 5865 } 5866 5867 if (child.value && child.type !== 'open') { 5868 queue.push(append(queue.pop(), child.value)); 5869 continue; 5870 } 5871 5872 if (child.nodes) { 5873 walk(child, node); 5874 } 5875 } 5876 5877 return queue; 5878 }; 5879 5880 return utils.flatten(walk(ast)); 5881 }; 5882 5883 expand_1 = expand; 5884 return expand_1; 5885 } 5886 5887 var constants$1; 5888 var hasRequiredConstants$1; 5889 5890 function requireConstants$1 () { 5891 if (hasRequiredConstants$1) return constants$1; 5892 hasRequiredConstants$1 = 1; 5893 5894 constants$1 = { 5895 MAX_LENGTH: 10000, 5896 5897 // Digits 5898 CHAR_0: '0', /* 0 */ 5899 CHAR_9: '9', /* 9 */ 5900 5901 // Alphabet chars. 5902 CHAR_UPPERCASE_A: 'A', /* A */ 5903 CHAR_LOWERCASE_A: 'a', /* a */ 5904 CHAR_UPPERCASE_Z: 'Z', /* Z */ 5905 CHAR_LOWERCASE_Z: 'z', /* z */ 5906 5907 CHAR_LEFT_PARENTHESES: '(', /* ( */ 5908 CHAR_RIGHT_PARENTHESES: ')', /* ) */ 5909 5910 CHAR_ASTERISK: '*', /* * */ 5911 5912 // Non-alphabetic chars. 5913 CHAR_AMPERSAND: '&', /* & */ 5914 CHAR_AT: '@', /* @ */ 5915 CHAR_BACKSLASH: '\\', /* \ */ 5916 CHAR_BACKTICK: '`', /* ` */ 5917 CHAR_CARRIAGE_RETURN: '\r', /* \r */ 5918 CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ 5919 CHAR_COLON: ':', /* : */ 5920 CHAR_COMMA: ',', /* , */ 5921 CHAR_DOLLAR: '$', /* . */ 5922 CHAR_DOT: '.', /* . */ 5923 CHAR_DOUBLE_QUOTE: '"', /* " */ 5924 CHAR_EQUAL: '=', /* = */ 5925 CHAR_EXCLAMATION_MARK: '!', /* ! */ 5926 CHAR_FORM_FEED: '\f', /* \f */ 5927 CHAR_FORWARD_SLASH: '/', /* / */ 5928 CHAR_HASH: '#', /* # */ 5929 CHAR_HYPHEN_MINUS: '-', /* - */ 5930 CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ 5931 CHAR_LEFT_CURLY_BRACE: '{', /* { */ 5932 CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ 5933 CHAR_LINE_FEED: '\n', /* \n */ 5934 CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ 5935 CHAR_PERCENT: '%', /* % */ 5936 CHAR_PLUS: '+', /* + */ 5937 CHAR_QUESTION_MARK: '?', /* ? */ 5938 CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ 5939 CHAR_RIGHT_CURLY_BRACE: '}', /* } */ 5940 CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ 5941 CHAR_SEMICOLON: ';', /* ; */ 5942 CHAR_SINGLE_QUOTE: '\'', /* ' */ 5943 CHAR_SPACE: ' ', /* */ 5944 CHAR_TAB: '\t', /* \t */ 5945 CHAR_UNDERSCORE: '_', /* _ */ 5946 CHAR_VERTICAL_LINE: '|', /* | */ 5947 CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ 5948 }; 5949 return constants$1; 5950 } 5951 5952 var parse_1; 5953 var hasRequiredParse; 5954 5955 function requireParse () { 5956 if (hasRequiredParse) return parse_1; 5957 hasRequiredParse = 1; 5958 5959 const stringify = /*@__PURE__*/ requireStringify(); 5960 5961 /** 5962 * Constants 5963 */ 5964 5965 const { 5966 MAX_LENGTH, 5967 CHAR_BACKSLASH, /* \ */ 5968 CHAR_BACKTICK, /* ` */ 5969 CHAR_COMMA, /* , */ 5970 CHAR_DOT, /* . */ 5971 CHAR_LEFT_PARENTHESES, /* ( */ 5972 CHAR_RIGHT_PARENTHESES, /* ) */ 5973 CHAR_LEFT_CURLY_BRACE, /* { */ 5974 CHAR_RIGHT_CURLY_BRACE, /* } */ 5975 CHAR_LEFT_SQUARE_BRACKET, /* [ */ 5976 CHAR_RIGHT_SQUARE_BRACKET, /* ] */ 5977 CHAR_DOUBLE_QUOTE, /* " */ 5978 CHAR_SINGLE_QUOTE, /* ' */ 5979 CHAR_NO_BREAK_SPACE, 5980 CHAR_ZERO_WIDTH_NOBREAK_SPACE 5981 } = /*@__PURE__*/ requireConstants$1(); 5982 5983 /** 5984 * parse 5985 */ 5986 5987 const parse = (input, options = {}) => { 5988 if (typeof input !== 'string') { 5989 throw new TypeError('Expected a string'); 5990 } 5991 5992 const opts = options || {}; 5993 const max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; 5994 if (input.length > max) { 5995 throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); 5996 } 5997 5998 const ast = { type: 'root', input, nodes: [] }; 5999 const stack = [ast]; 6000 let block = ast; 6001 let prev = ast; 6002 let brackets = 0; 6003 const length = input.length; 6004 let index = 0; 6005 let depth = 0; 6006 let value; 6007 6008 /** 6009 * Helpers 6010 */ 6011 6012 const advance = () => input[index++]; 6013 const push = node => { 6014 if (node.type === 'text' && prev.type === 'dot') { 6015 prev.type = 'text'; 6016 } 6017 6018 if (prev && prev.type === 'text' && node.type === 'text') { 6019 prev.value += node.value; 6020 return; 6021 } 6022 6023 block.nodes.push(node); 6024 node.parent = block; 6025 node.prev = prev; 6026 prev = node; 6027 return node; 6028 }; 6029 6030 push({ type: 'bos' }); 6031 6032 while (index < length) { 6033 block = stack[stack.length - 1]; 6034 value = advance(); 6035 6036 /** 6037 * Invalid chars 6038 */ 6039 6040 if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { 6041 continue; 6042 } 6043 6044 /** 6045 * Escaped chars 6046 */ 6047 6048 if (value === CHAR_BACKSLASH) { 6049 push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); 6050 continue; 6051 } 6052 6053 /** 6054 * Right square bracket (literal): ']' 6055 */ 6056 6057 if (value === CHAR_RIGHT_SQUARE_BRACKET) { 6058 push({ type: 'text', value: '\\' + value }); 6059 continue; 6060 } 6061 6062 /** 6063 * Left square bracket: '[' 6064 */ 6065 6066 if (value === CHAR_LEFT_SQUARE_BRACKET) { 6067 brackets++; 6068 6069 let next; 6070 6071 while (index < length && (next = advance())) { 6072 value += next; 6073 6074 if (next === CHAR_LEFT_SQUARE_BRACKET) { 6075 brackets++; 6076 continue; 6077 } 6078 6079 if (next === CHAR_BACKSLASH) { 6080 value += advance(); 6081 continue; 6082 } 6083 6084 if (next === CHAR_RIGHT_SQUARE_BRACKET) { 6085 brackets--; 6086 6087 if (brackets === 0) { 6088 break; 6089 } 6090 } 6091 } 6092 6093 push({ type: 'text', value }); 6094 continue; 6095 } 6096 6097 /** 6098 * Parentheses 6099 */ 6100 6101 if (value === CHAR_LEFT_PARENTHESES) { 6102 block = push({ type: 'paren', nodes: [] }); 6103 stack.push(block); 6104 push({ type: 'text', value }); 6105 continue; 6106 } 6107 6108 if (value === CHAR_RIGHT_PARENTHESES) { 6109 if (block.type !== 'paren') { 6110 push({ type: 'text', value }); 6111 continue; 6112 } 6113 block = stack.pop(); 6114 push({ type: 'text', value }); 6115 block = stack[stack.length - 1]; 6116 continue; 6117 } 6118 6119 /** 6120 * Quotes: '|"|` 6121 */ 6122 6123 if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { 6124 const open = value; 6125 let next; 6126 6127 if (options.keepQuotes !== true) { 6128 value = ''; 6129 } 6130 6131 while (index < length && (next = advance())) { 6132 if (next === CHAR_BACKSLASH) { 6133 value += next + advance(); 6134 continue; 6135 } 6136 6137 if (next === open) { 6138 if (options.keepQuotes === true) value += next; 6139 break; 6140 } 6141 6142 value += next; 6143 } 6144 6145 push({ type: 'text', value }); 6146 continue; 6147 } 6148 6149 /** 6150 * Left curly brace: '{' 6151 */ 6152 6153 if (value === CHAR_LEFT_CURLY_BRACE) { 6154 depth++; 6155 6156 const dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; 6157 const brace = { 6158 type: 'brace', 6159 open: true, 6160 close: false, 6161 dollar, 6162 depth, 6163 commas: 0, 6164 ranges: 0, 6165 nodes: [] 6166 }; 6167 6168 block = push(brace); 6169 stack.push(block); 6170 push({ type: 'open', value }); 6171 continue; 6172 } 6173 6174 /** 6175 * Right curly brace: '}' 6176 */ 6177 6178 if (value === CHAR_RIGHT_CURLY_BRACE) { 6179 if (block.type !== 'brace') { 6180 push({ type: 'text', value }); 6181 continue; 6182 } 6183 6184 const type = 'close'; 6185 block = stack.pop(); 6186 block.close = true; 6187 6188 push({ type, value }); 6189 depth--; 6190 6191 block = stack[stack.length - 1]; 6192 continue; 6193 } 6194 6195 /** 6196 * Comma: ',' 6197 */ 6198 6199 if (value === CHAR_COMMA && depth > 0) { 6200 if (block.ranges > 0) { 6201 block.ranges = 0; 6202 const open = block.nodes.shift(); 6203 block.nodes = [open, { type: 'text', value: stringify(block) }]; 6204 } 6205 6206 push({ type: 'comma', value }); 6207 block.commas++; 6208 continue; 6209 } 6210 6211 /** 6212 * Dot: '.' 6213 */ 6214 6215 if (value === CHAR_DOT && depth > 0 && block.commas === 0) { 6216 const siblings = block.nodes; 6217 6218 if (depth === 0 || siblings.length === 0) { 6219 push({ type: 'text', value }); 6220 continue; 6221 } 6222 6223 if (prev.type === 'dot') { 6224 block.range = []; 6225 prev.value += value; 6226 prev.type = 'range'; 6227 6228 if (block.nodes.length !== 3 && block.nodes.length !== 5) { 6229 block.invalid = true; 6230 block.ranges = 0; 6231 prev.type = 'text'; 6232 continue; 6233 } 6234 6235 block.ranges++; 6236 block.args = []; 6237 continue; 6238 } 6239 6240 if (prev.type === 'range') { 6241 siblings.pop(); 6242 6243 const before = siblings[siblings.length - 1]; 6244 before.value += prev.value + value; 6245 prev = before; 6246 block.ranges--; 6247 continue; 6248 } 6249 6250 push({ type: 'dot', value }); 6251 continue; 6252 } 6253 6254 /** 6255 * Text 6256 */ 6257 6258 push({ type: 'text', value }); 6259 } 6260 6261 // Mark imbalanced braces and brackets as invalid 6262 do { 6263 block = stack.pop(); 6264 6265 if (block.type !== 'root') { 6266 block.nodes.forEach(node => { 6267 if (!node.nodes) { 6268 if (node.type === 'open') node.isOpen = true; 6269 if (node.type === 'close') node.isClose = true; 6270 if (!node.nodes) node.type = 'text'; 6271 node.invalid = true; 6272 } 6273 }); 6274 6275 // get the location of the block on parent.nodes (block's siblings) 6276 const parent = stack[stack.length - 1]; 6277 const index = parent.nodes.indexOf(block); 6278 // replace the (invalid) block with it's nodes 6279 parent.nodes.splice(index, 1, ...block.nodes); 6280 } 6281 } while (stack.length > 0); 6282 6283 push({ type: 'eos' }); 6284 return ast; 6285 }; 6286 6287 parse_1 = parse; 6288 return parse_1; 6289 } 6290 6291 var braces_1; 6292 var hasRequiredBraces; 6293 6294 function requireBraces () { 6295 if (hasRequiredBraces) return braces_1; 6296 hasRequiredBraces = 1; 6297 6298 const stringify = /*@__PURE__*/ requireStringify(); 6299 const compile = /*@__PURE__*/ requireCompile(); 6300 const expand = /*@__PURE__*/ requireExpand(); 6301 const parse = /*@__PURE__*/ requireParse(); 6302 6303 /** 6304 * Expand the given pattern or create a regex-compatible string. 6305 * 6306 * ```js 6307 * const braces = require('braces'); 6308 * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)'] 6309 * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c'] 6310 * ``` 6311 * @param {String} `str` 6312 * @param {Object} `options` 6313 * @return {String} 6314 * @api public 6315 */ 6316 6317 const braces = (input, options = {}) => { 6318 let output = []; 6319 6320 if (Array.isArray(input)) { 6321 for (const pattern of input) { 6322 const result = braces.create(pattern, options); 6323 if (Array.isArray(result)) { 6324 output.push(...result); 6325 } else { 6326 output.push(result); 6327 } 6328 } 6329 } else { 6330 output = [].concat(braces.create(input, options)); 6331 } 6332 6333 if (options && options.expand === true && options.nodupes === true) { 6334 output = [...new Set(output)]; 6335 } 6336 return output; 6337 }; 6338 6339 /** 6340 * Parse the given `str` with the given `options`. 6341 * 6342 * ```js 6343 * // braces.parse(pattern, [, options]); 6344 * const ast = braces.parse('a/{b,c}/d'); 6345 * console.log(ast); 6346 * ``` 6347 * @param {String} pattern Brace pattern to parse 6348 * @param {Object} options 6349 * @return {Object} Returns an AST 6350 * @api public 6351 */ 6352 6353 braces.parse = (input, options = {}) => parse(input, options); 6354 6355 /** 6356 * Creates a braces string from an AST, or an AST node. 6357 * 6358 * ```js 6359 * const braces = require('braces'); 6360 * let ast = braces.parse('foo/{a,b}/bar'); 6361 * console.log(stringify(ast.nodes[2])); //=> '{a,b}' 6362 * ``` 6363 * @param {String} `input` Brace pattern or AST. 6364 * @param {Object} `options` 6365 * @return {Array} Returns an array of expanded values. 6366 * @api public 6367 */ 6368 6369 braces.stringify = (input, options = {}) => { 6370 if (typeof input === 'string') { 6371 return stringify(braces.parse(input, options), options); 6372 } 6373 return stringify(input, options); 6374 }; 6375 6376 /** 6377 * Compiles a brace pattern into a regex-compatible, optimized string. 6378 * This method is called by the main [braces](#braces) function by default. 6379 * 6380 * ```js 6381 * const braces = require('braces'); 6382 * console.log(braces.compile('a/{b,c}/d')); 6383 * //=> ['a/(b|c)/d'] 6384 * ``` 6385 * @param {String} `input` Brace pattern or AST. 6386 * @param {Object} `options` 6387 * @return {Array} Returns an array of expanded values. 6388 * @api public 6389 */ 6390 6391 braces.compile = (input, options = {}) => { 6392 if (typeof input === 'string') { 6393 input = braces.parse(input, options); 6394 } 6395 return compile(input, options); 6396 }; 6397 6398 /** 6399 * Expands a brace pattern into an array. This method is called by the 6400 * main [braces](#braces) function when `options.expand` is true. Before 6401 * using this method it's recommended that you read the [performance notes](#performance)) 6402 * and advantages of using [.compile](#compile) instead. 6403 * 6404 * ```js 6405 * const braces = require('braces'); 6406 * console.log(braces.expand('a/{b,c}/d')); 6407 * //=> ['a/b/d', 'a/c/d']; 6408 * ``` 6409 * @param {String} `pattern` Brace pattern 6410 * @param {Object} `options` 6411 * @return {Array} Returns an array of expanded values. 6412 * @api public 6413 */ 6414 6415 braces.expand = (input, options = {}) => { 6416 if (typeof input === 'string') { 6417 input = braces.parse(input, options); 6418 } 6419 6420 let result = expand(input, options); 6421 6422 // filter out empty strings if specified 6423 if (options.noempty === true) { 6424 result = result.filter(Boolean); 6425 } 6426 6427 // filter out duplicates if specified 6428 if (options.nodupes === true) { 6429 result = [...new Set(result)]; 6430 } 6431 6432 return result; 6433 }; 6434 6435 /** 6436 * Processes a brace pattern and returns either an expanded array 6437 * (if `options.expand` is true), a highly optimized regex-compatible string. 6438 * This method is called by the main [braces](#braces) function. 6439 * 6440 * ```js 6441 * const braces = require('braces'); 6442 * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}')) 6443 * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)' 6444 * ``` 6445 * @param {String} `pattern` Brace pattern 6446 * @param {Object} `options` 6447 * @return {Array} Returns an array of expanded values. 6448 * @api public 6449 */ 6450 6451 braces.create = (input, options = {}) => { 6452 if (input === '' || input.length < 3) { 6453 return [input]; 6454 } 6455 6456 return options.expand !== true 6457 ? braces.compile(input, options) 6458 : braces.expand(input, options); 6459 }; 6460 6461 /** 6462 * Expose "braces" 6463 */ 6464 6465 braces_1 = braces; 6466 return braces_1; 6467 } 2104 6468 2105 6469 const require$$0 = [ … … 2367 6731 ]; 2368 6732 2369 var binaryExtensions$1 = require$$0; 2370 2371 const path = require$$0$2; 2372 const binaryExtensions = binaryExtensions$1; 2373 2374 const extensions = new Set(binaryExtensions); 2375 2376 var isBinaryPath$1 = filePath => extensions.has(path.extname(filePath).slice(1).toLowerCase()); 6733 var binaryExtensions; 6734 var hasRequiredBinaryExtensions; 6735 6736 function requireBinaryExtensions () { 6737 if (hasRequiredBinaryExtensions) return binaryExtensions; 6738 hasRequiredBinaryExtensions = 1; 6739 binaryExtensions = require$$0; 6740 return binaryExtensions; 6741 } 6742 6743 var isBinaryPath; 6744 var hasRequiredIsBinaryPath; 6745 6746 function requireIsBinaryPath () { 6747 if (hasRequiredIsBinaryPath) return isBinaryPath; 6748 hasRequiredIsBinaryPath = 1; 6749 const path = require$$0$1; 6750 const binaryExtensions = /*@__PURE__*/ requireBinaryExtensions(); 6751 6752 const extensions = new Set(binaryExtensions); 6753 6754 isBinaryPath = filePath => extensions.has(path.extname(filePath).slice(1).toLowerCase()); 6755 return isBinaryPath; 6756 } 2377 6757 2378 6758 var constants = {}; 2379 6759 2380 (function (exports) { 2381 2382 const {sep} = require$$0$2; 2383 const {platform} = process; 2384 const os = require$$2$1; 2385 2386 exports.EV_ALL = 'all'; 2387 exports.EV_READY = 'ready'; 2388 exports.EV_ADD = 'add'; 2389 exports.EV_CHANGE = 'change'; 2390 exports.EV_ADD_DIR = 'addDir'; 2391 exports.EV_UNLINK = 'unlink'; 2392 exports.EV_UNLINK_DIR = 'unlinkDir'; 2393 exports.EV_RAW = 'raw'; 2394 exports.EV_ERROR = 'error'; 2395 2396 exports.STR_DATA = 'data'; 2397 exports.STR_END = 'end'; 2398 exports.STR_CLOSE = 'close'; 2399 2400 exports.FSEVENT_CREATED = 'created'; 2401 exports.FSEVENT_MODIFIED = 'modified'; 2402 exports.FSEVENT_DELETED = 'deleted'; 2403 exports.FSEVENT_MOVED = 'moved'; 2404 exports.FSEVENT_CLONED = 'cloned'; 2405 exports.FSEVENT_UNKNOWN = 'unknown'; 2406 exports.FSEVENT_FLAG_MUST_SCAN_SUBDIRS = 1; 2407 exports.FSEVENT_TYPE_FILE = 'file'; 2408 exports.FSEVENT_TYPE_DIRECTORY = 'directory'; 2409 exports.FSEVENT_TYPE_SYMLINK = 'symlink'; 2410 2411 exports.KEY_LISTENERS = 'listeners'; 2412 exports.KEY_ERR = 'errHandlers'; 2413 exports.KEY_RAW = 'rawEmitters'; 2414 exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW]; 2415 2416 exports.DOT_SLASH = `.${sep}`; 2417 2418 exports.BACK_SLASH_RE = /\\/g; 2419 exports.DOUBLE_SLASH_RE = /\/\//; 2420 exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/; 2421 exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; 2422 exports.REPLACER_RE = /^\.[/\\]/; 2423 2424 exports.SLASH = '/'; 2425 exports.SLASH_SLASH = '//'; 2426 exports.BRACE_START = '{'; 2427 exports.BANG = '!'; 2428 exports.ONE_DOT = '.'; 2429 exports.TWO_DOTS = '..'; 2430 exports.STAR = '*'; 2431 exports.GLOBSTAR = '**'; 2432 exports.ROOT_GLOBSTAR = '/**/*'; 2433 exports.SLASH_GLOBSTAR = '/**'; 2434 exports.DIR_SUFFIX = 'Dir'; 2435 exports.ANYMATCH_OPTS = {dot: true}; 2436 exports.STRING_TYPE = 'string'; 2437 exports.FUNCTION_TYPE = 'function'; 2438 exports.EMPTY_STR = ''; 2439 exports.EMPTY_FN = () => {}; 2440 exports.IDENTITY_FN = val => val; 2441 2442 exports.isWindows = platform === 'win32'; 2443 exports.isMacos = platform === 'darwin'; 2444 exports.isLinux = platform === 'linux'; 2445 exports.isIBMi = os.type() === 'OS400'; 2446 } (constants)); 2447 2448 const fs$2 = require$$0$1; 2449 const sysPath$2 = require$$0$2; 2450 const { promisify: promisify$2 } = require$$2; 2451 const isBinaryPath = isBinaryPath$1; 2452 const { 2453 isWindows: isWindows$1, 2454 isLinux, 2455 EMPTY_FN: EMPTY_FN$2, 2456 EMPTY_STR: EMPTY_STR$1, 2457 KEY_LISTENERS, 2458 KEY_ERR, 2459 KEY_RAW, 2460 HANDLER_KEYS, 2461 EV_CHANGE: EV_CHANGE$2, 2462 EV_ADD: EV_ADD$2, 2463 EV_ADD_DIR: EV_ADD_DIR$2, 2464 EV_ERROR: EV_ERROR$2, 2465 STR_DATA: STR_DATA$1, 2466 STR_END: STR_END$2, 2467 BRACE_START: BRACE_START$1, 2468 STAR 2469 } = constants; 2470 2471 const THROTTLE_MODE_WATCH = 'watch'; 2472 2473 const open = promisify$2(fs$2.open); 2474 const stat$2 = promisify$2(fs$2.stat); 2475 const lstat$1 = promisify$2(fs$2.lstat); 2476 const close = promisify$2(fs$2.close); 2477 const fsrealpath = promisify$2(fs$2.realpath); 2478 2479 const statMethods$1 = { lstat: lstat$1, stat: stat$2 }; 2480 2481 // TODO: emit errors properly. Example: EMFILE on Macos. 2482 const foreach = (val, fn) => { 2483 if (val instanceof Set) { 2484 val.forEach(fn); 2485 } else { 2486 fn(val); 2487 } 2488 }; 2489 2490 const addAndConvert = (main, prop, item) => { 2491 let container = main[prop]; 2492 if (!(container instanceof Set)) { 2493 main[prop] = container = new Set([container]); 2494 } 2495 container.add(item); 2496 }; 2497 2498 const clearItem = cont => key => { 2499 const set = cont[key]; 2500 if (set instanceof Set) { 2501 set.clear(); 2502 } else { 2503 delete cont[key]; 2504 } 2505 }; 2506 2507 const delFromSet = (main, prop, item) => { 2508 const container = main[prop]; 2509 if (container instanceof Set) { 2510 container.delete(item); 2511 } else if (container === item) { 2512 delete main[prop]; 2513 } 2514 }; 2515 2516 const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val; 2517 2518 /** 2519 * @typedef {String} Path 2520 */ 2521 2522 // fs_watch helpers 2523 2524 // object to hold per-process fs_watch instances 2525 // (may be shared across chokidar FSWatcher instances) 2526 2527 /** 2528 * @typedef {Object} FsWatchContainer 2529 * @property {Set} listeners 2530 * @property {Set} errHandlers 2531 * @property {Set} rawEmitters 2532 * @property {fs.FSWatcher=} watcher 2533 * @property {Boolean=} watcherUnusable 2534 */ 2535 2536 /** 2537 * @type {Map<String,FsWatchContainer>} 2538 */ 2539 const FsWatchInstances = new Map(); 2540 2541 /** 2542 * Instantiates the fs_watch interface 2543 * @param {String} path to be watched 2544 * @param {Object} options to be passed to fs_watch 2545 * @param {Function} listener main event handler 2546 * @param {Function} errHandler emits info about errors 2547 * @param {Function} emitRaw emits raw event data 2548 * @returns {fs.FSWatcher} new fsevents instance 2549 */ 2550 function createFsWatchInstance(path, options, listener, errHandler, emitRaw) { 2551 const handleEvent = (rawEvent, evPath) => { 2552 listener(path); 2553 emitRaw(rawEvent, evPath, {watchedPath: path}); 2554 2555 // emit based on events occurring for files from a directory's watcher in 2556 // case the file's watcher misses it (and rely on throttling to de-dupe) 2557 if (evPath && path !== evPath) { 2558 fsWatchBroadcast( 2559 sysPath$2.resolve(path, evPath), KEY_LISTENERS, sysPath$2.join(path, evPath) 2560 ); 2561 } 2562 }; 2563 try { 2564 return fs$2.watch(path, options, handleEvent); 2565 } catch (error) { 2566 errHandler(error); 2567 } 6760 var hasRequiredConstants; 6761 6762 function requireConstants () { 6763 if (hasRequiredConstants) return constants; 6764 hasRequiredConstants = 1; 6765 (function (exports) { 6766 6767 const {sep} = require$$0$1; 6768 const {platform} = process; 6769 const os = require$$2$1; 6770 6771 exports.EV_ALL = 'all'; 6772 exports.EV_READY = 'ready'; 6773 exports.EV_ADD = 'add'; 6774 exports.EV_CHANGE = 'change'; 6775 exports.EV_ADD_DIR = 'addDir'; 6776 exports.EV_UNLINK = 'unlink'; 6777 exports.EV_UNLINK_DIR = 'unlinkDir'; 6778 exports.EV_RAW = 'raw'; 6779 exports.EV_ERROR = 'error'; 6780 6781 exports.STR_DATA = 'data'; 6782 exports.STR_END = 'end'; 6783 exports.STR_CLOSE = 'close'; 6784 6785 exports.FSEVENT_CREATED = 'created'; 6786 exports.FSEVENT_MODIFIED = 'modified'; 6787 exports.FSEVENT_DELETED = 'deleted'; 6788 exports.FSEVENT_MOVED = 'moved'; 6789 exports.FSEVENT_CLONED = 'cloned'; 6790 exports.FSEVENT_UNKNOWN = 'unknown'; 6791 exports.FSEVENT_FLAG_MUST_SCAN_SUBDIRS = 1; 6792 exports.FSEVENT_TYPE_FILE = 'file'; 6793 exports.FSEVENT_TYPE_DIRECTORY = 'directory'; 6794 exports.FSEVENT_TYPE_SYMLINK = 'symlink'; 6795 6796 exports.KEY_LISTENERS = 'listeners'; 6797 exports.KEY_ERR = 'errHandlers'; 6798 exports.KEY_RAW = 'rawEmitters'; 6799 exports.HANDLER_KEYS = [exports.KEY_LISTENERS, exports.KEY_ERR, exports.KEY_RAW]; 6800 6801 exports.DOT_SLASH = `.${sep}`; 6802 6803 exports.BACK_SLASH_RE = /\\/g; 6804 exports.DOUBLE_SLASH_RE = /\/\//; 6805 exports.SLASH_OR_BACK_SLASH_RE = /[/\\]/; 6806 exports.DOT_RE = /\..*\.(sw[px])$|~$|\.subl.*\.tmp/; 6807 exports.REPLACER_RE = /^\.[/\\]/; 6808 6809 exports.SLASH = '/'; 6810 exports.SLASH_SLASH = '//'; 6811 exports.BRACE_START = '{'; 6812 exports.BANG = '!'; 6813 exports.ONE_DOT = '.'; 6814 exports.TWO_DOTS = '..'; 6815 exports.STAR = '*'; 6816 exports.GLOBSTAR = '**'; 6817 exports.ROOT_GLOBSTAR = '/**/*'; 6818 exports.SLASH_GLOBSTAR = '/**'; 6819 exports.DIR_SUFFIX = 'Dir'; 6820 exports.ANYMATCH_OPTS = {dot: true}; 6821 exports.STRING_TYPE = 'string'; 6822 exports.FUNCTION_TYPE = 'function'; 6823 exports.EMPTY_STR = ''; 6824 exports.EMPTY_FN = () => {}; 6825 exports.IDENTITY_FN = val => val; 6826 6827 exports.isWindows = platform === 'win32'; 6828 exports.isMacos = platform === 'darwin'; 6829 exports.isLinux = platform === 'linux'; 6830 exports.isIBMi = os.type() === 'OS400'; 6831 } (constants)); 6832 return constants; 2568 6833 } 2569 6834 2570 /** 2571 * Helper for passing fs_watch event data to a collection of listeners 2572 * @param {Path} fullPath absolute path bound to fs_watch instance 2573 * @param {String} type listener type 2574 * @param {*=} val1 arguments to be passed to listeners 2575 * @param {*=} val2 2576 * @param {*=} val3 2577 */ 2578 const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => { 2579 const cont = FsWatchInstances.get(fullPath); 2580 if (!cont) return; 2581 foreach(cont[type], (listener) => { 2582 listener(val1, val2, val3); 2583 }); 2584 }; 2585 2586 /** 2587 * Instantiates the fs_watch interface or binds listeners 2588 * to an existing one covering the same file system entry 2589 * @param {String} path 2590 * @param {String} fullPath absolute path 2591 * @param {Object} options to be passed to fs_watch 2592 * @param {Object} handlers container for event listener functions 2593 */ 2594 const setFsWatchListener = (path, fullPath, options, handlers) => { 2595 const {listener, errHandler, rawEmitter} = handlers; 2596 let cont = FsWatchInstances.get(fullPath); 2597 2598 /** @type {fs.FSWatcher=} */ 2599 let watcher; 2600 if (!options.persistent) { 2601 watcher = createFsWatchInstance( 2602 path, options, listener, errHandler, rawEmitter 2603 ); 2604 return watcher.close.bind(watcher); 2605 } 2606 if (cont) { 2607 addAndConvert(cont, KEY_LISTENERS, listener); 2608 addAndConvert(cont, KEY_ERR, errHandler); 2609 addAndConvert(cont, KEY_RAW, rawEmitter); 2610 } else { 2611 watcher = createFsWatchInstance( 2612 path, 2613 options, 2614 fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), 2615 errHandler, // no need to use broadcast here 2616 fsWatchBroadcast.bind(null, fullPath, KEY_RAW) 2617 ); 2618 if (!watcher) return; 2619 watcher.on(EV_ERROR$2, async (error) => { 2620 const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); 2621 cont.watcherUnusable = true; // documented since Node 10.4.1 2622 // Workaround for https://github.com/joyent/node/issues/4337 2623 if (isWindows$1 && error.code === 'EPERM') { 2624 try { 2625 const fd = await open(path, 'r'); 2626 await close(fd); 2627 broadcastErr(error); 2628 } catch (err) {} 2629 } else { 2630 broadcastErr(error); 2631 } 2632 }); 2633 cont = { 2634 listeners: listener, 2635 errHandlers: errHandler, 2636 rawEmitters: rawEmitter, 2637 watcher 2638 }; 2639 FsWatchInstances.set(fullPath, cont); 2640 } 2641 // const index = cont.listeners.indexOf(listener); 2642 2643 // removes this instance's listeners and closes the underlying fs_watch 2644 // instance if there are no more listeners left 2645 return () => { 2646 delFromSet(cont, KEY_LISTENERS, listener); 2647 delFromSet(cont, KEY_ERR, errHandler); 2648 delFromSet(cont, KEY_RAW, rawEmitter); 2649 if (isEmptySet(cont.listeners)) { 2650 // Check to protect against issue gh-730. 2651 // if (cont.watcherUnusable) { 2652 cont.watcher.close(); 2653 // } 2654 FsWatchInstances.delete(fullPath); 2655 HANDLER_KEYS.forEach(clearItem(cont)); 2656 cont.watcher = undefined; 2657 Object.freeze(cont); 2658 } 2659 }; 2660 }; 2661 2662 // fs_watchFile helpers 2663 2664 // object to hold per-process fs_watchFile instances 2665 // (may be shared across chokidar FSWatcher instances) 2666 const FsWatchFileInstances = new Map(); 2667 2668 /** 2669 * Instantiates the fs_watchFile interface or binds listeners 2670 * to an existing one covering the same file system entry 2671 * @param {String} path to be watched 2672 * @param {String} fullPath absolute path 2673 * @param {Object} options options to be passed to fs_watchFile 2674 * @param {Object} handlers container for event listener functions 2675 * @returns {Function} closer 2676 */ 2677 const setFsWatchFileListener = (path, fullPath, options, handlers) => { 2678 const {listener, rawEmitter} = handlers; 2679 let cont = FsWatchFileInstances.get(fullPath); 2680 2681 const copts = cont && cont.options; 2682 if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { 2683 fs$2.unwatchFile(fullPath); 2684 cont = undefined; 2685 } 2686 2687 /* eslint-enable no-unused-vars, prefer-destructuring */ 2688 2689 if (cont) { 2690 addAndConvert(cont, KEY_LISTENERS, listener); 2691 addAndConvert(cont, KEY_RAW, rawEmitter); 2692 } else { 2693 // TODO 2694 // listeners.add(listener); 2695 // rawEmitters.add(rawEmitter); 2696 cont = { 2697 listeners: listener, 2698 rawEmitters: rawEmitter, 2699 options, 2700 watcher: fs$2.watchFile(fullPath, options, (curr, prev) => { 2701 foreach(cont.rawEmitters, (rawEmitter) => { 2702 rawEmitter(EV_CHANGE$2, fullPath, {curr, prev}); 2703 }); 2704 const currmtime = curr.mtimeMs; 2705 if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { 2706 foreach(cont.listeners, (listener) => listener(path, curr)); 2707 } 2708 }) 2709 }; 2710 FsWatchFileInstances.set(fullPath, cont); 2711 } 2712 // const index = cont.listeners.indexOf(listener); 2713 2714 // Removes this instance's listeners and closes the underlying fs_watchFile 2715 // instance if there are no more listeners left. 2716 return () => { 2717 delFromSet(cont, KEY_LISTENERS, listener); 2718 delFromSet(cont, KEY_RAW, rawEmitter); 2719 if (isEmptySet(cont.listeners)) { 2720 FsWatchFileInstances.delete(fullPath); 2721 fs$2.unwatchFile(fullPath); 2722 cont.options = cont.watcher = undefined; 2723 Object.freeze(cont); 2724 } 2725 }; 2726 }; 2727 2728 /** 2729 * @mixin 2730 */ 2731 let NodeFsHandler$1 = class NodeFsHandler { 2732 2733 /** 2734 * @param {import("../index").FSWatcher} fsW 2735 */ 2736 constructor(fsW) { 2737 this.fsw = fsW; 2738 this._boundHandleError = (error) => fsW._handleError(error); 6835 var nodefsHandler; 6836 var hasRequiredNodefsHandler; 6837 6838 function requireNodefsHandler () { 6839 if (hasRequiredNodefsHandler) return nodefsHandler; 6840 hasRequiredNodefsHandler = 1; 6841 6842 const fs = require$$0$2; 6843 const sysPath = require$$0$1; 6844 const { promisify } = require$$2; 6845 const isBinaryPath = /*@__PURE__*/ requireIsBinaryPath(); 6846 const { 6847 isWindows, 6848 isLinux, 6849 EMPTY_FN, 6850 EMPTY_STR, 6851 KEY_LISTENERS, 6852 KEY_ERR, 6853 KEY_RAW, 6854 HANDLER_KEYS, 6855 EV_CHANGE, 6856 EV_ADD, 6857 EV_ADD_DIR, 6858 EV_ERROR, 6859 STR_DATA, 6860 STR_END, 6861 BRACE_START, 6862 STAR 6863 } = /*@__PURE__*/ requireConstants(); 6864 6865 const THROTTLE_MODE_WATCH = 'watch'; 6866 6867 const open = promisify(fs.open); 6868 const stat = promisify(fs.stat); 6869 const lstat = promisify(fs.lstat); 6870 const close = promisify(fs.close); 6871 const fsrealpath = promisify(fs.realpath); 6872 6873 const statMethods = { lstat, stat }; 6874 6875 // TODO: emit errors properly. Example: EMFILE on Macos. 6876 const foreach = (val, fn) => { 6877 if (val instanceof Set) { 6878 val.forEach(fn); 6879 } else { 6880 fn(val); 6881 } 6882 }; 6883 6884 const addAndConvert = (main, prop, item) => { 6885 let container = main[prop]; 6886 if (!(container instanceof Set)) { 6887 main[prop] = container = new Set([container]); 6888 } 6889 container.add(item); 6890 }; 6891 6892 const clearItem = cont => key => { 6893 const set = cont[key]; 6894 if (set instanceof Set) { 6895 set.clear(); 6896 } else { 6897 delete cont[key]; 6898 } 6899 }; 6900 6901 const delFromSet = (main, prop, item) => { 6902 const container = main[prop]; 6903 if (container instanceof Set) { 6904 container.delete(item); 6905 } else if (container === item) { 6906 delete main[prop]; 6907 } 6908 }; 6909 6910 const isEmptySet = (val) => val instanceof Set ? val.size === 0 : !val; 6911 6912 /** 6913 * @typedef {String} Path 6914 */ 6915 6916 // fs_watch helpers 6917 6918 // object to hold per-process fs_watch instances 6919 // (may be shared across chokidar FSWatcher instances) 6920 6921 /** 6922 * @typedef {Object} FsWatchContainer 6923 * @property {Set} listeners 6924 * @property {Set} errHandlers 6925 * @property {Set} rawEmitters 6926 * @property {fs.FSWatcher=} watcher 6927 * @property {Boolean=} watcherUnusable 6928 */ 6929 6930 /** 6931 * @type {Map<String,FsWatchContainer>} 6932 */ 6933 const FsWatchInstances = new Map(); 6934 6935 /** 6936 * Instantiates the fs_watch interface 6937 * @param {String} path to be watched 6938 * @param {Object} options to be passed to fs_watch 6939 * @param {Function} listener main event handler 6940 * @param {Function} errHandler emits info about errors 6941 * @param {Function} emitRaw emits raw event data 6942 * @returns {fs.FSWatcher} new fsevents instance 6943 */ 6944 function createFsWatchInstance(path, options, listener, errHandler, emitRaw) { 6945 const handleEvent = (rawEvent, evPath) => { 6946 listener(path); 6947 emitRaw(rawEvent, evPath, {watchedPath: path}); 6948 6949 // emit based on events occurring for files from a directory's watcher in 6950 // case the file's watcher misses it (and rely on throttling to de-dupe) 6951 if (evPath && path !== evPath) { 6952 fsWatchBroadcast( 6953 sysPath.resolve(path, evPath), KEY_LISTENERS, sysPath.join(path, evPath) 6954 ); 6955 } 6956 }; 6957 try { 6958 return fs.watch(path, options, handleEvent); 6959 } catch (error) { 6960 errHandler(error); 6961 } 6962 } 6963 6964 /** 6965 * Helper for passing fs_watch event data to a collection of listeners 6966 * @param {Path} fullPath absolute path bound to fs_watch instance 6967 * @param {String} type listener type 6968 * @param {*=} val1 arguments to be passed to listeners 6969 * @param {*=} val2 6970 * @param {*=} val3 6971 */ 6972 const fsWatchBroadcast = (fullPath, type, val1, val2, val3) => { 6973 const cont = FsWatchInstances.get(fullPath); 6974 if (!cont) return; 6975 foreach(cont[type], (listener) => { 6976 listener(val1, val2, val3); 6977 }); 6978 }; 6979 6980 /** 6981 * Instantiates the fs_watch interface or binds listeners 6982 * to an existing one covering the same file system entry 6983 * @param {String} path 6984 * @param {String} fullPath absolute path 6985 * @param {Object} options to be passed to fs_watch 6986 * @param {Object} handlers container for event listener functions 6987 */ 6988 const setFsWatchListener = (path, fullPath, options, handlers) => { 6989 const {listener, errHandler, rawEmitter} = handlers; 6990 let cont = FsWatchInstances.get(fullPath); 6991 6992 /** @type {fs.FSWatcher=} */ 6993 let watcher; 6994 if (!options.persistent) { 6995 watcher = createFsWatchInstance( 6996 path, options, listener, errHandler, rawEmitter 6997 ); 6998 return watcher.close.bind(watcher); 6999 } 7000 if (cont) { 7001 addAndConvert(cont, KEY_LISTENERS, listener); 7002 addAndConvert(cont, KEY_ERR, errHandler); 7003 addAndConvert(cont, KEY_RAW, rawEmitter); 7004 } else { 7005 watcher = createFsWatchInstance( 7006 path, 7007 options, 7008 fsWatchBroadcast.bind(null, fullPath, KEY_LISTENERS), 7009 errHandler, // no need to use broadcast here 7010 fsWatchBroadcast.bind(null, fullPath, KEY_RAW) 7011 ); 7012 if (!watcher) return; 7013 watcher.on(EV_ERROR, async (error) => { 7014 const broadcastErr = fsWatchBroadcast.bind(null, fullPath, KEY_ERR); 7015 cont.watcherUnusable = true; // documented since Node 10.4.1 7016 // Workaround for https://github.com/joyent/node/issues/4337 7017 if (isWindows && error.code === 'EPERM') { 7018 try { 7019 const fd = await open(path, 'r'); 7020 await close(fd); 7021 broadcastErr(error); 7022 } catch (err) {} 7023 } else { 7024 broadcastErr(error); 7025 } 7026 }); 7027 cont = { 7028 listeners: listener, 7029 errHandlers: errHandler, 7030 rawEmitters: rawEmitter, 7031 watcher 7032 }; 7033 FsWatchInstances.set(fullPath, cont); 7034 } 7035 // const index = cont.listeners.indexOf(listener); 7036 7037 // removes this instance's listeners and closes the underlying fs_watch 7038 // instance if there are no more listeners left 7039 return () => { 7040 delFromSet(cont, KEY_LISTENERS, listener); 7041 delFromSet(cont, KEY_ERR, errHandler); 7042 delFromSet(cont, KEY_RAW, rawEmitter); 7043 if (isEmptySet(cont.listeners)) { 7044 // Check to protect against issue gh-730. 7045 // if (cont.watcherUnusable) { 7046 cont.watcher.close(); 7047 // } 7048 FsWatchInstances.delete(fullPath); 7049 HANDLER_KEYS.forEach(clearItem(cont)); 7050 cont.watcher = undefined; 7051 Object.freeze(cont); 7052 } 7053 }; 7054 }; 7055 7056 // fs_watchFile helpers 7057 7058 // object to hold per-process fs_watchFile instances 7059 // (may be shared across chokidar FSWatcher instances) 7060 const FsWatchFileInstances = new Map(); 7061 7062 /** 7063 * Instantiates the fs_watchFile interface or binds listeners 7064 * to an existing one covering the same file system entry 7065 * @param {String} path to be watched 7066 * @param {String} fullPath absolute path 7067 * @param {Object} options options to be passed to fs_watchFile 7068 * @param {Object} handlers container for event listener functions 7069 * @returns {Function} closer 7070 */ 7071 const setFsWatchFileListener = (path, fullPath, options, handlers) => { 7072 const {listener, rawEmitter} = handlers; 7073 let cont = FsWatchFileInstances.get(fullPath); 7074 7075 const copts = cont && cont.options; 7076 if (copts && (copts.persistent < options.persistent || copts.interval > options.interval)) { 7077 fs.unwatchFile(fullPath); 7078 cont = undefined; 7079 } 7080 7081 /* eslint-enable no-unused-vars, prefer-destructuring */ 7082 7083 if (cont) { 7084 addAndConvert(cont, KEY_LISTENERS, listener); 7085 addAndConvert(cont, KEY_RAW, rawEmitter); 7086 } else { 7087 // TODO 7088 // listeners.add(listener); 7089 // rawEmitters.add(rawEmitter); 7090 cont = { 7091 listeners: listener, 7092 rawEmitters: rawEmitter, 7093 options, 7094 watcher: fs.watchFile(fullPath, options, (curr, prev) => { 7095 foreach(cont.rawEmitters, (rawEmitter) => { 7096 rawEmitter(EV_CHANGE, fullPath, {curr, prev}); 7097 }); 7098 const currmtime = curr.mtimeMs; 7099 if (curr.size !== prev.size || currmtime > prev.mtimeMs || currmtime === 0) { 7100 foreach(cont.listeners, (listener) => listener(path, curr)); 7101 } 7102 }) 7103 }; 7104 FsWatchFileInstances.set(fullPath, cont); 7105 } 7106 // const index = cont.listeners.indexOf(listener); 7107 7108 // Removes this instance's listeners and closes the underlying fs_watchFile 7109 // instance if there are no more listeners left. 7110 return () => { 7111 delFromSet(cont, KEY_LISTENERS, listener); 7112 delFromSet(cont, KEY_RAW, rawEmitter); 7113 if (isEmptySet(cont.listeners)) { 7114 FsWatchFileInstances.delete(fullPath); 7115 fs.unwatchFile(fullPath); 7116 cont.options = cont.watcher = undefined; 7117 Object.freeze(cont); 7118 } 7119 }; 7120 }; 7121 7122 /** 7123 * @mixin 7124 */ 7125 class NodeFsHandler { 7126 7127 /** 7128 * @param {import("../index").FSWatcher} fsW 7129 */ 7130 constructor(fsW) { 7131 this.fsw = fsW; 7132 this._boundHandleError = (error) => fsW._handleError(error); 7133 } 7134 7135 /** 7136 * Watch file for changes with fs_watchFile or fs_watch. 7137 * @param {String} path to file or dir 7138 * @param {Function} listener on fs change 7139 * @returns {Function} closer for the watcher instance 7140 */ 7141 _watchWithNodeFs(path, listener) { 7142 const opts = this.fsw.options; 7143 const directory = sysPath.dirname(path); 7144 const basename = sysPath.basename(path); 7145 const parent = this.fsw._getWatchedDir(directory); 7146 parent.add(basename); 7147 const absolutePath = sysPath.resolve(path); 7148 const options = {persistent: opts.persistent}; 7149 if (!listener) listener = EMPTY_FN; 7150 7151 let closer; 7152 if (opts.usePolling) { 7153 options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ? 7154 opts.binaryInterval : opts.interval; 7155 closer = setFsWatchFileListener(path, absolutePath, options, { 7156 listener, 7157 rawEmitter: this.fsw._emitRaw 7158 }); 7159 } else { 7160 closer = setFsWatchListener(path, absolutePath, options, { 7161 listener, 7162 errHandler: this._boundHandleError, 7163 rawEmitter: this.fsw._emitRaw 7164 }); 7165 } 7166 return closer; 7167 } 7168 7169 /** 7170 * Watch a file and emit add event if warranted. 7171 * @param {Path} file Path 7172 * @param {fs.Stats} stats result of fs_stat 7173 * @param {Boolean} initialAdd was the file added at watch instantiation? 7174 * @returns {Function} closer for the watcher instance 7175 */ 7176 _handleFile(file, stats, initialAdd) { 7177 if (this.fsw.closed) { 7178 return; 7179 } 7180 const dirname = sysPath.dirname(file); 7181 const basename = sysPath.basename(file); 7182 const parent = this.fsw._getWatchedDir(dirname); 7183 // stats is always present 7184 let prevStats = stats; 7185 7186 // if the file is already being watched, do nothing 7187 if (parent.has(basename)) return; 7188 7189 const listener = async (path, newStats) => { 7190 if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return; 7191 if (!newStats || newStats.mtimeMs === 0) { 7192 try { 7193 const newStats = await stat(file); 7194 if (this.fsw.closed) return; 7195 // Check that change event was not fired because of changed only accessTime. 7196 const at = newStats.atimeMs; 7197 const mt = newStats.mtimeMs; 7198 if (!at || at <= mt || mt !== prevStats.mtimeMs) { 7199 this.fsw._emit(EV_CHANGE, file, newStats); 7200 } 7201 if (isLinux && prevStats.ino !== newStats.ino) { 7202 this.fsw._closeFile(path); 7203 prevStats = newStats; 7204 this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener)); 7205 } else { 7206 prevStats = newStats; 7207 } 7208 } catch (error) { 7209 // Fix issues where mtime is null but file is still present 7210 this.fsw._remove(dirname, basename); 7211 } 7212 // add is about to be emitted if file not already tracked in parent 7213 } else if (parent.has(basename)) { 7214 // Check that change event was not fired because of changed only accessTime. 7215 const at = newStats.atimeMs; 7216 const mt = newStats.mtimeMs; 7217 if (!at || at <= mt || mt !== prevStats.mtimeMs) { 7218 this.fsw._emit(EV_CHANGE, file, newStats); 7219 } 7220 prevStats = newStats; 7221 } 7222 }; 7223 // kick off the watcher 7224 const closer = this._watchWithNodeFs(file, listener); 7225 7226 // emit an add event if we're supposed to 7227 if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { 7228 if (!this.fsw._throttle(EV_ADD, file, 0)) return; 7229 this.fsw._emit(EV_ADD, file, stats); 7230 } 7231 7232 return closer; 7233 } 7234 7235 /** 7236 * Handle symlinks encountered while reading a dir. 7237 * @param {Object} entry returned by readdirp 7238 * @param {String} directory path of dir being read 7239 * @param {String} path of this item 7240 * @param {String} item basename of this item 7241 * @returns {Promise<Boolean>} true if no more processing is needed for this entry. 7242 */ 7243 async _handleSymlink(entry, directory, path, item) { 7244 if (this.fsw.closed) { 7245 return; 7246 } 7247 const full = entry.fullPath; 7248 const dir = this.fsw._getWatchedDir(directory); 7249 7250 if (!this.fsw.options.followSymlinks) { 7251 // watch symlink directly (don't follow) and detect changes 7252 this.fsw._incrReadyCount(); 7253 7254 let linkPath; 7255 try { 7256 linkPath = await fsrealpath(path); 7257 } catch (e) { 7258 this.fsw._emitReady(); 7259 return true; 7260 } 7261 7262 if (this.fsw.closed) return; 7263 if (dir.has(item)) { 7264 if (this.fsw._symlinkPaths.get(full) !== linkPath) { 7265 this.fsw._symlinkPaths.set(full, linkPath); 7266 this.fsw._emit(EV_CHANGE, path, entry.stats); 7267 } 7268 } else { 7269 dir.add(item); 7270 this.fsw._symlinkPaths.set(full, linkPath); 7271 this.fsw._emit(EV_ADD, path, entry.stats); 7272 } 7273 this.fsw._emitReady(); 7274 return true; 7275 } 7276 7277 // don't follow the same symlink more than once 7278 if (this.fsw._symlinkPaths.has(full)) { 7279 return true; 7280 } 7281 7282 this.fsw._symlinkPaths.set(full, true); 7283 } 7284 7285 _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { 7286 // Normalize the directory name on Windows 7287 directory = sysPath.join(directory, EMPTY_STR); 7288 7289 if (!wh.hasGlob) { 7290 throttler = this.fsw._throttle('readdir', directory, 1000); 7291 if (!throttler) return; 7292 } 7293 7294 const previous = this.fsw._getWatchedDir(wh.path); 7295 const current = new Set(); 7296 7297 let stream = this.fsw._readdirp(directory, { 7298 fileFilter: entry => wh.filterPath(entry), 7299 directoryFilter: entry => wh.filterDir(entry), 7300 depth: 0 7301 }).on(STR_DATA, async (entry) => { 7302 if (this.fsw.closed) { 7303 stream = undefined; 7304 return; 7305 } 7306 const item = entry.path; 7307 let path = sysPath.join(directory, item); 7308 current.add(item); 7309 7310 if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) { 7311 return; 7312 } 7313 7314 if (this.fsw.closed) { 7315 stream = undefined; 7316 return; 7317 } 7318 // Files that present in current directory snapshot 7319 // but absent in previous are added to watch list and 7320 // emit `add` event. 7321 if (item === target || !target && !previous.has(item)) { 7322 this.fsw._incrReadyCount(); 7323 7324 // ensure relativeness of path is preserved in case of watcher reuse 7325 path = sysPath.join(dir, sysPath.relative(dir, path)); 7326 7327 this._addToNodeFs(path, initialAdd, wh, depth + 1); 7328 } 7329 }).on(EV_ERROR, this._boundHandleError); 7330 7331 return new Promise(resolve => 7332 stream.once(STR_END, () => { 7333 if (this.fsw.closed) { 7334 stream = undefined; 7335 return; 7336 } 7337 const wasThrottled = throttler ? throttler.clear() : false; 7338 7339 resolve(); 7340 7341 // Files that absent in current directory snapshot 7342 // but present in previous emit `remove` event 7343 // and are removed from @watched[directory]. 7344 previous.getChildren().filter((item) => { 7345 return item !== directory && 7346 !current.has(item) && 7347 // in case of intersecting globs; 7348 // a path may have been filtered out of this readdir, but 7349 // shouldn't be removed because it matches a different glob 7350 (!wh.hasGlob || wh.filterPath({ 7351 fullPath: sysPath.resolve(directory, item) 7352 })); 7353 }).forEach((item) => { 7354 this.fsw._remove(directory, item); 7355 }); 7356 7357 stream = undefined; 7358 7359 // one more time for any missed in case changes came in extremely quickly 7360 if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler); 7361 }) 7362 ); 7363 } 7364 7365 /** 7366 * Read directory to add / remove files from `@watched` list and re-read it on change. 7367 * @param {String} dir fs path 7368 * @param {fs.Stats} stats 7369 * @param {Boolean} initialAdd 7370 * @param {Number} depth relative to user-supplied path 7371 * @param {String} target child path targeted for watch 7372 * @param {Object} wh Common watch helpers for this path 7373 * @param {String} realpath 7374 * @returns {Promise<Function>} closer for the watcher instance. 7375 */ 7376 async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) { 7377 const parentDir = this.fsw._getWatchedDir(sysPath.dirname(dir)); 7378 const tracked = parentDir.has(sysPath.basename(dir)); 7379 if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { 7380 if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR, dir, stats); 7381 } 7382 7383 // ensure dir is tracked (harmless if redundant) 7384 parentDir.add(sysPath.basename(dir)); 7385 this.fsw._getWatchedDir(dir); 7386 let throttler; 7387 let closer; 7388 7389 const oDepth = this.fsw.options.depth; 7390 if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) { 7391 if (!target) { 7392 await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); 7393 if (this.fsw.closed) return; 7394 } 7395 7396 closer = this._watchWithNodeFs(dir, (dirPath, stats) => { 7397 // if current directory is removed, do nothing 7398 if (stats && stats.mtimeMs === 0) return; 7399 7400 this._handleRead(dirPath, false, wh, target, dir, depth, throttler); 7401 }); 7402 } 7403 return closer; 7404 } 7405 7406 /** 7407 * Handle added file, directory, or glob pattern. 7408 * Delegates call to _handleFile / _handleDir after checks. 7409 * @param {String} path to file or ir 7410 * @param {Boolean} initialAdd was the file added at watch instantiation? 7411 * @param {Object} priorWh depth relative to user-supplied path 7412 * @param {Number} depth Child path actually targeted for watch 7413 * @param {String=} target Child path actually targeted for watch 7414 * @returns {Promise} 7415 */ 7416 async _addToNodeFs(path, initialAdd, priorWh, depth, target) { 7417 const ready = this.fsw._emitReady; 7418 if (this.fsw._isIgnored(path) || this.fsw.closed) { 7419 ready(); 7420 return false; 7421 } 7422 7423 const wh = this.fsw._getWatchHelpers(path, depth); 7424 if (!wh.hasGlob && priorWh) { 7425 wh.hasGlob = priorWh.hasGlob; 7426 wh.globFilter = priorWh.globFilter; 7427 wh.filterPath = entry => priorWh.filterPath(entry); 7428 wh.filterDir = entry => priorWh.filterDir(entry); 7429 } 7430 7431 // evaluate what is at the path we're being asked to watch 7432 try { 7433 const stats = await statMethods[wh.statMethod](wh.watchPath); 7434 if (this.fsw.closed) return; 7435 if (this.fsw._isIgnored(wh.watchPath, stats)) { 7436 ready(); 7437 return false; 7438 } 7439 7440 const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START); 7441 let closer; 7442 if (stats.isDirectory()) { 7443 const absPath = sysPath.resolve(path); 7444 const targetPath = follow ? await fsrealpath(path) : path; 7445 if (this.fsw.closed) return; 7446 closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); 7447 if (this.fsw.closed) return; 7448 // preserve this symlink's target path 7449 if (absPath !== targetPath && targetPath !== undefined) { 7450 this.fsw._symlinkPaths.set(absPath, targetPath); 7451 } 7452 } else if (stats.isSymbolicLink()) { 7453 const targetPath = follow ? await fsrealpath(path) : path; 7454 if (this.fsw.closed) return; 7455 const parent = sysPath.dirname(wh.watchPath); 7456 this.fsw._getWatchedDir(parent).add(wh.watchPath); 7457 this.fsw._emit(EV_ADD, wh.watchPath, stats); 7458 closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath); 7459 if (this.fsw.closed) return; 7460 7461 // preserve this symlink's target path 7462 if (targetPath !== undefined) { 7463 this.fsw._symlinkPaths.set(sysPath.resolve(path), targetPath); 7464 } 7465 } else { 7466 closer = this._handleFile(wh.watchPath, stats, initialAdd); 7467 } 7468 ready(); 7469 7470 this.fsw._addPathCloser(path, closer); 7471 return false; 7472 7473 } catch (error) { 7474 if (this.fsw._handleError(error)) { 7475 ready(); 7476 return path; 7477 } 7478 } 7479 } 7480 7481 } 7482 7483 nodefsHandler = NodeFsHandler; 7484 return nodefsHandler; 2739 7485 } 2740 7486 2741 /** 2742 * Watch file for changes with fs_watchFile or fs_watch. 2743 * @param {String} path to file or dir 2744 * @param {Function} listener on fs change 2745 * @returns {Function} closer for the watcher instance 2746 */ 2747 _watchWithNodeFs(path, listener) { 2748 const opts = this.fsw.options; 2749 const directory = sysPath$2.dirname(path); 2750 const basename = sysPath$2.basename(path); 2751 const parent = this.fsw._getWatchedDir(directory); 2752 parent.add(basename); 2753 const absolutePath = sysPath$2.resolve(path); 2754 const options = {persistent: opts.persistent}; 2755 if (!listener) listener = EMPTY_FN$2; 2756 2757 let closer; 2758 if (opts.usePolling) { 2759 options.interval = opts.enableBinaryInterval && isBinaryPath(basename) ? 2760 opts.binaryInterval : opts.interval; 2761 closer = setFsWatchFileListener(path, absolutePath, options, { 2762 listener, 2763 rawEmitter: this.fsw._emitRaw 2764 }); 2765 } else { 2766 closer = setFsWatchListener(path, absolutePath, options, { 2767 listener, 2768 errHandler: this._boundHandleError, 2769 rawEmitter: this.fsw._emitRaw 2770 }); 2771 } 2772 return closer; 7487 var fseventsHandler = {exports: {}}; 7488 7489 const require$$3 = /*@__PURE__*/getAugmentedNamespace(fseventsImporter); 7490 7491 var hasRequiredFseventsHandler; 7492 7493 function requireFseventsHandler () { 7494 if (hasRequiredFseventsHandler) return fseventsHandler.exports; 7495 hasRequiredFseventsHandler = 1; 7496 7497 const fs = require$$0$2; 7498 const sysPath = require$$0$1; 7499 const { promisify } = require$$2; 7500 7501 let fsevents; 7502 try { 7503 fsevents = require$$3.getFsEvents(); 7504 } catch (error) { 7505 if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error); 7506 } 7507 7508 if (fsevents) { 7509 // TODO: real check 7510 const mtch = process.version.match(/v(\d+)\.(\d+)/); 7511 if (mtch && mtch[1] && mtch[2]) { 7512 const maj = Number.parseInt(mtch[1], 10); 7513 const min = Number.parseInt(mtch[2], 10); 7514 if (maj === 8 && min < 16) { 7515 fsevents = undefined; 7516 } 7517 } 7518 } 7519 7520 const { 7521 EV_ADD, 7522 EV_CHANGE, 7523 EV_ADD_DIR, 7524 EV_UNLINK, 7525 EV_ERROR, 7526 STR_DATA, 7527 STR_END, 7528 FSEVENT_CREATED, 7529 FSEVENT_MODIFIED, 7530 FSEVENT_DELETED, 7531 FSEVENT_MOVED, 7532 // FSEVENT_CLONED, 7533 FSEVENT_UNKNOWN, 7534 FSEVENT_FLAG_MUST_SCAN_SUBDIRS, 7535 FSEVENT_TYPE_FILE, 7536 FSEVENT_TYPE_DIRECTORY, 7537 FSEVENT_TYPE_SYMLINK, 7538 7539 ROOT_GLOBSTAR, 7540 DIR_SUFFIX, 7541 DOT_SLASH, 7542 FUNCTION_TYPE, 7543 EMPTY_FN, 7544 IDENTITY_FN 7545 } = /*@__PURE__*/ requireConstants(); 7546 7547 const Depth = (value) => isNaN(value) ? {} : {depth: value}; 7548 7549 const stat = promisify(fs.stat); 7550 const lstat = promisify(fs.lstat); 7551 const realpath = promisify(fs.realpath); 7552 7553 const statMethods = { stat, lstat }; 7554 7555 /** 7556 * @typedef {String} Path 7557 */ 7558 7559 /** 7560 * @typedef {Object} FsEventsWatchContainer 7561 * @property {Set<Function>} listeners 7562 * @property {Function} rawEmitter 7563 * @property {{stop: Function}} watcher 7564 */ 7565 7566 // fsevents instance helper functions 7567 /** 7568 * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances) 7569 * @type {Map<Path,FsEventsWatchContainer>} 7570 */ 7571 const FSEventsWatchers = new Map(); 7572 7573 // Threshold of duplicate path prefixes at which to start 7574 // consolidating going forward 7575 const consolidateThreshhold = 10; 7576 7577 const wrongEventFlags = new Set([ 7578 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912 7579 ]); 7580 7581 /** 7582 * Instantiates the fsevents interface 7583 * @param {Path} path path to be watched 7584 * @param {Function} callback called when fsevents is bound and ready 7585 * @returns {{stop: Function}} new fsevents instance 7586 */ 7587 const createFSEventsInstance = (path, callback) => { 7588 const stop = fsevents.watch(path, callback); 7589 return {stop}; 7590 }; 7591 7592 /** 7593 * Instantiates the fsevents interface or binds listeners to an existing one covering 7594 * the same file tree. 7595 * @param {Path} path - to be watched 7596 * @param {Path} realPath - real path for symlinks 7597 * @param {Function} listener - called when fsevents emits events 7598 * @param {Function} rawEmitter - passes data to listeners of the 'raw' event 7599 * @returns {Function} closer 7600 */ 7601 function setFSEventsListener(path, realPath, listener, rawEmitter) { 7602 let watchPath = sysPath.extname(realPath) ? sysPath.dirname(realPath) : realPath; 7603 7604 const parentPath = sysPath.dirname(watchPath); 7605 let cont = FSEventsWatchers.get(watchPath); 7606 7607 // If we've accumulated a substantial number of paths that 7608 // could have been consolidated by watching one directory 7609 // above the current one, create a watcher on the parent 7610 // path instead, so that we do consolidate going forward. 7611 if (couldConsolidate(parentPath)) { 7612 watchPath = parentPath; 7613 } 7614 7615 const resolvedPath = sysPath.resolve(path); 7616 const hasSymlink = resolvedPath !== realPath; 7617 7618 const filteredListener = (fullPath, flags, info) => { 7619 if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath); 7620 if ( 7621 fullPath === resolvedPath || 7622 !fullPath.indexOf(resolvedPath + sysPath.sep) 7623 ) listener(fullPath, flags, info); 7624 }; 7625 7626 // check if there is already a watcher on a parent path 7627 // modifies `watchPath` to the parent path when it finds a match 7628 let watchedParent = false; 7629 for (const watchedPath of FSEventsWatchers.keys()) { 7630 if (realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep) === 0) { 7631 watchPath = watchedPath; 7632 cont = FSEventsWatchers.get(watchPath); 7633 watchedParent = true; 7634 break; 7635 } 7636 } 7637 7638 if (cont || watchedParent) { 7639 cont.listeners.add(filteredListener); 7640 } else { 7641 cont = { 7642 listeners: new Set([filteredListener]), 7643 rawEmitter, 7644 watcher: createFSEventsInstance(watchPath, (fullPath, flags) => { 7645 if (!cont.listeners.size) return; 7646 if (flags & FSEVENT_FLAG_MUST_SCAN_SUBDIRS) return; 7647 const info = fsevents.getInfo(fullPath, flags); 7648 cont.listeners.forEach(list => { 7649 list(fullPath, flags, info); 7650 }); 7651 7652 cont.rawEmitter(info.event, fullPath, info); 7653 }) 7654 }; 7655 FSEventsWatchers.set(watchPath, cont); 7656 } 7657 7658 // removes this instance's listeners and closes the underlying fsevents 7659 // instance if there are no more listeners left 7660 return () => { 7661 const lst = cont.listeners; 7662 7663 lst.delete(filteredListener); 7664 if (!lst.size) { 7665 FSEventsWatchers.delete(watchPath); 7666 if (cont.watcher) return cont.watcher.stop().then(() => { 7667 cont.rawEmitter = cont.watcher = undefined; 7668 Object.freeze(cont); 7669 }); 7670 } 7671 }; 7672 } 7673 7674 // Decide whether or not we should start a new higher-level 7675 // parent watcher 7676 const couldConsolidate = (path) => { 7677 let count = 0; 7678 for (const watchPath of FSEventsWatchers.keys()) { 7679 if (watchPath.indexOf(path) === 0) { 7680 count++; 7681 if (count >= consolidateThreshhold) { 7682 return true; 7683 } 7684 } 7685 } 7686 7687 return false; 7688 }; 7689 7690 // returns boolean indicating whether fsevents can be used 7691 const canUse = () => fsevents && FSEventsWatchers.size < 128; 7692 7693 // determines subdirectory traversal levels from root to path 7694 const calcDepth = (path, root) => { 7695 let i = 0; 7696 while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++; 7697 return i; 7698 }; 7699 7700 // returns boolean indicating whether the fsevents' event info has the same type 7701 // as the one returned by fs.stat 7702 const sameTypes = (info, stats) => ( 7703 info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() || 7704 info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() || 7705 info.type === FSEVENT_TYPE_FILE && stats.isFile() 7706 ); 7707 7708 /** 7709 * @mixin 7710 */ 7711 class FsEventsHandler { 7712 7713 /** 7714 * @param {import('../index').FSWatcher} fsw 7715 */ 7716 constructor(fsw) { 7717 this.fsw = fsw; 7718 } 7719 checkIgnored(path, stats) { 7720 const ipaths = this.fsw._ignoredPaths; 7721 if (this.fsw._isIgnored(path, stats)) { 7722 ipaths.add(path); 7723 if (stats && stats.isDirectory()) { 7724 ipaths.add(path + ROOT_GLOBSTAR); 7725 } 7726 return true; 7727 } 7728 7729 ipaths.delete(path); 7730 ipaths.delete(path + ROOT_GLOBSTAR); 7731 } 7732 7733 addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) { 7734 const event = watchedDir.has(item) ? EV_CHANGE : EV_ADD; 7735 this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts); 7736 } 7737 7738 async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) { 7739 try { 7740 const stats = await stat(path); 7741 if (this.fsw.closed) return; 7742 if (sameTypes(info, stats)) { 7743 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7744 } else { 7745 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts); 7746 } 7747 } catch (error) { 7748 if (error.code === 'EACCES') { 7749 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7750 } else { 7751 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts); 7752 } 7753 } 7754 } 7755 7756 handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) { 7757 if (this.fsw.closed || this.checkIgnored(path)) return; 7758 7759 if (event === EV_UNLINK) { 7760 const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY; 7761 // suppress unlink events on never before seen files 7762 if (isDirectory || watchedDir.has(item)) { 7763 this.fsw._remove(parent, item, isDirectory); 7764 } 7765 } else { 7766 if (event === EV_ADD) { 7767 // track new directories 7768 if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path); 7769 7770 if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) { 7771 // push symlinks back to the top of the stack to get handled 7772 const curDepth = opts.depth === undefined ? 7773 undefined : calcDepth(fullPath, realPath) + 1; 7774 return this._addToFsEvents(path, false, true, curDepth); 7775 } 7776 7777 // track new paths 7778 // (other than symlinks being followed, which will be tracked soon) 7779 this.fsw._getWatchedDir(parent).add(item); 7780 } 7781 /** 7782 * @type {'add'|'addDir'|'unlink'|'unlinkDir'} 7783 */ 7784 const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event; 7785 this.fsw._emit(eventName, path); 7786 if (eventName === EV_ADD_DIR) this._addToFsEvents(path, false, true); 7787 } 7788 } 7789 7790 /** 7791 * Handle symlinks encountered during directory scan 7792 * @param {String} watchPath - file/dir path to be watched with fsevents 7793 * @param {String} realPath - real path (in case of symlinks) 7794 * @param {Function} transform - path transformer 7795 * @param {Function} globFilter - path filter in case a glob pattern was provided 7796 * @returns {Function} closer for the watcher instance 7797 */ 7798 _watchWithFsEvents(watchPath, realPath, transform, globFilter) { 7799 if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return; 7800 const opts = this.fsw.options; 7801 const watchCallback = async (fullPath, flags, info) => { 7802 if (this.fsw.closed) return; 7803 if ( 7804 opts.depth !== undefined && 7805 calcDepth(fullPath, realPath) > opts.depth 7806 ) return; 7807 const path = transform(sysPath.join( 7808 watchPath, sysPath.relative(watchPath, fullPath) 7809 )); 7810 if (globFilter && !globFilter(path)) return; 7811 // ensure directories are tracked 7812 const parent = sysPath.dirname(path); 7813 const item = sysPath.basename(path); 7814 const watchedDir = this.fsw._getWatchedDir( 7815 info.type === FSEVENT_TYPE_DIRECTORY ? path : parent 7816 ); 7817 7818 // correct for wrong events emitted 7819 if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) { 7820 if (typeof opts.ignored === FUNCTION_TYPE) { 7821 let stats; 7822 try { 7823 stats = await stat(path); 7824 } catch (error) {} 7825 if (this.fsw.closed) return; 7826 if (this.checkIgnored(path, stats)) return; 7827 if (sameTypes(info, stats)) { 7828 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7829 } else { 7830 this.handleEvent(EV_UNLINK, path, fullPath, realPath, parent, watchedDir, item, info, opts); 7831 } 7832 } else { 7833 this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7834 } 7835 } else { 7836 switch (info.event) { 7837 case FSEVENT_CREATED: 7838 case FSEVENT_MODIFIED: 7839 return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7840 case FSEVENT_DELETED: 7841 case FSEVENT_MOVED: 7842 return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); 7843 } 7844 } 7845 }; 7846 7847 const closer = setFSEventsListener( 7848 watchPath, 7849 realPath, 7850 watchCallback, 7851 this.fsw._emitRaw 7852 ); 7853 7854 this.fsw._emitReady(); 7855 return closer; 7856 } 7857 7858 /** 7859 * Handle symlinks encountered during directory scan 7860 * @param {String} linkPath path to symlink 7861 * @param {String} fullPath absolute path to the symlink 7862 * @param {Function} transform pre-existing path transformer 7863 * @param {Number} curDepth level of subdirectories traversed to where symlink is 7864 * @returns {Promise<void>} 7865 */ 7866 async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) { 7867 // don't follow the same symlink more than once 7868 if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return; 7869 7870 this.fsw._symlinkPaths.set(fullPath, true); 7871 this.fsw._incrReadyCount(); 7872 7873 try { 7874 const linkTarget = await realpath(linkPath); 7875 if (this.fsw.closed) return; 7876 if (this.fsw._isIgnored(linkTarget)) { 7877 return this.fsw._emitReady(); 7878 } 7879 7880 this.fsw._incrReadyCount(); 7881 7882 // add the linkTarget for watching with a wrapper for transform 7883 // that causes emitted paths to incorporate the link's path 7884 this._addToFsEvents(linkTarget || linkPath, (path) => { 7885 let aliasedPath = linkPath; 7886 if (linkTarget && linkTarget !== DOT_SLASH) { 7887 aliasedPath = path.replace(linkTarget, linkPath); 7888 } else if (path !== DOT_SLASH) { 7889 aliasedPath = sysPath.join(linkPath, path); 7890 } 7891 return transform(aliasedPath); 7892 }, false, curDepth); 7893 } catch(error) { 7894 if (this.fsw._handleError(error)) { 7895 return this.fsw._emitReady(); 7896 } 7897 } 7898 } 7899 7900 /** 7901 * 7902 * @param {Path} newPath 7903 * @param {fs.Stats} stats 7904 */ 7905 emitAdd(newPath, stats, processPath, opts, forceAdd) { 7906 const pp = processPath(newPath); 7907 const isDir = stats.isDirectory(); 7908 const dirObj = this.fsw._getWatchedDir(sysPath.dirname(pp)); 7909 const base = sysPath.basename(pp); 7910 7911 // ensure empty dirs get tracked 7912 if (isDir) this.fsw._getWatchedDir(pp); 7913 if (dirObj.has(base)) return; 7914 dirObj.add(base); 7915 7916 if (!opts.ignoreInitial || forceAdd === true) { 7917 this.fsw._emit(isDir ? EV_ADD_DIR : EV_ADD, pp, stats); 7918 } 7919 } 7920 7921 initWatch(realPath, path, wh, processPath) { 7922 if (this.fsw.closed) return; 7923 const closer = this._watchWithFsEvents( 7924 wh.watchPath, 7925 sysPath.resolve(realPath || wh.watchPath), 7926 processPath, 7927 wh.globFilter 7928 ); 7929 this.fsw._addPathCloser(path, closer); 7930 } 7931 7932 /** 7933 * Handle added path with fsevents 7934 * @param {String} path file/dir path or glob pattern 7935 * @param {Function|Boolean=} transform converts working path to what the user expects 7936 * @param {Boolean=} forceAdd ensure add is emitted 7937 * @param {Number=} priorDepth Level of subdirectories already traversed. 7938 * @returns {Promise<void>} 7939 */ 7940 async _addToFsEvents(path, transform, forceAdd, priorDepth) { 7941 if (this.fsw.closed) { 7942 return; 7943 } 7944 const opts = this.fsw.options; 7945 const processPath = typeof transform === FUNCTION_TYPE ? transform : IDENTITY_FN; 7946 7947 const wh = this.fsw._getWatchHelpers(path); 7948 7949 // evaluate what is at the path we're being asked to watch 7950 try { 7951 const stats = await statMethods[wh.statMethod](wh.watchPath); 7952 if (this.fsw.closed) return; 7953 if (this.fsw._isIgnored(wh.watchPath, stats)) { 7954 throw null; 7955 } 7956 if (stats.isDirectory()) { 7957 // emit addDir unless this is a glob parent 7958 if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd); 7959 7960 // don't recurse further if it would exceed depth setting 7961 if (priorDepth && priorDepth > opts.depth) return; 7962 7963 // scan the contents of the dir 7964 this.fsw._readdirp(wh.watchPath, { 7965 fileFilter: entry => wh.filterPath(entry), 7966 directoryFilter: entry => wh.filterDir(entry), 7967 ...Depth(opts.depth - (priorDepth || 0)) 7968 }).on(STR_DATA, (entry) => { 7969 // need to check filterPath on dirs b/c filterDir is less restrictive 7970 if (this.fsw.closed) { 7971 return; 7972 } 7973 if (entry.stats.isDirectory() && !wh.filterPath(entry)) return; 7974 7975 const joinedPath = sysPath.join(wh.watchPath, entry.path); 7976 const {fullPath} = entry; 7977 7978 if (wh.followSymlinks && entry.stats.isSymbolicLink()) { 7979 // preserve the current depth here since it can't be derived from 7980 // real paths past the symlink 7981 const curDepth = opts.depth === undefined ? 7982 undefined : calcDepth(joinedPath, sysPath.resolve(wh.watchPath)) + 1; 7983 7984 this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth); 7985 } else { 7986 this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd); 7987 } 7988 }).on(EV_ERROR, EMPTY_FN).on(STR_END, () => { 7989 this.fsw._emitReady(); 7990 }); 7991 } else { 7992 this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd); 7993 this.fsw._emitReady(); 7994 } 7995 } catch (error) { 7996 if (!error || this.fsw._handleError(error)) { 7997 // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__- 7998 this.fsw._emitReady(); 7999 this.fsw._emitReady(); 8000 } 8001 } 8002 8003 if (opts.persistent && forceAdd !== true) { 8004 if (typeof transform === FUNCTION_TYPE) { 8005 // realpath has already been resolved 8006 this.initWatch(undefined, path, wh, processPath); 8007 } else { 8008 let realPath; 8009 try { 8010 realPath = await realpath(wh.watchPath); 8011 } catch (e) {} 8012 this.initWatch(realPath, path, wh, processPath); 8013 } 8014 } 8015 } 8016 8017 } 8018 8019 fseventsHandler.exports = FsEventsHandler; 8020 fseventsHandler.exports.canUse = canUse; 8021 return fseventsHandler.exports; 2773 8022 } 2774 8023 2775 /** 2776 * Watch a file and emit add event if warranted. 2777 * @param {Path} file Path 2778 * @param {fs.Stats} stats result of fs_stat 2779 * @param {Boolean} initialAdd was the file added at watch instantiation? 2780 * @returns {Function} closer for the watcher instance 2781 */ 2782 _handleFile(file, stats, initialAdd) { 2783 if (this.fsw.closed) { 2784 return; 2785 } 2786 const dirname = sysPath$2.dirname(file); 2787 const basename = sysPath$2.basename(file); 2788 const parent = this.fsw._getWatchedDir(dirname); 2789 // stats is always present 2790 let prevStats = stats; 2791 2792 // if the file is already being watched, do nothing 2793 if (parent.has(basename)) return; 2794 2795 const listener = async (path, newStats) => { 2796 if (!this.fsw._throttle(THROTTLE_MODE_WATCH, file, 5)) return; 2797 if (!newStats || newStats.mtimeMs === 0) { 2798 try { 2799 const newStats = await stat$2(file); 2800 if (this.fsw.closed) return; 2801 // Check that change event was not fired because of changed only accessTime. 2802 const at = newStats.atimeMs; 2803 const mt = newStats.mtimeMs; 2804 if (!at || at <= mt || mt !== prevStats.mtimeMs) { 2805 this.fsw._emit(EV_CHANGE$2, file, newStats); 2806 } 2807 if (isLinux && prevStats.ino !== newStats.ino) { 2808 this.fsw._closeFile(path); 2809 prevStats = newStats; 2810 this.fsw._addPathCloser(path, this._watchWithNodeFs(file, listener)); 2811 } else { 2812 prevStats = newStats; 2813 } 2814 } catch (error) { 2815 // Fix issues where mtime is null but file is still present 2816 this.fsw._remove(dirname, basename); 2817 } 2818 // add is about to be emitted if file not already tracked in parent 2819 } else if (parent.has(basename)) { 2820 // Check that change event was not fired because of changed only accessTime. 2821 const at = newStats.atimeMs; 2822 const mt = newStats.mtimeMs; 2823 if (!at || at <= mt || mt !== prevStats.mtimeMs) { 2824 this.fsw._emit(EV_CHANGE$2, file, newStats); 2825 } 2826 prevStats = newStats; 2827 } 2828 }; 2829 // kick off the watcher 2830 const closer = this._watchWithNodeFs(file, listener); 2831 2832 // emit an add event if we're supposed to 2833 if (!(initialAdd && this.fsw.options.ignoreInitial) && this.fsw._isntIgnored(file)) { 2834 if (!this.fsw._throttle(EV_ADD$2, file, 0)) return; 2835 this.fsw._emit(EV_ADD$2, file, stats); 2836 } 2837 2838 return closer; 8024 var hasRequiredChokidar; 8025 8026 function requireChokidar () { 8027 if (hasRequiredChokidar) return chokidar$1; 8028 hasRequiredChokidar = 1; 8029 8030 const { EventEmitter } = require$$0$3; 8031 const fs = require$$0$2; 8032 const sysPath = require$$0$1; 8033 const { promisify } = require$$2; 8034 const readdirp = /*@__PURE__*/ requireReaddirp(); 8035 const anymatch = /*@__PURE__*/ requireAnymatch().default; 8036 const globParent = /*@__PURE__*/ requireGlobParent(); 8037 const isGlob = /*@__PURE__*/ requireIsGlob(); 8038 const braces = /*@__PURE__*/ requireBraces(); 8039 const normalizePath = /*@__PURE__*/ requireNormalizePath(); 8040 8041 const NodeFsHandler = /*@__PURE__*/ requireNodefsHandler(); 8042 const FsEventsHandler = /*@__PURE__*/ requireFseventsHandler(); 8043 const { 8044 EV_ALL, 8045 EV_READY, 8046 EV_ADD, 8047 EV_CHANGE, 8048 EV_UNLINK, 8049 EV_ADD_DIR, 8050 EV_UNLINK_DIR, 8051 EV_RAW, 8052 EV_ERROR, 8053 8054 STR_CLOSE, 8055 STR_END, 8056 8057 BACK_SLASH_RE, 8058 DOUBLE_SLASH_RE, 8059 SLASH_OR_BACK_SLASH_RE, 8060 DOT_RE, 8061 REPLACER_RE, 8062 8063 SLASH, 8064 SLASH_SLASH, 8065 BRACE_START, 8066 BANG, 8067 ONE_DOT, 8068 TWO_DOTS, 8069 GLOBSTAR, 8070 SLASH_GLOBSTAR, 8071 ANYMATCH_OPTS, 8072 STRING_TYPE, 8073 FUNCTION_TYPE, 8074 EMPTY_STR, 8075 EMPTY_FN, 8076 8077 isWindows, 8078 isMacos, 8079 isIBMi 8080 } = /*@__PURE__*/ requireConstants(); 8081 8082 const stat = promisify(fs.stat); 8083 const readdir = promisify(fs.readdir); 8084 8085 /** 8086 * @typedef {String} Path 8087 * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName 8088 * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType 8089 */ 8090 8091 /** 8092 * 8093 * @typedef {Object} WatchHelpers 8094 * @property {Boolean} followSymlinks 8095 * @property {'stat'|'lstat'} statMethod 8096 * @property {Path} path 8097 * @property {Path} watchPath 8098 * @property {Function} entryPath 8099 * @property {Boolean} hasGlob 8100 * @property {Object} globFilter 8101 * @property {Function} filterPath 8102 * @property {Function} filterDir 8103 */ 8104 8105 const arrify = (value = []) => Array.isArray(value) ? value : [value]; 8106 const flatten = (list, result = []) => { 8107 list.forEach(item => { 8108 if (Array.isArray(item)) { 8109 flatten(item, result); 8110 } else { 8111 result.push(item); 8112 } 8113 }); 8114 return result; 8115 }; 8116 8117 const unifyPaths = (paths_) => { 8118 /** 8119 * @type {Array<String>} 8120 */ 8121 const paths = flatten(arrify(paths_)); 8122 if (!paths.every(p => typeof p === STRING_TYPE)) { 8123 throw new TypeError(`Non-string provided as watch path: ${paths}`); 8124 } 8125 return paths.map(normalizePathToUnix); 8126 }; 8127 8128 // If SLASH_SLASH occurs at the beginning of path, it is not replaced 8129 // because "//StoragePC/DrivePool/Movies" is a valid network path 8130 const toUnix = (string) => { 8131 let str = string.replace(BACK_SLASH_RE, SLASH); 8132 let prepend = false; 8133 if (str.startsWith(SLASH_SLASH)) { 8134 prepend = true; 8135 } 8136 while (str.match(DOUBLE_SLASH_RE)) { 8137 str = str.replace(DOUBLE_SLASH_RE, SLASH); 8138 } 8139 if (prepend) { 8140 str = SLASH + str; 8141 } 8142 return str; 8143 }; 8144 8145 // Our version of upath.normalize 8146 // TODO: this is not equal to path-normalize module - investigate why 8147 const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path))); 8148 8149 const normalizeIgnored = (cwd = EMPTY_STR) => (path) => { 8150 if (typeof path !== STRING_TYPE) return path; 8151 return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path)); 8152 }; 8153 8154 const getAbsolutePath = (path, cwd) => { 8155 if (sysPath.isAbsolute(path)) { 8156 return path; 8157 } 8158 if (path.startsWith(BANG)) { 8159 return BANG + sysPath.join(cwd, path.slice(1)); 8160 } 8161 return sysPath.join(cwd, path); 8162 }; 8163 8164 const undef = (opts, key) => opts[key] === undefined; 8165 8166 /** 8167 * Directory entry. 8168 * @property {Path} path 8169 * @property {Set<Path>} items 8170 */ 8171 class DirEntry { 8172 /** 8173 * @param {Path} dir 8174 * @param {Function} removeWatcher 8175 */ 8176 constructor(dir, removeWatcher) { 8177 this.path = dir; 8178 this._removeWatcher = removeWatcher; 8179 /** @type {Set<Path>} */ 8180 this.items = new Set(); 8181 } 8182 8183 add(item) { 8184 const {items} = this; 8185 if (!items) return; 8186 if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item); 8187 } 8188 8189 async remove(item) { 8190 const {items} = this; 8191 if (!items) return; 8192 items.delete(item); 8193 if (items.size > 0) return; 8194 8195 const dir = this.path; 8196 try { 8197 await readdir(dir); 8198 } catch (err) { 8199 if (this._removeWatcher) { 8200 this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir)); 8201 } 8202 } 8203 } 8204 8205 has(item) { 8206 const {items} = this; 8207 if (!items) return; 8208 return items.has(item); 8209 } 8210 8211 /** 8212 * @returns {Array<String>} 8213 */ 8214 getChildren() { 8215 const {items} = this; 8216 if (!items) return; 8217 return [...items.values()]; 8218 } 8219 8220 dispose() { 8221 this.items.clear(); 8222 delete this.path; 8223 delete this._removeWatcher; 8224 delete this.items; 8225 Object.freeze(this); 8226 } 8227 } 8228 8229 const STAT_METHOD_F = 'stat'; 8230 const STAT_METHOD_L = 'lstat'; 8231 class WatchHelper { 8232 constructor(path, watchPath, follow, fsw) { 8233 this.fsw = fsw; 8234 this.path = path = path.replace(REPLACER_RE, EMPTY_STR); 8235 this.watchPath = watchPath; 8236 this.fullWatchPath = sysPath.resolve(watchPath); 8237 this.hasGlob = watchPath !== path; 8238 /** @type {object|boolean} */ 8239 if (path === EMPTY_STR) this.hasGlob = false; 8240 this.globSymlink = this.hasGlob && follow ? undefined : false; 8241 this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false; 8242 this.dirParts = this.getDirParts(path); 8243 this.dirParts.forEach((parts) => { 8244 if (parts.length > 1) parts.pop(); 8245 }); 8246 this.followSymlinks = follow; 8247 this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; 8248 } 8249 8250 checkGlobSymlink(entry) { 8251 // only need to resolve once 8252 // first entry should always have entry.parentDir === EMPTY_STR 8253 if (this.globSymlink === undefined) { 8254 this.globSymlink = entry.fullParentDir === this.fullWatchPath ? 8255 false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath}; 8256 } 8257 8258 if (this.globSymlink) { 8259 return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath); 8260 } 8261 8262 return entry.fullPath; 8263 } 8264 8265 entryPath(entry) { 8266 return sysPath.join(this.watchPath, 8267 sysPath.relative(this.watchPath, this.checkGlobSymlink(entry)) 8268 ); 8269 } 8270 8271 filterPath(entry) { 8272 const {stats} = entry; 8273 if (stats && stats.isSymbolicLink()) return this.filterDir(entry); 8274 const resolvedPath = this.entryPath(entry); 8275 const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ? 8276 this.globFilter(resolvedPath) : true; 8277 return matchesGlob && 8278 this.fsw._isntIgnored(resolvedPath, stats) && 8279 this.fsw._hasReadPermissions(stats); 8280 } 8281 8282 getDirParts(path) { 8283 if (!this.hasGlob) return []; 8284 const parts = []; 8285 const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path]; 8286 expandedPath.forEach((path) => { 8287 parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE)); 8288 }); 8289 return parts; 8290 } 8291 8292 filterDir(entry) { 8293 if (this.hasGlob) { 8294 const entryParts = this.getDirParts(this.checkGlobSymlink(entry)); 8295 let globstar = false; 8296 this.unmatchedGlob = !this.dirParts.some((parts) => { 8297 return parts.every((part, i) => { 8298 if (part === GLOBSTAR) globstar = true; 8299 return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS); 8300 }); 8301 }); 8302 } 8303 return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats); 8304 } 8305 } 8306 8307 /** 8308 * Watches files & directories for changes. Emitted events: 8309 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` 8310 * 8311 * new FSWatcher() 8312 * .add(directories) 8313 * .on('add', path => log('File', path, 'was added')) 8314 */ 8315 class FSWatcher extends EventEmitter { 8316 // Not indenting methods for history sake; for now. 8317 constructor(_opts) { 8318 super(); 8319 8320 const opts = {}; 8321 if (_opts) Object.assign(opts, _opts); // for frozen objects 8322 8323 /** @type {Map<String, DirEntry>} */ 8324 this._watched = new Map(); 8325 /** @type {Map<String, Array>} */ 8326 this._closers = new Map(); 8327 /** @type {Set<String>} */ 8328 this._ignoredPaths = new Set(); 8329 8330 /** @type {Map<ThrottleType, Map>} */ 8331 this._throttled = new Map(); 8332 8333 /** @type {Map<Path, String|Boolean>} */ 8334 this._symlinkPaths = new Map(); 8335 8336 this._streams = new Set(); 8337 this.closed = false; 8338 8339 // Set up default options. 8340 if (undef(opts, 'persistent')) opts.persistent = true; 8341 if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false; 8342 if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false; 8343 if (undef(opts, 'interval')) opts.interval = 100; 8344 if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300; 8345 if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false; 8346 opts.enableBinaryInterval = opts.binaryInterval !== opts.interval; 8347 8348 // Enable fsevents on OS X when polling isn't explicitly enabled. 8349 if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling; 8350 8351 // If we can't use fsevents, ensure the options reflect it's disabled. 8352 const canUseFsEvents = FsEventsHandler.canUse(); 8353 if (!canUseFsEvents) opts.useFsEvents = false; 8354 8355 // Use polling on Mac if not using fsevents. 8356 // Other platforms use non-polling fs_watch. 8357 if (undef(opts, 'usePolling') && !opts.useFsEvents) { 8358 opts.usePolling = isMacos; 8359 } 8360 8361 // Always default to polling on IBM i because fs.watch() is not available on IBM i. 8362 if(isIBMi) { 8363 opts.usePolling = true; 8364 } 8365 8366 // Global override (useful for end-developers that need to force polling for all 8367 // instances of chokidar, regardless of usage/dependency depth) 8368 const envPoll = process.env.CHOKIDAR_USEPOLLING; 8369 if (envPoll !== undefined) { 8370 const envLower = envPoll.toLowerCase(); 8371 8372 if (envLower === 'false' || envLower === '0') { 8373 opts.usePolling = false; 8374 } else if (envLower === 'true' || envLower === '1') { 8375 opts.usePolling = true; 8376 } else { 8377 opts.usePolling = !!envLower; 8378 } 8379 } 8380 const envInterval = process.env.CHOKIDAR_INTERVAL; 8381 if (envInterval) { 8382 opts.interval = Number.parseInt(envInterval, 10); 8383 } 8384 8385 // Editor atomic write normalization enabled by default with fs.watch 8386 if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents; 8387 if (opts.atomic) this._pendingUnlinks = new Map(); 8388 8389 if (undef(opts, 'followSymlinks')) opts.followSymlinks = true; 8390 8391 if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false; 8392 if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {}; 8393 const awf = opts.awaitWriteFinish; 8394 if (awf) { 8395 if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000; 8396 if (!awf.pollInterval) awf.pollInterval = 100; 8397 this._pendingWrites = new Map(); 8398 } 8399 if (opts.ignored) opts.ignored = arrify(opts.ignored); 8400 8401 let readyCalls = 0; 8402 this._emitReady = () => { 8403 readyCalls++; 8404 if (readyCalls >= this._readyCount) { 8405 this._emitReady = EMPTY_FN; 8406 this._readyEmitted = true; 8407 // use process.nextTick to allow time for listener to be bound 8408 process.nextTick(() => this.emit(EV_READY)); 8409 } 8410 }; 8411 this._emitRaw = (...args) => this.emit(EV_RAW, ...args); 8412 this._readyEmitted = false; 8413 this.options = opts; 8414 8415 // Initialize with proper watcher. 8416 if (opts.useFsEvents) { 8417 this._fsEventsHandler = new FsEventsHandler(this); 8418 } else { 8419 this._nodeFsHandler = new NodeFsHandler(this); 8420 } 8421 8422 // You’re frozen when your heart’s not open. 8423 Object.freeze(opts); 8424 } 8425 8426 // Public methods 8427 8428 /** 8429 * Adds paths to be watched on an existing FSWatcher instance 8430 * @param {Path|Array<Path>} paths_ 8431 * @param {String=} _origAdd private; for handling non-existent paths to be watched 8432 * @param {Boolean=} _internal private; indicates a non-user add 8433 * @returns {FSWatcher} for chaining 8434 */ 8435 add(paths_, _origAdd, _internal) { 8436 const {cwd, disableGlobbing} = this.options; 8437 this.closed = false; 8438 let paths = unifyPaths(paths_); 8439 if (cwd) { 8440 paths = paths.map((path) => { 8441 const absPath = getAbsolutePath(path, cwd); 8442 8443 // Check `path` instead of `absPath` because the cwd portion can't be a glob 8444 if (disableGlobbing || !isGlob(path)) { 8445 return absPath; 8446 } 8447 return normalizePath(absPath); 8448 }); 8449 } 8450 8451 // set aside negated glob strings 8452 paths = paths.filter((path) => { 8453 if (path.startsWith(BANG)) { 8454 this._ignoredPaths.add(path.slice(1)); 8455 return false; 8456 } 8457 8458 // if a path is being added that was previously ignored, stop ignoring it 8459 this._ignoredPaths.delete(path); 8460 this._ignoredPaths.delete(path + SLASH_GLOBSTAR); 8461 8462 // reset the cached userIgnored anymatch fn 8463 // to make ignoredPaths changes effective 8464 this._userIgnored = undefined; 8465 8466 return true; 8467 }); 8468 8469 if (this.options.useFsEvents && this._fsEventsHandler) { 8470 if (!this._readyCount) this._readyCount = paths.length; 8471 if (this.options.persistent) this._readyCount += paths.length; 8472 paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path)); 8473 } else { 8474 if (!this._readyCount) this._readyCount = 0; 8475 this._readyCount += paths.length; 8476 Promise.all( 8477 paths.map(async path => { 8478 const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd); 8479 if (res) this._emitReady(); 8480 return res; 8481 }) 8482 ).then(results => { 8483 if (this.closed) return; 8484 results.filter(item => item).forEach(item => { 8485 this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item)); 8486 }); 8487 }); 8488 } 8489 8490 return this; 8491 } 8492 8493 /** 8494 * Close watchers or start ignoring events from specified paths. 8495 * @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs 8496 * @returns {FSWatcher} for chaining 8497 */ 8498 unwatch(paths_) { 8499 if (this.closed) return this; 8500 const paths = unifyPaths(paths_); 8501 const {cwd} = this.options; 8502 8503 paths.forEach((path) => { 8504 // convert to absolute path unless relative path already matches 8505 if (!sysPath.isAbsolute(path) && !this._closers.has(path)) { 8506 if (cwd) path = sysPath.join(cwd, path); 8507 path = sysPath.resolve(path); 8508 } 8509 8510 this._closePath(path); 8511 8512 this._ignoredPaths.add(path); 8513 if (this._watched.has(path)) { 8514 this._ignoredPaths.add(path + SLASH_GLOBSTAR); 8515 } 8516 8517 // reset the cached userIgnored anymatch fn 8518 // to make ignoredPaths changes effective 8519 this._userIgnored = undefined; 8520 }); 8521 8522 return this; 8523 } 8524 8525 /** 8526 * Close watchers and remove all listeners from watched paths. 8527 * @returns {Promise<void>}. 8528 */ 8529 close() { 8530 if (this.closed) return this._closePromise; 8531 this.closed = true; 8532 8533 // Memory management. 8534 this.removeAllListeners(); 8535 const closers = []; 8536 this._closers.forEach(closerList => closerList.forEach(closer => { 8537 const promise = closer(); 8538 if (promise instanceof Promise) closers.push(promise); 8539 })); 8540 this._streams.forEach(stream => stream.destroy()); 8541 this._userIgnored = undefined; 8542 this._readyCount = 0; 8543 this._readyEmitted = false; 8544 this._watched.forEach(dirent => dirent.dispose()); 8545 ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => { 8546 this[`_${key}`].clear(); 8547 }); 8548 8549 this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve(); 8550 return this._closePromise; 8551 } 8552 8553 /** 8554 * Expose list of watched paths 8555 * @returns {Object} for chaining 8556 */ 8557 getWatched() { 8558 const watchList = {}; 8559 this._watched.forEach((entry, dir) => { 8560 const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir; 8561 watchList[key || ONE_DOT] = entry.getChildren().sort(); 8562 }); 8563 return watchList; 8564 } 8565 8566 emitWithAll(event, args) { 8567 this.emit(...args); 8568 if (event !== EV_ERROR) this.emit(EV_ALL, ...args); 8569 } 8570 8571 // Common helpers 8572 // -------------- 8573 8574 /** 8575 * Normalize and emit events. 8576 * Calling _emit DOES NOT MEAN emit() would be called! 8577 * @param {EventName} event Type of event 8578 * @param {Path} path File or directory path 8579 * @param {*=} val1 arguments to be passed with event 8580 * @param {*=} val2 8581 * @param {*=} val3 8582 * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag 8583 */ 8584 async _emit(event, path, val1, val2, val3) { 8585 if (this.closed) return; 8586 8587 const opts = this.options; 8588 if (isWindows) path = sysPath.normalize(path); 8589 if (opts.cwd) path = sysPath.relative(opts.cwd, path); 8590 /** @type Array<any> */ 8591 const args = [event, path]; 8592 if (val3 !== undefined) args.push(val1, val2, val3); 8593 else if (val2 !== undefined) args.push(val1, val2); 8594 else if (val1 !== undefined) args.push(val1); 8595 8596 const awf = opts.awaitWriteFinish; 8597 let pw; 8598 if (awf && (pw = this._pendingWrites.get(path))) { 8599 pw.lastChange = new Date(); 8600 return this; 8601 } 8602 8603 if (opts.atomic) { 8604 if (event === EV_UNLINK) { 8605 this._pendingUnlinks.set(path, args); 8606 setTimeout(() => { 8607 this._pendingUnlinks.forEach((entry, path) => { 8608 this.emit(...entry); 8609 this.emit(EV_ALL, ...entry); 8610 this._pendingUnlinks.delete(path); 8611 }); 8612 }, typeof opts.atomic === 'number' ? opts.atomic : 100); 8613 return this; 8614 } 8615 if (event === EV_ADD && this._pendingUnlinks.has(path)) { 8616 event = args[0] = EV_CHANGE; 8617 this._pendingUnlinks.delete(path); 8618 } 8619 } 8620 8621 if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) { 8622 const awfEmit = (err, stats) => { 8623 if (err) { 8624 event = args[0] = EV_ERROR; 8625 args[1] = err; 8626 this.emitWithAll(event, args); 8627 } else if (stats) { 8628 // if stats doesn't exist the file must have been deleted 8629 if (args.length > 2) { 8630 args[2] = stats; 8631 } else { 8632 args.push(stats); 8633 } 8634 this.emitWithAll(event, args); 8635 } 8636 }; 8637 8638 this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit); 8639 return this; 8640 } 8641 8642 if (event === EV_CHANGE) { 8643 const isThrottled = !this._throttle(EV_CHANGE, path, 50); 8644 if (isThrottled) return this; 8645 } 8646 8647 if (opts.alwaysStat && val1 === undefined && 8648 (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE) 8649 ) { 8650 const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path; 8651 let stats; 8652 try { 8653 stats = await stat(fullPath); 8654 } catch (err) {} 8655 // Suppress event when fs_stat fails, to avoid sending undefined 'stat' 8656 if (!stats || this.closed) return; 8657 args.push(stats); 8658 } 8659 this.emitWithAll(event, args); 8660 8661 return this; 8662 } 8663 8664 /** 8665 * Common handler for errors 8666 * @param {Error} error 8667 * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag 8668 */ 8669 _handleError(error) { 8670 const code = error && error.code; 8671 if (error && code !== 'ENOENT' && code !== 'ENOTDIR' && 8672 (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES')) 8673 ) { 8674 this.emit(EV_ERROR, error); 8675 } 8676 return error || this.closed; 8677 } 8678 8679 /** 8680 * Helper utility for throttling 8681 * @param {ThrottleType} actionType type being throttled 8682 * @param {Path} path being acted upon 8683 * @param {Number} timeout duration of time to suppress duplicate actions 8684 * @returns {Object|false} tracking object or false if action should be suppressed 8685 */ 8686 _throttle(actionType, path, timeout) { 8687 if (!this._throttled.has(actionType)) { 8688 this._throttled.set(actionType, new Map()); 8689 } 8690 8691 /** @type {Map<Path, Object>} */ 8692 const action = this._throttled.get(actionType); 8693 /** @type {Object} */ 8694 const actionPath = action.get(path); 8695 8696 if (actionPath) { 8697 actionPath.count++; 8698 return false; 8699 } 8700 8701 let timeoutObject; 8702 const clear = () => { 8703 const item = action.get(path); 8704 const count = item ? item.count : 0; 8705 action.delete(path); 8706 clearTimeout(timeoutObject); 8707 if (item) clearTimeout(item.timeoutObject); 8708 return count; 8709 }; 8710 timeoutObject = setTimeout(clear, timeout); 8711 const thr = {timeoutObject, clear, count: 0}; 8712 action.set(path, thr); 8713 return thr; 8714 } 8715 8716 _incrReadyCount() { 8717 return this._readyCount++; 8718 } 8719 8720 /** 8721 * Awaits write operation to finish. 8722 * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. 8723 * @param {Path} path being acted upon 8724 * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished 8725 * @param {EventName} event 8726 * @param {Function} awfEmit Callback to be called when ready for event to be emitted. 8727 */ 8728 _awaitWriteFinish(path, threshold, event, awfEmit) { 8729 let timeoutHandler; 8730 8731 let fullPath = path; 8732 if (this.options.cwd && !sysPath.isAbsolute(path)) { 8733 fullPath = sysPath.join(this.options.cwd, path); 8734 } 8735 8736 const now = new Date(); 8737 8738 const awaitWriteFinish = (prevStat) => { 8739 fs.stat(fullPath, (err, curStat) => { 8740 if (err || !this._pendingWrites.has(path)) { 8741 if (err && err.code !== 'ENOENT') awfEmit(err); 8742 return; 8743 } 8744 8745 const now = Number(new Date()); 8746 8747 if (prevStat && curStat.size !== prevStat.size) { 8748 this._pendingWrites.get(path).lastChange = now; 8749 } 8750 const pw = this._pendingWrites.get(path); 8751 const df = now - pw.lastChange; 8752 8753 if (df >= threshold) { 8754 this._pendingWrites.delete(path); 8755 awfEmit(undefined, curStat); 8756 } else { 8757 timeoutHandler = setTimeout( 8758 awaitWriteFinish, 8759 this.options.awaitWriteFinish.pollInterval, 8760 curStat 8761 ); 8762 } 8763 }); 8764 }; 8765 8766 if (!this._pendingWrites.has(path)) { 8767 this._pendingWrites.set(path, { 8768 lastChange: now, 8769 cancelWait: () => { 8770 this._pendingWrites.delete(path); 8771 clearTimeout(timeoutHandler); 8772 return event; 8773 } 8774 }); 8775 timeoutHandler = setTimeout( 8776 awaitWriteFinish, 8777 this.options.awaitWriteFinish.pollInterval 8778 ); 8779 } 8780 } 8781 8782 _getGlobIgnored() { 8783 return [...this._ignoredPaths.values()]; 8784 } 8785 8786 /** 8787 * Determines whether user has asked to ignore this path. 8788 * @param {Path} path filepath or dir 8789 * @param {fs.Stats=} stats result of fs.stat 8790 * @returns {Boolean} 8791 */ 8792 _isIgnored(path, stats) { 8793 if (this.options.atomic && DOT_RE.test(path)) return true; 8794 if (!this._userIgnored) { 8795 const {cwd} = this.options; 8796 const ign = this.options.ignored; 8797 8798 const ignored = ign && ign.map(normalizeIgnored(cwd)); 8799 const paths = arrify(ignored) 8800 .filter((path) => typeof path === STRING_TYPE && !isGlob(path)) 8801 .map((path) => path + SLASH_GLOBSTAR); 8802 const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths); 8803 this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS); 8804 } 8805 8806 return this._userIgnored([path, stats]); 8807 } 8808 8809 _isntIgnored(path, stat) { 8810 return !this._isIgnored(path, stat); 8811 } 8812 8813 /** 8814 * Provides a set of common helpers and properties relating to symlink and glob handling. 8815 * @param {Path} path file, directory, or glob pattern being watched 8816 * @param {Number=} depth at any depth > 0, this isn't a glob 8817 * @returns {WatchHelper} object containing helpers for this path 8818 */ 8819 _getWatchHelpers(path, depth) { 8820 const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path); 8821 const follow = this.options.followSymlinks; 8822 8823 return new WatchHelper(path, watchPath, follow, this); 8824 } 8825 8826 // Directory helpers 8827 // ----------------- 8828 8829 /** 8830 * Provides directory tracking objects 8831 * @param {String} directory path of the directory 8832 * @returns {DirEntry} the directory's tracking object 8833 */ 8834 _getWatchedDir(directory) { 8835 if (!this._boundRemove) this._boundRemove = this._remove.bind(this); 8836 const dir = sysPath.resolve(directory); 8837 if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove)); 8838 return this._watched.get(dir); 8839 } 8840 8841 // File helpers 8842 // ------------ 8843 8844 /** 8845 * Check for read permissions. 8846 * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405 8847 * @param {fs.Stats} stats - object, result of fs_stat 8848 * @returns {Boolean} indicates whether the file can be read 8849 */ 8850 _hasReadPermissions(stats) { 8851 if (this.options.ignorePermissionErrors) return true; 8852 8853 // stats.mode may be bigint 8854 const md = stats && Number.parseInt(stats.mode, 10); 8855 const st = md & 0o777; 8856 const it = Number.parseInt(st.toString(8)[0], 10); 8857 return Boolean(4 & it); 8858 } 8859 8860 /** 8861 * Handles emitting unlink events for 8862 * files and directories, and via recursion, for 8863 * files and directories within directories that are unlinked 8864 * @param {String} directory within which the following item is located 8865 * @param {String} item base path of item/directory 8866 * @returns {void} 8867 */ 8868 _remove(directory, item, isDirectory) { 8869 // if what is being deleted is a directory, get that directory's paths 8870 // for recursive deleting and cleaning of watched object 8871 // if it is not a directory, nestedDirectoryChildren will be empty array 8872 const path = sysPath.join(directory, item); 8873 const fullPath = sysPath.resolve(path); 8874 isDirectory = isDirectory != null 8875 ? isDirectory 8876 : this._watched.has(path) || this._watched.has(fullPath); 8877 8878 // prevent duplicate handling in case of arriving here nearly simultaneously 8879 // via multiple paths (such as _handleFile and _handleDir) 8880 if (!this._throttle('remove', path, 100)) return; 8881 8882 // if the only watched file is removed, watch for its return 8883 if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) { 8884 this.add(directory, item, true); 8885 } 8886 8887 // This will create a new entry in the watched object in either case 8888 // so we got to do the directory check beforehand 8889 const wp = this._getWatchedDir(path); 8890 const nestedDirectoryChildren = wp.getChildren(); 8891 8892 // Recursively remove children directories / files. 8893 nestedDirectoryChildren.forEach(nested => this._remove(path, nested)); 8894 8895 // Check if item was on the watched list and remove it 8896 const parent = this._getWatchedDir(directory); 8897 const wasTracked = parent.has(item); 8898 parent.remove(item); 8899 8900 // Fixes issue #1042 -> Relative paths were detected and added as symlinks 8901 // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612), 8902 // but never removed from the map in case the path was deleted. 8903 // This leads to an incorrect state if the path was recreated: 8904 // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553 8905 if (this._symlinkPaths.has(fullPath)) { 8906 this._symlinkPaths.delete(fullPath); 8907 } 8908 8909 // If we wait for this file to be fully written, cancel the wait. 8910 let relPath = path; 8911 if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path); 8912 if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { 8913 const event = this._pendingWrites.get(relPath).cancelWait(); 8914 if (event === EV_ADD) return; 8915 } 8916 8917 // The Entry will either be a directory that just got removed 8918 // or a bogus entry to a file, in either case we have to remove it 8919 this._watched.delete(path); 8920 this._watched.delete(fullPath); 8921 const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK; 8922 if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path); 8923 8924 // Avoid conflicts if we later create another file with the same name 8925 if (!this.options.useFsEvents) { 8926 this._closePath(path); 8927 } 8928 } 8929 8930 /** 8931 * Closes all watchers for a path 8932 * @param {Path} path 8933 */ 8934 _closePath(path) { 8935 this._closeFile(path); 8936 const dir = sysPath.dirname(path); 8937 this._getWatchedDir(dir).remove(sysPath.basename(path)); 8938 } 8939 8940 /** 8941 * Closes only file-specific watchers 8942 * @param {Path} path 8943 */ 8944 _closeFile(path) { 8945 const closers = this._closers.get(path); 8946 if (!closers) return; 8947 closers.forEach(closer => closer()); 8948 this._closers.delete(path); 8949 } 8950 8951 /** 8952 * 8953 * @param {Path} path 8954 * @param {Function} closer 8955 */ 8956 _addPathCloser(path, closer) { 8957 if (!closer) return; 8958 let list = this._closers.get(path); 8959 if (!list) { 8960 list = []; 8961 this._closers.set(path, list); 8962 } 8963 list.push(closer); 8964 } 8965 8966 _readdirp(root, opts) { 8967 if (this.closed) return; 8968 const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts}; 8969 let stream = readdirp(root, options); 8970 this._streams.add(stream); 8971 stream.once(STR_CLOSE, () => { 8972 stream = undefined; 8973 }); 8974 stream.once(STR_END, () => { 8975 if (stream) { 8976 this._streams.delete(stream); 8977 stream = undefined; 8978 } 8979 }); 8980 return stream; 8981 } 8982 8983 } 8984 8985 // Export FSWatcher class 8986 chokidar$1.FSWatcher = FSWatcher; 8987 8988 /** 8989 * Instantiates watcher with paths to be tracked. 8990 * @param {String|Array<String>} paths file/directory paths and/or globs 8991 * @param {Object=} options chokidar opts 8992 * @returns an instance of FSWatcher for chaining. 8993 */ 8994 const watch = (paths, options) => { 8995 const watcher = new FSWatcher(options); 8996 watcher.add(paths); 8997 return watcher; 8998 }; 8999 9000 chokidar$1.watch = watch; 9001 return chokidar$1; 2839 9002 } 2840 9003 2841 /** 2842 * Handle symlinks encountered while reading a dir. 2843 * @param {Object} entry returned by readdirp 2844 * @param {String} directory path of dir being read 2845 * @param {String} path of this item 2846 * @param {String} item basename of this item 2847 * @returns {Promise<Boolean>} true if no more processing is needed for this entry. 2848 */ 2849 async _handleSymlink(entry, directory, path, item) { 2850 if (this.fsw.closed) { 2851 return; 2852 } 2853 const full = entry.fullPath; 2854 const dir = this.fsw._getWatchedDir(directory); 2855 2856 if (!this.fsw.options.followSymlinks) { 2857 // watch symlink directly (don't follow) and detect changes 2858 this.fsw._incrReadyCount(); 2859 2860 let linkPath; 2861 try { 2862 linkPath = await fsrealpath(path); 2863 } catch (e) { 2864 this.fsw._emitReady(); 2865 return true; 2866 } 2867 2868 if (this.fsw.closed) return; 2869 if (dir.has(item)) { 2870 if (this.fsw._symlinkPaths.get(full) !== linkPath) { 2871 this.fsw._symlinkPaths.set(full, linkPath); 2872 this.fsw._emit(EV_CHANGE$2, path, entry.stats); 2873 } 2874 } else { 2875 dir.add(item); 2876 this.fsw._symlinkPaths.set(full, linkPath); 2877 this.fsw._emit(EV_ADD$2, path, entry.stats); 2878 } 2879 this.fsw._emitReady(); 2880 return true; 2881 } 2882 2883 // don't follow the same symlink more than once 2884 if (this.fsw._symlinkPaths.has(full)) { 2885 return true; 2886 } 2887 2888 this.fsw._symlinkPaths.set(full, true); 2889 } 2890 2891 _handleRead(directory, initialAdd, wh, target, dir, depth, throttler) { 2892 // Normalize the directory name on Windows 2893 directory = sysPath$2.join(directory, EMPTY_STR$1); 2894 2895 if (!wh.hasGlob) { 2896 throttler = this.fsw._throttle('readdir', directory, 1000); 2897 if (!throttler) return; 2898 } 2899 2900 const previous = this.fsw._getWatchedDir(wh.path); 2901 const current = new Set(); 2902 2903 let stream = this.fsw._readdirp(directory, { 2904 fileFilter: entry => wh.filterPath(entry), 2905 directoryFilter: entry => wh.filterDir(entry), 2906 depth: 0 2907 }).on(STR_DATA$1, async (entry) => { 2908 if (this.fsw.closed) { 2909 stream = undefined; 2910 return; 2911 } 2912 const item = entry.path; 2913 let path = sysPath$2.join(directory, item); 2914 current.add(item); 2915 2916 if (entry.stats.isSymbolicLink() && await this._handleSymlink(entry, directory, path, item)) { 2917 return; 2918 } 2919 2920 if (this.fsw.closed) { 2921 stream = undefined; 2922 return; 2923 } 2924 // Files that present in current directory snapshot 2925 // but absent in previous are added to watch list and 2926 // emit `add` event. 2927 if (item === target || !target && !previous.has(item)) { 2928 this.fsw._incrReadyCount(); 2929 2930 // ensure relativeness of path is preserved in case of watcher reuse 2931 path = sysPath$2.join(dir, sysPath$2.relative(dir, path)); 2932 2933 this._addToNodeFs(path, initialAdd, wh, depth + 1); 2934 } 2935 }).on(EV_ERROR$2, this._boundHandleError); 2936 2937 return new Promise(resolve => 2938 stream.once(STR_END$2, () => { 2939 if (this.fsw.closed) { 2940 stream = undefined; 2941 return; 2942 } 2943 const wasThrottled = throttler ? throttler.clear() : false; 2944 2945 resolve(); 2946 2947 // Files that absent in current directory snapshot 2948 // but present in previous emit `remove` event 2949 // and are removed from @watched[directory]. 2950 previous.getChildren().filter((item) => { 2951 return item !== directory && 2952 !current.has(item) && 2953 // in case of intersecting globs; 2954 // a path may have been filtered out of this readdir, but 2955 // shouldn't be removed because it matches a different glob 2956 (!wh.hasGlob || wh.filterPath({ 2957 fullPath: sysPath$2.resolve(directory, item) 2958 })); 2959 }).forEach((item) => { 2960 this.fsw._remove(directory, item); 2961 }); 2962 2963 stream = undefined; 2964 2965 // one more time for any missed in case changes came in extremely quickly 2966 if (wasThrottled) this._handleRead(directory, false, wh, target, dir, depth, throttler); 2967 }) 2968 ); 2969 } 2970 2971 /** 2972 * Read directory to add / remove files from `@watched` list and re-read it on change. 2973 * @param {String} dir fs path 2974 * @param {fs.Stats} stats 2975 * @param {Boolean} initialAdd 2976 * @param {Number} depth relative to user-supplied path 2977 * @param {String} target child path targeted for watch 2978 * @param {Object} wh Common watch helpers for this path 2979 * @param {String} realpath 2980 * @returns {Promise<Function>} closer for the watcher instance. 2981 */ 2982 async _handleDir(dir, stats, initialAdd, depth, target, wh, realpath) { 2983 const parentDir = this.fsw._getWatchedDir(sysPath$2.dirname(dir)); 2984 const tracked = parentDir.has(sysPath$2.basename(dir)); 2985 if (!(initialAdd && this.fsw.options.ignoreInitial) && !target && !tracked) { 2986 if (!wh.hasGlob || wh.globFilter(dir)) this.fsw._emit(EV_ADD_DIR$2, dir, stats); 2987 } 2988 2989 // ensure dir is tracked (harmless if redundant) 2990 parentDir.add(sysPath$2.basename(dir)); 2991 this.fsw._getWatchedDir(dir); 2992 let throttler; 2993 let closer; 2994 2995 const oDepth = this.fsw.options.depth; 2996 if ((oDepth == null || depth <= oDepth) && !this.fsw._symlinkPaths.has(realpath)) { 2997 if (!target) { 2998 await this._handleRead(dir, initialAdd, wh, target, dir, depth, throttler); 2999 if (this.fsw.closed) return; 3000 } 3001 3002 closer = this._watchWithNodeFs(dir, (dirPath, stats) => { 3003 // if current directory is removed, do nothing 3004 if (stats && stats.mtimeMs === 0) return; 3005 3006 this._handleRead(dirPath, false, wh, target, dir, depth, throttler); 3007 }); 3008 } 3009 return closer; 3010 } 3011 3012 /** 3013 * Handle added file, directory, or glob pattern. 3014 * Delegates call to _handleFile / _handleDir after checks. 3015 * @param {String} path to file or ir 3016 * @param {Boolean} initialAdd was the file added at watch instantiation? 3017 * @param {Object} priorWh depth relative to user-supplied path 3018 * @param {Number} depth Child path actually targeted for watch 3019 * @param {String=} target Child path actually targeted for watch 3020 * @returns {Promise} 3021 */ 3022 async _addToNodeFs(path, initialAdd, priorWh, depth, target) { 3023 const ready = this.fsw._emitReady; 3024 if (this.fsw._isIgnored(path) || this.fsw.closed) { 3025 ready(); 3026 return false; 3027 } 3028 3029 const wh = this.fsw._getWatchHelpers(path, depth); 3030 if (!wh.hasGlob && priorWh) { 3031 wh.hasGlob = priorWh.hasGlob; 3032 wh.globFilter = priorWh.globFilter; 3033 wh.filterPath = entry => priorWh.filterPath(entry); 3034 wh.filterDir = entry => priorWh.filterDir(entry); 3035 } 3036 3037 // evaluate what is at the path we're being asked to watch 3038 try { 3039 const stats = await statMethods$1[wh.statMethod](wh.watchPath); 3040 if (this.fsw.closed) return; 3041 if (this.fsw._isIgnored(wh.watchPath, stats)) { 3042 ready(); 3043 return false; 3044 } 3045 3046 const follow = this.fsw.options.followSymlinks && !path.includes(STAR) && !path.includes(BRACE_START$1); 3047 let closer; 3048 if (stats.isDirectory()) { 3049 const absPath = sysPath$2.resolve(path); 3050 const targetPath = follow ? await fsrealpath(path) : path; 3051 if (this.fsw.closed) return; 3052 closer = await this._handleDir(wh.watchPath, stats, initialAdd, depth, target, wh, targetPath); 3053 if (this.fsw.closed) return; 3054 // preserve this symlink's target path 3055 if (absPath !== targetPath && targetPath !== undefined) { 3056 this.fsw._symlinkPaths.set(absPath, targetPath); 3057 } 3058 } else if (stats.isSymbolicLink()) { 3059 const targetPath = follow ? await fsrealpath(path) : path; 3060 if (this.fsw.closed) return; 3061 const parent = sysPath$2.dirname(wh.watchPath); 3062 this.fsw._getWatchedDir(parent).add(wh.watchPath); 3063 this.fsw._emit(EV_ADD$2, wh.watchPath, stats); 3064 closer = await this._handleDir(parent, stats, initialAdd, depth, path, wh, targetPath); 3065 if (this.fsw.closed) return; 3066 3067 // preserve this symlink's target path 3068 if (targetPath !== undefined) { 3069 this.fsw._symlinkPaths.set(sysPath$2.resolve(path), targetPath); 3070 } 3071 } else { 3072 closer = this._handleFile(wh.watchPath, stats, initialAdd); 3073 } 3074 ready(); 3075 3076 this.fsw._addPathCloser(path, closer); 3077 return false; 3078 3079 } catch (error) { 3080 if (this.fsw._handleError(error)) { 3081 ready(); 3082 return path; 3083 } 3084 } 3085 } 3086 3087 }; 3088 3089 var nodefsHandler = NodeFsHandler$1; 3090 3091 var fseventsHandler = {exports: {}}; 3092 3093 const require$$3 = /*@__PURE__*/getAugmentedNamespace(fseventsImporter); 3094 3095 const fs$1 = require$$0$1; 3096 const sysPath$1 = require$$0$2; 3097 const { promisify: promisify$1 } = require$$2; 3098 3099 let fsevents; 3100 try { 3101 fsevents = require$$3.getFsEvents(); 3102 } catch (error) { 3103 if (process.env.CHOKIDAR_PRINT_FSEVENTS_REQUIRE_ERROR) console.error(error); 3104 } 3105 3106 if (fsevents) { 3107 // TODO: real check 3108 const mtch = process.version.match(/v(\d+)\.(\d+)/); 3109 if (mtch && mtch[1] && mtch[2]) { 3110 const maj = Number.parseInt(mtch[1], 10); 3111 const min = Number.parseInt(mtch[2], 10); 3112 if (maj === 8 && min < 16) { 3113 fsevents = undefined; 3114 } 3115 } 3116 } 3117 3118 const { 3119 EV_ADD: EV_ADD$1, 3120 EV_CHANGE: EV_CHANGE$1, 3121 EV_ADD_DIR: EV_ADD_DIR$1, 3122 EV_UNLINK: EV_UNLINK$1, 3123 EV_ERROR: EV_ERROR$1, 3124 STR_DATA, 3125 STR_END: STR_END$1, 3126 FSEVENT_CREATED, 3127 FSEVENT_MODIFIED, 3128 FSEVENT_DELETED, 3129 FSEVENT_MOVED, 3130 // FSEVENT_CLONED, 3131 FSEVENT_UNKNOWN, 3132 FSEVENT_FLAG_MUST_SCAN_SUBDIRS, 3133 FSEVENT_TYPE_FILE, 3134 FSEVENT_TYPE_DIRECTORY, 3135 FSEVENT_TYPE_SYMLINK, 3136 3137 ROOT_GLOBSTAR, 3138 DIR_SUFFIX, 3139 DOT_SLASH, 3140 FUNCTION_TYPE: FUNCTION_TYPE$1, 3141 EMPTY_FN: EMPTY_FN$1, 3142 IDENTITY_FN 3143 } = constants; 3144 3145 const Depth = (value) => isNaN(value) ? {} : {depth: value}; 3146 3147 const stat$1 = promisify$1(fs$1.stat); 3148 const lstat = promisify$1(fs$1.lstat); 3149 const realpath = promisify$1(fs$1.realpath); 3150 3151 const statMethods = { stat: stat$1, lstat }; 3152 3153 /** 3154 * @typedef {String} Path 3155 */ 3156 3157 /** 3158 * @typedef {Object} FsEventsWatchContainer 3159 * @property {Set<Function>} listeners 3160 * @property {Function} rawEmitter 3161 * @property {{stop: Function}} watcher 3162 */ 3163 3164 // fsevents instance helper functions 3165 /** 3166 * Object to hold per-process fsevents instances (may be shared across chokidar FSWatcher instances) 3167 * @type {Map<Path,FsEventsWatchContainer>} 3168 */ 3169 const FSEventsWatchers = new Map(); 3170 3171 // Threshold of duplicate path prefixes at which to start 3172 // consolidating going forward 3173 const consolidateThreshhold = 10; 3174 3175 const wrongEventFlags = new Set([ 3176 69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912 3177 ]); 3178 3179 /** 3180 * Instantiates the fsevents interface 3181 * @param {Path} path path to be watched 3182 * @param {Function} callback called when fsevents is bound and ready 3183 * @returns {{stop: Function}} new fsevents instance 3184 */ 3185 const createFSEventsInstance = (path, callback) => { 3186 const stop = fsevents.watch(path, callback); 3187 return {stop}; 3188 }; 3189 3190 /** 3191 * Instantiates the fsevents interface or binds listeners to an existing one covering 3192 * the same file tree. 3193 * @param {Path} path - to be watched 3194 * @param {Path} realPath - real path for symlinks 3195 * @param {Function} listener - called when fsevents emits events 3196 * @param {Function} rawEmitter - passes data to listeners of the 'raw' event 3197 * @returns {Function} closer 3198 */ 3199 function setFSEventsListener(path, realPath, listener, rawEmitter) { 3200 let watchPath = sysPath$1.extname(realPath) ? sysPath$1.dirname(realPath) : realPath; 3201 3202 const parentPath = sysPath$1.dirname(watchPath); 3203 let cont = FSEventsWatchers.get(watchPath); 3204 3205 // If we've accumulated a substantial number of paths that 3206 // could have been consolidated by watching one directory 3207 // above the current one, create a watcher on the parent 3208 // path instead, so that we do consolidate going forward. 3209 if (couldConsolidate(parentPath)) { 3210 watchPath = parentPath; 3211 } 3212 3213 const resolvedPath = sysPath$1.resolve(path); 3214 const hasSymlink = resolvedPath !== realPath; 3215 3216 const filteredListener = (fullPath, flags, info) => { 3217 if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath); 3218 if ( 3219 fullPath === resolvedPath || 3220 !fullPath.indexOf(resolvedPath + sysPath$1.sep) 3221 ) listener(fullPath, flags, info); 3222 }; 3223 3224 // check if there is already a watcher on a parent path 3225 // modifies `watchPath` to the parent path when it finds a match 3226 let watchedParent = false; 3227 for (const watchedPath of FSEventsWatchers.keys()) { 3228 if (realPath.indexOf(sysPath$1.resolve(watchedPath) + sysPath$1.sep) === 0) { 3229 watchPath = watchedPath; 3230 cont = FSEventsWatchers.get(watchPath); 3231 watchedParent = true; 3232 break; 3233 } 3234 } 3235 3236 if (cont || watchedParent) { 3237 cont.listeners.add(filteredListener); 3238 } else { 3239 cont = { 3240 listeners: new Set([filteredListener]), 3241 rawEmitter, 3242 watcher: createFSEventsInstance(watchPath, (fullPath, flags) => { 3243 if (!cont.listeners.size) return; 3244 if (flags & FSEVENT_FLAG_MUST_SCAN_SUBDIRS) return; 3245 const info = fsevents.getInfo(fullPath, flags); 3246 cont.listeners.forEach(list => { 3247 list(fullPath, flags, info); 3248 }); 3249 3250 cont.rawEmitter(info.event, fullPath, info); 3251 }) 3252 }; 3253 FSEventsWatchers.set(watchPath, cont); 3254 } 3255 3256 // removes this instance's listeners and closes the underlying fsevents 3257 // instance if there are no more listeners left 3258 return () => { 3259 const lst = cont.listeners; 3260 3261 lst.delete(filteredListener); 3262 if (!lst.size) { 3263 FSEventsWatchers.delete(watchPath); 3264 if (cont.watcher) return cont.watcher.stop().then(() => { 3265 cont.rawEmitter = cont.watcher = undefined; 3266 Object.freeze(cont); 3267 }); 3268 } 3269 }; 3270 } 3271 3272 // Decide whether or not we should start a new higher-level 3273 // parent watcher 3274 const couldConsolidate = (path) => { 3275 let count = 0; 3276 for (const watchPath of FSEventsWatchers.keys()) { 3277 if (watchPath.indexOf(path) === 0) { 3278 count++; 3279 if (count >= consolidateThreshhold) { 3280 return true; 3281 } 3282 } 3283 } 3284 3285 return false; 3286 }; 3287 3288 // returns boolean indicating whether fsevents can be used 3289 const canUse = () => fsevents && FSEventsWatchers.size < 128; 3290 3291 // determines subdirectory traversal levels from root to path 3292 const calcDepth = (path, root) => { 3293 let i = 0; 3294 while (!path.indexOf(root) && (path = sysPath$1.dirname(path)) !== root) i++; 3295 return i; 3296 }; 3297 3298 // returns boolean indicating whether the fsevents' event info has the same type 3299 // as the one returned by fs.stat 3300 const sameTypes = (info, stats) => ( 3301 info.type === FSEVENT_TYPE_DIRECTORY && stats.isDirectory() || 3302 info.type === FSEVENT_TYPE_SYMLINK && stats.isSymbolicLink() || 3303 info.type === FSEVENT_TYPE_FILE && stats.isFile() 3304 ); 3305 3306 /** 3307 * @mixin 3308 */ 3309 let FsEventsHandler$1 = class FsEventsHandler { 3310 3311 /** 3312 * @param {import('../index').FSWatcher} fsw 3313 */ 3314 constructor(fsw) { 3315 this.fsw = fsw; 3316 } 3317 checkIgnored(path, stats) { 3318 const ipaths = this.fsw._ignoredPaths; 3319 if (this.fsw._isIgnored(path, stats)) { 3320 ipaths.add(path); 3321 if (stats && stats.isDirectory()) { 3322 ipaths.add(path + ROOT_GLOBSTAR); 3323 } 3324 return true; 3325 } 3326 3327 ipaths.delete(path); 3328 ipaths.delete(path + ROOT_GLOBSTAR); 3329 } 3330 3331 addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts) { 3332 const event = watchedDir.has(item) ? EV_CHANGE$1 : EV_ADD$1; 3333 this.handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts); 3334 } 3335 3336 async checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts) { 3337 try { 3338 const stats = await stat$1(path); 3339 if (this.fsw.closed) return; 3340 if (sameTypes(info, stats)) { 3341 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3342 } else { 3343 this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); 3344 } 3345 } catch (error) { 3346 if (error.code === 'EACCES') { 3347 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3348 } else { 3349 this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); 3350 } 3351 } 3352 } 3353 3354 handleEvent(event, path, fullPath, realPath, parent, watchedDir, item, info, opts) { 3355 if (this.fsw.closed || this.checkIgnored(path)) return; 3356 3357 if (event === EV_UNLINK$1) { 3358 const isDirectory = info.type === FSEVENT_TYPE_DIRECTORY; 3359 // suppress unlink events on never before seen files 3360 if (isDirectory || watchedDir.has(item)) { 3361 this.fsw._remove(parent, item, isDirectory); 3362 } 3363 } else { 3364 if (event === EV_ADD$1) { 3365 // track new directories 3366 if (info.type === FSEVENT_TYPE_DIRECTORY) this.fsw._getWatchedDir(path); 3367 3368 if (info.type === FSEVENT_TYPE_SYMLINK && opts.followSymlinks) { 3369 // push symlinks back to the top of the stack to get handled 3370 const curDepth = opts.depth === undefined ? 3371 undefined : calcDepth(fullPath, realPath) + 1; 3372 return this._addToFsEvents(path, false, true, curDepth); 3373 } 3374 3375 // track new paths 3376 // (other than symlinks being followed, which will be tracked soon) 3377 this.fsw._getWatchedDir(parent).add(item); 3378 } 3379 /** 3380 * @type {'add'|'addDir'|'unlink'|'unlinkDir'} 3381 */ 3382 const eventName = info.type === FSEVENT_TYPE_DIRECTORY ? event + DIR_SUFFIX : event; 3383 this.fsw._emit(eventName, path); 3384 if (eventName === EV_ADD_DIR$1) this._addToFsEvents(path, false, true); 3385 } 3386 } 3387 3388 /** 3389 * Handle symlinks encountered during directory scan 3390 * @param {String} watchPath - file/dir path to be watched with fsevents 3391 * @param {String} realPath - real path (in case of symlinks) 3392 * @param {Function} transform - path transformer 3393 * @param {Function} globFilter - path filter in case a glob pattern was provided 3394 * @returns {Function} closer for the watcher instance 3395 */ 3396 _watchWithFsEvents(watchPath, realPath, transform, globFilter) { 3397 if (this.fsw.closed || this.fsw._isIgnored(watchPath)) return; 3398 const opts = this.fsw.options; 3399 const watchCallback = async (fullPath, flags, info) => { 3400 if (this.fsw.closed) return; 3401 if ( 3402 opts.depth !== undefined && 3403 calcDepth(fullPath, realPath) > opts.depth 3404 ) return; 3405 const path = transform(sysPath$1.join( 3406 watchPath, sysPath$1.relative(watchPath, fullPath) 3407 )); 3408 if (globFilter && !globFilter(path)) return; 3409 // ensure directories are tracked 3410 const parent = sysPath$1.dirname(path); 3411 const item = sysPath$1.basename(path); 3412 const watchedDir = this.fsw._getWatchedDir( 3413 info.type === FSEVENT_TYPE_DIRECTORY ? path : parent 3414 ); 3415 3416 // correct for wrong events emitted 3417 if (wrongEventFlags.has(flags) || info.event === FSEVENT_UNKNOWN) { 3418 if (typeof opts.ignored === FUNCTION_TYPE$1) { 3419 let stats; 3420 try { 3421 stats = await stat$1(path); 3422 } catch (error) {} 3423 if (this.fsw.closed) return; 3424 if (this.checkIgnored(path, stats)) return; 3425 if (sameTypes(info, stats)) { 3426 this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3427 } else { 3428 this.handleEvent(EV_UNLINK$1, path, fullPath, realPath, parent, watchedDir, item, info, opts); 3429 } 3430 } else { 3431 this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3432 } 3433 } else { 3434 switch (info.event) { 3435 case FSEVENT_CREATED: 3436 case FSEVENT_MODIFIED: 3437 return this.addOrChange(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3438 case FSEVENT_DELETED: 3439 case FSEVENT_MOVED: 3440 return this.checkExists(path, fullPath, realPath, parent, watchedDir, item, info, opts); 3441 } 3442 } 3443 }; 3444 3445 const closer = setFSEventsListener( 3446 watchPath, 3447 realPath, 3448 watchCallback, 3449 this.fsw._emitRaw 3450 ); 3451 3452 this.fsw._emitReady(); 3453 return closer; 3454 } 3455 3456 /** 3457 * Handle symlinks encountered during directory scan 3458 * @param {String} linkPath path to symlink 3459 * @param {String} fullPath absolute path to the symlink 3460 * @param {Function} transform pre-existing path transformer 3461 * @param {Number} curDepth level of subdirectories traversed to where symlink is 3462 * @returns {Promise<void>} 3463 */ 3464 async _handleFsEventsSymlink(linkPath, fullPath, transform, curDepth) { 3465 // don't follow the same symlink more than once 3466 if (this.fsw.closed || this.fsw._symlinkPaths.has(fullPath)) return; 3467 3468 this.fsw._symlinkPaths.set(fullPath, true); 3469 this.fsw._incrReadyCount(); 3470 3471 try { 3472 const linkTarget = await realpath(linkPath); 3473 if (this.fsw.closed) return; 3474 if (this.fsw._isIgnored(linkTarget)) { 3475 return this.fsw._emitReady(); 3476 } 3477 3478 this.fsw._incrReadyCount(); 3479 3480 // add the linkTarget for watching with a wrapper for transform 3481 // that causes emitted paths to incorporate the link's path 3482 this._addToFsEvents(linkTarget || linkPath, (path) => { 3483 let aliasedPath = linkPath; 3484 if (linkTarget && linkTarget !== DOT_SLASH) { 3485 aliasedPath = path.replace(linkTarget, linkPath); 3486 } else if (path !== DOT_SLASH) { 3487 aliasedPath = sysPath$1.join(linkPath, path); 3488 } 3489 return transform(aliasedPath); 3490 }, false, curDepth); 3491 } catch(error) { 3492 if (this.fsw._handleError(error)) { 3493 return this.fsw._emitReady(); 3494 } 3495 } 3496 } 3497 3498 /** 3499 * 3500 * @param {Path} newPath 3501 * @param {fs.Stats} stats 3502 */ 3503 emitAdd(newPath, stats, processPath, opts, forceAdd) { 3504 const pp = processPath(newPath); 3505 const isDir = stats.isDirectory(); 3506 const dirObj = this.fsw._getWatchedDir(sysPath$1.dirname(pp)); 3507 const base = sysPath$1.basename(pp); 3508 3509 // ensure empty dirs get tracked 3510 if (isDir) this.fsw._getWatchedDir(pp); 3511 if (dirObj.has(base)) return; 3512 dirObj.add(base); 3513 3514 if (!opts.ignoreInitial || forceAdd === true) { 3515 this.fsw._emit(isDir ? EV_ADD_DIR$1 : EV_ADD$1, pp, stats); 3516 } 3517 } 3518 3519 initWatch(realPath, path, wh, processPath) { 3520 if (this.fsw.closed) return; 3521 const closer = this._watchWithFsEvents( 3522 wh.watchPath, 3523 sysPath$1.resolve(realPath || wh.watchPath), 3524 processPath, 3525 wh.globFilter 3526 ); 3527 this.fsw._addPathCloser(path, closer); 3528 } 3529 3530 /** 3531 * Handle added path with fsevents 3532 * @param {String} path file/dir path or glob pattern 3533 * @param {Function|Boolean=} transform converts working path to what the user expects 3534 * @param {Boolean=} forceAdd ensure add is emitted 3535 * @param {Number=} priorDepth Level of subdirectories already traversed. 3536 * @returns {Promise<void>} 3537 */ 3538 async _addToFsEvents(path, transform, forceAdd, priorDepth) { 3539 if (this.fsw.closed) { 3540 return; 3541 } 3542 const opts = this.fsw.options; 3543 const processPath = typeof transform === FUNCTION_TYPE$1 ? transform : IDENTITY_FN; 3544 3545 const wh = this.fsw._getWatchHelpers(path); 3546 3547 // evaluate what is at the path we're being asked to watch 3548 try { 3549 const stats = await statMethods[wh.statMethod](wh.watchPath); 3550 if (this.fsw.closed) return; 3551 if (this.fsw._isIgnored(wh.watchPath, stats)) { 3552 throw null; 3553 } 3554 if (stats.isDirectory()) { 3555 // emit addDir unless this is a glob parent 3556 if (!wh.globFilter) this.emitAdd(processPath(path), stats, processPath, opts, forceAdd); 3557 3558 // don't recurse further if it would exceed depth setting 3559 if (priorDepth && priorDepth > opts.depth) return; 3560 3561 // scan the contents of the dir 3562 this.fsw._readdirp(wh.watchPath, { 3563 fileFilter: entry => wh.filterPath(entry), 3564 directoryFilter: entry => wh.filterDir(entry), 3565 ...Depth(opts.depth - (priorDepth || 0)) 3566 }).on(STR_DATA, (entry) => { 3567 // need to check filterPath on dirs b/c filterDir is less restrictive 3568 if (this.fsw.closed) { 3569 return; 3570 } 3571 if (entry.stats.isDirectory() && !wh.filterPath(entry)) return; 3572 3573 const joinedPath = sysPath$1.join(wh.watchPath, entry.path); 3574 const {fullPath} = entry; 3575 3576 if (wh.followSymlinks && entry.stats.isSymbolicLink()) { 3577 // preserve the current depth here since it can't be derived from 3578 // real paths past the symlink 3579 const curDepth = opts.depth === undefined ? 3580 undefined : calcDepth(joinedPath, sysPath$1.resolve(wh.watchPath)) + 1; 3581 3582 this._handleFsEventsSymlink(joinedPath, fullPath, processPath, curDepth); 3583 } else { 3584 this.emitAdd(joinedPath, entry.stats, processPath, opts, forceAdd); 3585 } 3586 }).on(EV_ERROR$1, EMPTY_FN$1).on(STR_END$1, () => { 3587 this.fsw._emitReady(); 3588 }); 3589 } else { 3590 this.emitAdd(wh.watchPath, stats, processPath, opts, forceAdd); 3591 this.fsw._emitReady(); 3592 } 3593 } catch (error) { 3594 if (!error || this.fsw._handleError(error)) { 3595 // TODO: Strange thing: "should not choke on an ignored watch path" will be failed without 2 ready calls -__- 3596 this.fsw._emitReady(); 3597 this.fsw._emitReady(); 3598 } 3599 } 3600 3601 if (opts.persistent && forceAdd !== true) { 3602 if (typeof transform === FUNCTION_TYPE$1) { 3603 // realpath has already been resolved 3604 this.initWatch(undefined, path, wh, processPath); 3605 } else { 3606 let realPath; 3607 try { 3608 realPath = await realpath(wh.watchPath); 3609 } catch (e) {} 3610 this.initWatch(realPath, path, wh, processPath); 3611 } 3612 } 3613 } 3614 3615 }; 3616 3617 fseventsHandler.exports = FsEventsHandler$1; 3618 fseventsHandler.exports.canUse = canUse; 3619 3620 var fseventsHandlerExports = fseventsHandler.exports; 3621 3622 const { EventEmitter } = require$$0$3; 3623 const fs = require$$0$1; 3624 const sysPath = require$$0$2; 3625 const { promisify } = require$$2; 3626 const readdirp = readdirp_1; 3627 const anymatch = anymatchExports.default; 3628 const globParent = globParent$1; 3629 const isGlob = isGlob$2; 3630 const braces = braces_1; 3631 const normalizePath = normalizePath$2; 3632 3633 const NodeFsHandler = nodefsHandler; 3634 const FsEventsHandler = fseventsHandlerExports; 3635 const { 3636 EV_ALL, 3637 EV_READY, 3638 EV_ADD, 3639 EV_CHANGE, 3640 EV_UNLINK, 3641 EV_ADD_DIR, 3642 EV_UNLINK_DIR, 3643 EV_RAW, 3644 EV_ERROR, 3645 3646 STR_CLOSE, 3647 STR_END, 3648 3649 BACK_SLASH_RE, 3650 DOUBLE_SLASH_RE, 3651 SLASH_OR_BACK_SLASH_RE, 3652 DOT_RE, 3653 REPLACER_RE, 3654 3655 SLASH, 3656 SLASH_SLASH, 3657 BRACE_START, 3658 BANG, 3659 ONE_DOT, 3660 TWO_DOTS, 3661 GLOBSTAR, 3662 SLASH_GLOBSTAR, 3663 ANYMATCH_OPTS, 3664 STRING_TYPE, 3665 FUNCTION_TYPE, 3666 EMPTY_STR, 3667 EMPTY_FN, 3668 3669 isWindows, 3670 isMacos, 3671 isIBMi 3672 } = constants; 3673 3674 const stat = promisify(fs.stat); 3675 const readdir = promisify(fs.readdir); 3676 3677 /** 3678 * @typedef {String} Path 3679 * @typedef {'all'|'add'|'addDir'|'change'|'unlink'|'unlinkDir'|'raw'|'error'|'ready'} EventName 3680 * @typedef {'readdir'|'watch'|'add'|'remove'|'change'} ThrottleType 3681 */ 3682 3683 /** 3684 * 3685 * @typedef {Object} WatchHelpers 3686 * @property {Boolean} followSymlinks 3687 * @property {'stat'|'lstat'} statMethod 3688 * @property {Path} path 3689 * @property {Path} watchPath 3690 * @property {Function} entryPath 3691 * @property {Boolean} hasGlob 3692 * @property {Object} globFilter 3693 * @property {Function} filterPath 3694 * @property {Function} filterDir 3695 */ 3696 3697 const arrify = (value = []) => Array.isArray(value) ? value : [value]; 3698 const flatten = (list, result = []) => { 3699 list.forEach(item => { 3700 if (Array.isArray(item)) { 3701 flatten(item, result); 3702 } else { 3703 result.push(item); 3704 } 3705 }); 3706 return result; 3707 }; 3708 3709 const unifyPaths = (paths_) => { 3710 /** 3711 * @type {Array<String>} 3712 */ 3713 const paths = flatten(arrify(paths_)); 3714 if (!paths.every(p => typeof p === STRING_TYPE)) { 3715 throw new TypeError(`Non-string provided as watch path: ${paths}`); 3716 } 3717 return paths.map(normalizePathToUnix); 3718 }; 3719 3720 // If SLASH_SLASH occurs at the beginning of path, it is not replaced 3721 // because "//StoragePC/DrivePool/Movies" is a valid network path 3722 const toUnix = (string) => { 3723 let str = string.replace(BACK_SLASH_RE, SLASH); 3724 let prepend = false; 3725 if (str.startsWith(SLASH_SLASH)) { 3726 prepend = true; 3727 } 3728 while (str.match(DOUBLE_SLASH_RE)) { 3729 str = str.replace(DOUBLE_SLASH_RE, SLASH); 3730 } 3731 if (prepend) { 3732 str = SLASH + str; 3733 } 3734 return str; 3735 }; 3736 3737 // Our version of upath.normalize 3738 // TODO: this is not equal to path-normalize module - investigate why 3739 const normalizePathToUnix = (path) => toUnix(sysPath.normalize(toUnix(path))); 3740 3741 const normalizeIgnored = (cwd = EMPTY_STR) => (path) => { 3742 if (typeof path !== STRING_TYPE) return path; 3743 return normalizePathToUnix(sysPath.isAbsolute(path) ? path : sysPath.join(cwd, path)); 3744 }; 3745 3746 const getAbsolutePath = (path, cwd) => { 3747 if (sysPath.isAbsolute(path)) { 3748 return path; 3749 } 3750 if (path.startsWith(BANG)) { 3751 return BANG + sysPath.join(cwd, path.slice(1)); 3752 } 3753 return sysPath.join(cwd, path); 3754 }; 3755 3756 const undef = (opts, key) => opts[key] === undefined; 3757 3758 /** 3759 * Directory entry. 3760 * @property {Path} path 3761 * @property {Set<Path>} items 3762 */ 3763 class DirEntry { 3764 /** 3765 * @param {Path} dir 3766 * @param {Function} removeWatcher 3767 */ 3768 constructor(dir, removeWatcher) { 3769 this.path = dir; 3770 this._removeWatcher = removeWatcher; 3771 /** @type {Set<Path>} */ 3772 this.items = new Set(); 3773 } 3774 3775 add(item) { 3776 const {items} = this; 3777 if (!items) return; 3778 if (item !== ONE_DOT && item !== TWO_DOTS) items.add(item); 3779 } 3780 3781 async remove(item) { 3782 const {items} = this; 3783 if (!items) return; 3784 items.delete(item); 3785 if (items.size > 0) return; 3786 3787 const dir = this.path; 3788 try { 3789 await readdir(dir); 3790 } catch (err) { 3791 if (this._removeWatcher) { 3792 this._removeWatcher(sysPath.dirname(dir), sysPath.basename(dir)); 3793 } 3794 } 3795 } 3796 3797 has(item) { 3798 const {items} = this; 3799 if (!items) return; 3800 return items.has(item); 3801 } 3802 3803 /** 3804 * @returns {Array<String>} 3805 */ 3806 getChildren() { 3807 const {items} = this; 3808 if (!items) return; 3809 return [...items.values()]; 3810 } 3811 3812 dispose() { 3813 this.items.clear(); 3814 delete this.path; 3815 delete this._removeWatcher; 3816 delete this.items; 3817 Object.freeze(this); 3818 } 3819 } 3820 3821 const STAT_METHOD_F = 'stat'; 3822 const STAT_METHOD_L = 'lstat'; 3823 class WatchHelper { 3824 constructor(path, watchPath, follow, fsw) { 3825 this.fsw = fsw; 3826 this.path = path = path.replace(REPLACER_RE, EMPTY_STR); 3827 this.watchPath = watchPath; 3828 this.fullWatchPath = sysPath.resolve(watchPath); 3829 this.hasGlob = watchPath !== path; 3830 /** @type {object|boolean} */ 3831 if (path === EMPTY_STR) this.hasGlob = false; 3832 this.globSymlink = this.hasGlob && follow ? undefined : false; 3833 this.globFilter = this.hasGlob ? anymatch(path, undefined, ANYMATCH_OPTS) : false; 3834 this.dirParts = this.getDirParts(path); 3835 this.dirParts.forEach((parts) => { 3836 if (parts.length > 1) parts.pop(); 3837 }); 3838 this.followSymlinks = follow; 3839 this.statMethod = follow ? STAT_METHOD_F : STAT_METHOD_L; 3840 } 3841 3842 checkGlobSymlink(entry) { 3843 // only need to resolve once 3844 // first entry should always have entry.parentDir === EMPTY_STR 3845 if (this.globSymlink === undefined) { 3846 this.globSymlink = entry.fullParentDir === this.fullWatchPath ? 3847 false : {realPath: entry.fullParentDir, linkPath: this.fullWatchPath}; 3848 } 3849 3850 if (this.globSymlink) { 3851 return entry.fullPath.replace(this.globSymlink.realPath, this.globSymlink.linkPath); 3852 } 3853 3854 return entry.fullPath; 3855 } 3856 3857 entryPath(entry) { 3858 return sysPath.join(this.watchPath, 3859 sysPath.relative(this.watchPath, this.checkGlobSymlink(entry)) 3860 ); 3861 } 3862 3863 filterPath(entry) { 3864 const {stats} = entry; 3865 if (stats && stats.isSymbolicLink()) return this.filterDir(entry); 3866 const resolvedPath = this.entryPath(entry); 3867 const matchesGlob = this.hasGlob && typeof this.globFilter === FUNCTION_TYPE ? 3868 this.globFilter(resolvedPath) : true; 3869 return matchesGlob && 3870 this.fsw._isntIgnored(resolvedPath, stats) && 3871 this.fsw._hasReadPermissions(stats); 3872 } 3873 3874 getDirParts(path) { 3875 if (!this.hasGlob) return []; 3876 const parts = []; 3877 const expandedPath = path.includes(BRACE_START) ? braces.expand(path) : [path]; 3878 expandedPath.forEach((path) => { 3879 parts.push(sysPath.relative(this.watchPath, path).split(SLASH_OR_BACK_SLASH_RE)); 3880 }); 3881 return parts; 3882 } 3883 3884 filterDir(entry) { 3885 if (this.hasGlob) { 3886 const entryParts = this.getDirParts(this.checkGlobSymlink(entry)); 3887 let globstar = false; 3888 this.unmatchedGlob = !this.dirParts.some((parts) => { 3889 return parts.every((part, i) => { 3890 if (part === GLOBSTAR) globstar = true; 3891 return globstar || !entryParts[0][i] || anymatch(part, entryParts[0][i], ANYMATCH_OPTS); 3892 }); 3893 }); 3894 } 3895 return !this.unmatchedGlob && this.fsw._isntIgnored(this.entryPath(entry), entry.stats); 3896 } 3897 } 3898 3899 /** 3900 * Watches files & directories for changes. Emitted events: 3901 * `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error` 3902 * 3903 * new FSWatcher() 3904 * .add(directories) 3905 * .on('add', path => log('File', path, 'was added')) 3906 */ 3907 class FSWatcher extends EventEmitter { 3908 // Not indenting methods for history sake; for now. 3909 constructor(_opts) { 3910 super(); 3911 3912 const opts = {}; 3913 if (_opts) Object.assign(opts, _opts); // for frozen objects 3914 3915 /** @type {Map<String, DirEntry>} */ 3916 this._watched = new Map(); 3917 /** @type {Map<String, Array>} */ 3918 this._closers = new Map(); 3919 /** @type {Set<String>} */ 3920 this._ignoredPaths = new Set(); 3921 3922 /** @type {Map<ThrottleType, Map>} */ 3923 this._throttled = new Map(); 3924 3925 /** @type {Map<Path, String|Boolean>} */ 3926 this._symlinkPaths = new Map(); 3927 3928 this._streams = new Set(); 3929 this.closed = false; 3930 3931 // Set up default options. 3932 if (undef(opts, 'persistent')) opts.persistent = true; 3933 if (undef(opts, 'ignoreInitial')) opts.ignoreInitial = false; 3934 if (undef(opts, 'ignorePermissionErrors')) opts.ignorePermissionErrors = false; 3935 if (undef(opts, 'interval')) opts.interval = 100; 3936 if (undef(opts, 'binaryInterval')) opts.binaryInterval = 300; 3937 if (undef(opts, 'disableGlobbing')) opts.disableGlobbing = false; 3938 opts.enableBinaryInterval = opts.binaryInterval !== opts.interval; 3939 3940 // Enable fsevents on OS X when polling isn't explicitly enabled. 3941 if (undef(opts, 'useFsEvents')) opts.useFsEvents = !opts.usePolling; 3942 3943 // If we can't use fsevents, ensure the options reflect it's disabled. 3944 const canUseFsEvents = FsEventsHandler.canUse(); 3945 if (!canUseFsEvents) opts.useFsEvents = false; 3946 3947 // Use polling on Mac if not using fsevents. 3948 // Other platforms use non-polling fs_watch. 3949 if (undef(opts, 'usePolling') && !opts.useFsEvents) { 3950 opts.usePolling = isMacos; 3951 } 3952 3953 // Always default to polling on IBM i because fs.watch() is not available on IBM i. 3954 if(isIBMi) { 3955 opts.usePolling = true; 3956 } 3957 3958 // Global override (useful for end-developers that need to force polling for all 3959 // instances of chokidar, regardless of usage/dependency depth) 3960 const envPoll = process.env.CHOKIDAR_USEPOLLING; 3961 if (envPoll !== undefined) { 3962 const envLower = envPoll.toLowerCase(); 3963 3964 if (envLower === 'false' || envLower === '0') { 3965 opts.usePolling = false; 3966 } else if (envLower === 'true' || envLower === '1') { 3967 opts.usePolling = true; 3968 } else { 3969 opts.usePolling = !!envLower; 3970 } 3971 } 3972 const envInterval = process.env.CHOKIDAR_INTERVAL; 3973 if (envInterval) { 3974 opts.interval = Number.parseInt(envInterval, 10); 3975 } 3976 3977 // Editor atomic write normalization enabled by default with fs.watch 3978 if (undef(opts, 'atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents; 3979 if (opts.atomic) this._pendingUnlinks = new Map(); 3980 3981 if (undef(opts, 'followSymlinks')) opts.followSymlinks = true; 3982 3983 if (undef(opts, 'awaitWriteFinish')) opts.awaitWriteFinish = false; 3984 if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {}; 3985 const awf = opts.awaitWriteFinish; 3986 if (awf) { 3987 if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000; 3988 if (!awf.pollInterval) awf.pollInterval = 100; 3989 this._pendingWrites = new Map(); 3990 } 3991 if (opts.ignored) opts.ignored = arrify(opts.ignored); 3992 3993 let readyCalls = 0; 3994 this._emitReady = () => { 3995 readyCalls++; 3996 if (readyCalls >= this._readyCount) { 3997 this._emitReady = EMPTY_FN; 3998 this._readyEmitted = true; 3999 // use process.nextTick to allow time for listener to be bound 4000 process.nextTick(() => this.emit(EV_READY)); 4001 } 4002 }; 4003 this._emitRaw = (...args) => this.emit(EV_RAW, ...args); 4004 this._readyEmitted = false; 4005 this.options = opts; 4006 4007 // Initialize with proper watcher. 4008 if (opts.useFsEvents) { 4009 this._fsEventsHandler = new FsEventsHandler(this); 4010 } else { 4011 this._nodeFsHandler = new NodeFsHandler(this); 4012 } 4013 4014 // You’re frozen when your heart’s not open. 4015 Object.freeze(opts); 4016 } 4017 4018 // Public methods 4019 4020 /** 4021 * Adds paths to be watched on an existing FSWatcher instance 4022 * @param {Path|Array<Path>} paths_ 4023 * @param {String=} _origAdd private; for handling non-existent paths to be watched 4024 * @param {Boolean=} _internal private; indicates a non-user add 4025 * @returns {FSWatcher} for chaining 4026 */ 4027 add(paths_, _origAdd, _internal) { 4028 const {cwd, disableGlobbing} = this.options; 4029 this.closed = false; 4030 let paths = unifyPaths(paths_); 4031 if (cwd) { 4032 paths = paths.map((path) => { 4033 const absPath = getAbsolutePath(path, cwd); 4034 4035 // Check `path` instead of `absPath` because the cwd portion can't be a glob 4036 if (disableGlobbing || !isGlob(path)) { 4037 return absPath; 4038 } 4039 return normalizePath(absPath); 4040 }); 4041 } 4042 4043 // set aside negated glob strings 4044 paths = paths.filter((path) => { 4045 if (path.startsWith(BANG)) { 4046 this._ignoredPaths.add(path.slice(1)); 4047 return false; 4048 } 4049 4050 // if a path is being added that was previously ignored, stop ignoring it 4051 this._ignoredPaths.delete(path); 4052 this._ignoredPaths.delete(path + SLASH_GLOBSTAR); 4053 4054 // reset the cached userIgnored anymatch fn 4055 // to make ignoredPaths changes effective 4056 this._userIgnored = undefined; 4057 4058 return true; 4059 }); 4060 4061 if (this.options.useFsEvents && this._fsEventsHandler) { 4062 if (!this._readyCount) this._readyCount = paths.length; 4063 if (this.options.persistent) this._readyCount += paths.length; 4064 paths.forEach((path) => this._fsEventsHandler._addToFsEvents(path)); 4065 } else { 4066 if (!this._readyCount) this._readyCount = 0; 4067 this._readyCount += paths.length; 4068 Promise.all( 4069 paths.map(async path => { 4070 const res = await this._nodeFsHandler._addToNodeFs(path, !_internal, 0, 0, _origAdd); 4071 if (res) this._emitReady(); 4072 return res; 4073 }) 4074 ).then(results => { 4075 if (this.closed) return; 4076 results.filter(item => item).forEach(item => { 4077 this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item)); 4078 }); 4079 }); 4080 } 4081 4082 return this; 4083 } 4084 4085 /** 4086 * Close watchers or start ignoring events from specified paths. 4087 * @param {Path|Array<Path>} paths_ - string or array of strings, file/directory paths and/or globs 4088 * @returns {FSWatcher} for chaining 4089 */ 4090 unwatch(paths_) { 4091 if (this.closed) return this; 4092 const paths = unifyPaths(paths_); 4093 const {cwd} = this.options; 4094 4095 paths.forEach((path) => { 4096 // convert to absolute path unless relative path already matches 4097 if (!sysPath.isAbsolute(path) && !this._closers.has(path)) { 4098 if (cwd) path = sysPath.join(cwd, path); 4099 path = sysPath.resolve(path); 4100 } 4101 4102 this._closePath(path); 4103 4104 this._ignoredPaths.add(path); 4105 if (this._watched.has(path)) { 4106 this._ignoredPaths.add(path + SLASH_GLOBSTAR); 4107 } 4108 4109 // reset the cached userIgnored anymatch fn 4110 // to make ignoredPaths changes effective 4111 this._userIgnored = undefined; 4112 }); 4113 4114 return this; 4115 } 4116 4117 /** 4118 * Close watchers and remove all listeners from watched paths. 4119 * @returns {Promise<void>}. 4120 */ 4121 close() { 4122 if (this.closed) return this._closePromise; 4123 this.closed = true; 4124 4125 // Memory management. 4126 this.removeAllListeners(); 4127 const closers = []; 4128 this._closers.forEach(closerList => closerList.forEach(closer => { 4129 const promise = closer(); 4130 if (promise instanceof Promise) closers.push(promise); 4131 })); 4132 this._streams.forEach(stream => stream.destroy()); 4133 this._userIgnored = undefined; 4134 this._readyCount = 0; 4135 this._readyEmitted = false; 4136 this._watched.forEach(dirent => dirent.dispose()); 4137 ['closers', 'watched', 'streams', 'symlinkPaths', 'throttled'].forEach(key => { 4138 this[`_${key}`].clear(); 4139 }); 4140 4141 this._closePromise = closers.length ? Promise.all(closers).then(() => undefined) : Promise.resolve(); 4142 return this._closePromise; 4143 } 4144 4145 /** 4146 * Expose list of watched paths 4147 * @returns {Object} for chaining 4148 */ 4149 getWatched() { 4150 const watchList = {}; 4151 this._watched.forEach((entry, dir) => { 4152 const key = this.options.cwd ? sysPath.relative(this.options.cwd, dir) : dir; 4153 watchList[key || ONE_DOT] = entry.getChildren().sort(); 4154 }); 4155 return watchList; 4156 } 4157 4158 emitWithAll(event, args) { 4159 this.emit(...args); 4160 if (event !== EV_ERROR) this.emit(EV_ALL, ...args); 4161 } 4162 4163 // Common helpers 4164 // -------------- 4165 4166 /** 4167 * Normalize and emit events. 4168 * Calling _emit DOES NOT MEAN emit() would be called! 4169 * @param {EventName} event Type of event 4170 * @param {Path} path File or directory path 4171 * @param {*=} val1 arguments to be passed with event 4172 * @param {*=} val2 4173 * @param {*=} val3 4174 * @returns the error if defined, otherwise the value of the FSWatcher instance's `closed` flag 4175 */ 4176 async _emit(event, path, val1, val2, val3) { 4177 if (this.closed) return; 4178 4179 const opts = this.options; 4180 if (isWindows) path = sysPath.normalize(path); 4181 if (opts.cwd) path = sysPath.relative(opts.cwd, path); 4182 /** @type Array<any> */ 4183 const args = [event, path]; 4184 if (val3 !== undefined) args.push(val1, val2, val3); 4185 else if (val2 !== undefined) args.push(val1, val2); 4186 else if (val1 !== undefined) args.push(val1); 4187 4188 const awf = opts.awaitWriteFinish; 4189 let pw; 4190 if (awf && (pw = this._pendingWrites.get(path))) { 4191 pw.lastChange = new Date(); 4192 return this; 4193 } 4194 4195 if (opts.atomic) { 4196 if (event === EV_UNLINK) { 4197 this._pendingUnlinks.set(path, args); 4198 setTimeout(() => { 4199 this._pendingUnlinks.forEach((entry, path) => { 4200 this.emit(...entry); 4201 this.emit(EV_ALL, ...entry); 4202 this._pendingUnlinks.delete(path); 4203 }); 4204 }, typeof opts.atomic === 'number' ? opts.atomic : 100); 4205 return this; 4206 } 4207 if (event === EV_ADD && this._pendingUnlinks.has(path)) { 4208 event = args[0] = EV_CHANGE; 4209 this._pendingUnlinks.delete(path); 4210 } 4211 } 4212 4213 if (awf && (event === EV_ADD || event === EV_CHANGE) && this._readyEmitted) { 4214 const awfEmit = (err, stats) => { 4215 if (err) { 4216 event = args[0] = EV_ERROR; 4217 args[1] = err; 4218 this.emitWithAll(event, args); 4219 } else if (stats) { 4220 // if stats doesn't exist the file must have been deleted 4221 if (args.length > 2) { 4222 args[2] = stats; 4223 } else { 4224 args.push(stats); 4225 } 4226 this.emitWithAll(event, args); 4227 } 4228 }; 4229 4230 this._awaitWriteFinish(path, awf.stabilityThreshold, event, awfEmit); 4231 return this; 4232 } 4233 4234 if (event === EV_CHANGE) { 4235 const isThrottled = !this._throttle(EV_CHANGE, path, 50); 4236 if (isThrottled) return this; 4237 } 4238 4239 if (opts.alwaysStat && val1 === undefined && 4240 (event === EV_ADD || event === EV_ADD_DIR || event === EV_CHANGE) 4241 ) { 4242 const fullPath = opts.cwd ? sysPath.join(opts.cwd, path) : path; 4243 let stats; 4244 try { 4245 stats = await stat(fullPath); 4246 } catch (err) {} 4247 // Suppress event when fs_stat fails, to avoid sending undefined 'stat' 4248 if (!stats || this.closed) return; 4249 args.push(stats); 4250 } 4251 this.emitWithAll(event, args); 4252 4253 return this; 4254 } 4255 4256 /** 4257 * Common handler for errors 4258 * @param {Error} error 4259 * @returns {Error|Boolean} The error if defined, otherwise the value of the FSWatcher instance's `closed` flag 4260 */ 4261 _handleError(error) { 4262 const code = error && error.code; 4263 if (error && code !== 'ENOENT' && code !== 'ENOTDIR' && 4264 (!this.options.ignorePermissionErrors || (code !== 'EPERM' && code !== 'EACCES')) 4265 ) { 4266 this.emit(EV_ERROR, error); 4267 } 4268 return error || this.closed; 4269 } 4270 4271 /** 4272 * Helper utility for throttling 4273 * @param {ThrottleType} actionType type being throttled 4274 * @param {Path} path being acted upon 4275 * @param {Number} timeout duration of time to suppress duplicate actions 4276 * @returns {Object|false} tracking object or false if action should be suppressed 4277 */ 4278 _throttle(actionType, path, timeout) { 4279 if (!this._throttled.has(actionType)) { 4280 this._throttled.set(actionType, new Map()); 4281 } 4282 4283 /** @type {Map<Path, Object>} */ 4284 const action = this._throttled.get(actionType); 4285 /** @type {Object} */ 4286 const actionPath = action.get(path); 4287 4288 if (actionPath) { 4289 actionPath.count++; 4290 return false; 4291 } 4292 4293 let timeoutObject; 4294 const clear = () => { 4295 const item = action.get(path); 4296 const count = item ? item.count : 0; 4297 action.delete(path); 4298 clearTimeout(timeoutObject); 4299 if (item) clearTimeout(item.timeoutObject); 4300 return count; 4301 }; 4302 timeoutObject = setTimeout(clear, timeout); 4303 const thr = {timeoutObject, clear, count: 0}; 4304 action.set(path, thr); 4305 return thr; 4306 } 4307 4308 _incrReadyCount() { 4309 return this._readyCount++; 4310 } 4311 4312 /** 4313 * Awaits write operation to finish. 4314 * Polls a newly created file for size variations. When files size does not change for 'threshold' milliseconds calls callback. 4315 * @param {Path} path being acted upon 4316 * @param {Number} threshold Time in milliseconds a file size must be fixed before acknowledging write OP is finished 4317 * @param {EventName} event 4318 * @param {Function} awfEmit Callback to be called when ready for event to be emitted. 4319 */ 4320 _awaitWriteFinish(path, threshold, event, awfEmit) { 4321 let timeoutHandler; 4322 4323 let fullPath = path; 4324 if (this.options.cwd && !sysPath.isAbsolute(path)) { 4325 fullPath = sysPath.join(this.options.cwd, path); 4326 } 4327 4328 const now = new Date(); 4329 4330 const awaitWriteFinish = (prevStat) => { 4331 fs.stat(fullPath, (err, curStat) => { 4332 if (err || !this._pendingWrites.has(path)) { 4333 if (err && err.code !== 'ENOENT') awfEmit(err); 4334 return; 4335 } 4336 4337 const now = Number(new Date()); 4338 4339 if (prevStat && curStat.size !== prevStat.size) { 4340 this._pendingWrites.get(path).lastChange = now; 4341 } 4342 const pw = this._pendingWrites.get(path); 4343 const df = now - pw.lastChange; 4344 4345 if (df >= threshold) { 4346 this._pendingWrites.delete(path); 4347 awfEmit(undefined, curStat); 4348 } else { 4349 timeoutHandler = setTimeout( 4350 awaitWriteFinish, 4351 this.options.awaitWriteFinish.pollInterval, 4352 curStat 4353 ); 4354 } 4355 }); 4356 }; 4357 4358 if (!this._pendingWrites.has(path)) { 4359 this._pendingWrites.set(path, { 4360 lastChange: now, 4361 cancelWait: () => { 4362 this._pendingWrites.delete(path); 4363 clearTimeout(timeoutHandler); 4364 return event; 4365 } 4366 }); 4367 timeoutHandler = setTimeout( 4368 awaitWriteFinish, 4369 this.options.awaitWriteFinish.pollInterval 4370 ); 4371 } 4372 } 4373 4374 _getGlobIgnored() { 4375 return [...this._ignoredPaths.values()]; 4376 } 4377 4378 /** 4379 * Determines whether user has asked to ignore this path. 4380 * @param {Path} path filepath or dir 4381 * @param {fs.Stats=} stats result of fs.stat 4382 * @returns {Boolean} 4383 */ 4384 _isIgnored(path, stats) { 4385 if (this.options.atomic && DOT_RE.test(path)) return true; 4386 if (!this._userIgnored) { 4387 const {cwd} = this.options; 4388 const ign = this.options.ignored; 4389 4390 const ignored = ign && ign.map(normalizeIgnored(cwd)); 4391 const paths = arrify(ignored) 4392 .filter((path) => typeof path === STRING_TYPE && !isGlob(path)) 4393 .map((path) => path + SLASH_GLOBSTAR); 4394 const list = this._getGlobIgnored().map(normalizeIgnored(cwd)).concat(ignored, paths); 4395 this._userIgnored = anymatch(list, undefined, ANYMATCH_OPTS); 4396 } 4397 4398 return this._userIgnored([path, stats]); 4399 } 4400 4401 _isntIgnored(path, stat) { 4402 return !this._isIgnored(path, stat); 4403 } 4404 4405 /** 4406 * Provides a set of common helpers and properties relating to symlink and glob handling. 4407 * @param {Path} path file, directory, or glob pattern being watched 4408 * @param {Number=} depth at any depth > 0, this isn't a glob 4409 * @returns {WatchHelper} object containing helpers for this path 4410 */ 4411 _getWatchHelpers(path, depth) { 4412 const watchPath = depth || this.options.disableGlobbing || !isGlob(path) ? path : globParent(path); 4413 const follow = this.options.followSymlinks; 4414 4415 return new WatchHelper(path, watchPath, follow, this); 4416 } 4417 4418 // Directory helpers 4419 // ----------------- 4420 4421 /** 4422 * Provides directory tracking objects 4423 * @param {String} directory path of the directory 4424 * @returns {DirEntry} the directory's tracking object 4425 */ 4426 _getWatchedDir(directory) { 4427 if (!this._boundRemove) this._boundRemove = this._remove.bind(this); 4428 const dir = sysPath.resolve(directory); 4429 if (!this._watched.has(dir)) this._watched.set(dir, new DirEntry(dir, this._boundRemove)); 4430 return this._watched.get(dir); 4431 } 4432 4433 // File helpers 4434 // ------------ 4435 4436 /** 4437 * Check for read permissions. 4438 * Based on this answer on SO: https://stackoverflow.com/a/11781404/1358405 4439 * @param {fs.Stats} stats - object, result of fs_stat 4440 * @returns {Boolean} indicates whether the file can be read 4441 */ 4442 _hasReadPermissions(stats) { 4443 if (this.options.ignorePermissionErrors) return true; 4444 4445 // stats.mode may be bigint 4446 const md = stats && Number.parseInt(stats.mode, 10); 4447 const st = md & 0o777; 4448 const it = Number.parseInt(st.toString(8)[0], 10); 4449 return Boolean(4 & it); 4450 } 4451 4452 /** 4453 * Handles emitting unlink events for 4454 * files and directories, and via recursion, for 4455 * files and directories within directories that are unlinked 4456 * @param {String} directory within which the following item is located 4457 * @param {String} item base path of item/directory 4458 * @returns {void} 4459 */ 4460 _remove(directory, item, isDirectory) { 4461 // if what is being deleted is a directory, get that directory's paths 4462 // for recursive deleting and cleaning of watched object 4463 // if it is not a directory, nestedDirectoryChildren will be empty array 4464 const path = sysPath.join(directory, item); 4465 const fullPath = sysPath.resolve(path); 4466 isDirectory = isDirectory != null 4467 ? isDirectory 4468 : this._watched.has(path) || this._watched.has(fullPath); 4469 4470 // prevent duplicate handling in case of arriving here nearly simultaneously 4471 // via multiple paths (such as _handleFile and _handleDir) 4472 if (!this._throttle('remove', path, 100)) return; 4473 4474 // if the only watched file is removed, watch for its return 4475 if (!isDirectory && !this.options.useFsEvents && this._watched.size === 1) { 4476 this.add(directory, item, true); 4477 } 4478 4479 // This will create a new entry in the watched object in either case 4480 // so we got to do the directory check beforehand 4481 const wp = this._getWatchedDir(path); 4482 const nestedDirectoryChildren = wp.getChildren(); 4483 4484 // Recursively remove children directories / files. 4485 nestedDirectoryChildren.forEach(nested => this._remove(path, nested)); 4486 4487 // Check if item was on the watched list and remove it 4488 const parent = this._getWatchedDir(directory); 4489 const wasTracked = parent.has(item); 4490 parent.remove(item); 4491 4492 // Fixes issue #1042 -> Relative paths were detected and added as symlinks 4493 // (https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L612), 4494 // but never removed from the map in case the path was deleted. 4495 // This leads to an incorrect state if the path was recreated: 4496 // https://github.com/paulmillr/chokidar/blob/e1753ddbc9571bdc33b4a4af172d52cb6e611c10/lib/nodefs-handler.js#L553 4497 if (this._symlinkPaths.has(fullPath)) { 4498 this._symlinkPaths.delete(fullPath); 4499 } 4500 4501 // If we wait for this file to be fully written, cancel the wait. 4502 let relPath = path; 4503 if (this.options.cwd) relPath = sysPath.relative(this.options.cwd, path); 4504 if (this.options.awaitWriteFinish && this._pendingWrites.has(relPath)) { 4505 const event = this._pendingWrites.get(relPath).cancelWait(); 4506 if (event === EV_ADD) return; 4507 } 4508 4509 // The Entry will either be a directory that just got removed 4510 // or a bogus entry to a file, in either case we have to remove it 4511 this._watched.delete(path); 4512 this._watched.delete(fullPath); 4513 const eventName = isDirectory ? EV_UNLINK_DIR : EV_UNLINK; 4514 if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path); 4515 4516 // Avoid conflicts if we later create another file with the same name 4517 if (!this.options.useFsEvents) { 4518 this._closePath(path); 4519 } 4520 } 4521 4522 /** 4523 * Closes all watchers for a path 4524 * @param {Path} path 4525 */ 4526 _closePath(path) { 4527 this._closeFile(path); 4528 const dir = sysPath.dirname(path); 4529 this._getWatchedDir(dir).remove(sysPath.basename(path)); 4530 } 4531 4532 /** 4533 * Closes only file-specific watchers 4534 * @param {Path} path 4535 */ 4536 _closeFile(path) { 4537 const closers = this._closers.get(path); 4538 if (!closers) return; 4539 closers.forEach(closer => closer()); 4540 this._closers.delete(path); 4541 } 4542 4543 /** 4544 * 4545 * @param {Path} path 4546 * @param {Function} closer 4547 */ 4548 _addPathCloser(path, closer) { 4549 if (!closer) return; 4550 let list = this._closers.get(path); 4551 if (!list) { 4552 list = []; 4553 this._closers.set(path, list); 4554 } 4555 list.push(closer); 4556 } 4557 4558 _readdirp(root, opts) { 4559 if (this.closed) return; 4560 const options = {type: EV_ALL, alwaysStat: true, lstat: true, ...opts}; 4561 let stream = readdirp(root, options); 4562 this._streams.add(stream); 4563 stream.once(STR_CLOSE, () => { 4564 stream = undefined; 4565 }); 4566 stream.once(STR_END, () => { 4567 if (stream) { 4568 this._streams.delete(stream); 4569 stream = undefined; 4570 } 4571 }); 4572 return stream; 4573 } 4574 4575 } 4576 4577 // Export FSWatcher class 4578 chokidar.FSWatcher = FSWatcher; 4579 4580 /** 4581 * Instantiates watcher with paths to be tracked. 4582 * @param {String|Array<String>} paths file/directory paths and/or globs 4583 * @param {Object=} options chokidar opts 4584 * @returns an instance of FSWatcher for chaining. 4585 */ 4586 const watch = (paths, options) => { 4587 const watcher = new FSWatcher(options); 4588 watcher.add(paths); 4589 return watcher; 4590 }; 4591 4592 chokidar.watch = watch; 9004 var chokidarExports = /*@__PURE__*/ requireChokidar(); 9005 const chokidar = /*@__PURE__*/getDefaultExportFromCjs(chokidarExports); 4593 9006 4594 9007 class FileWatcher { … … 4626 9039 const task = this.task; 4627 9040 const isLinux = platform() === 'linux'; 9041 const isFreeBSD = platform() === 'freebsd'; 4628 9042 const isTransformDependency = transformWatcherId !== null; 4629 9043 const handleChange = (id, event) => { 4630 9044 const changedId = transformWatcherId || id; 4631 if (isLinux ) {9045 if (isLinux || isFreeBSD) { 4632 9046 // unwatching and watching fixes an issue with chokidar where on certain systems, 4633 9047 // a file that was unlinked and immediately recreated would create a change event … … 4768 9182 this.outputFiles = this.outputs.map(output => { 4769 9183 if (output.file || output.dir) 4770 return path $1.resolve(output.file || output.dir);9184 return path.resolve(output.file || output.dir); 4771 9185 return undefined; 4772 9186 }); -
imaps-frontend/node_modules/rollup/dist/getLogFilter.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/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 -
imaps-frontend/node_modules/rollup/dist/native.js
rd565449 r0c6b92a 13 13 arm64: { base: 'darwin-arm64' }, 14 14 x64: { base: 'darwin-x64' } 15 }, 16 freebsd: { 17 arm64: { base: 'freebsd-arm64' }, 18 x64: { base: 'freebsd-x64' } 15 19 }, 16 20 linux: { -
imaps-frontend/node_modules/rollup/dist/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 -
imaps-frontend/node_modules/rollup/dist/rollup.d.ts
rd565449 r0c6b92a 212 212 export type GetModuleInfo = (moduleId: string) => ModuleInfo | null; 213 213 214 export interface CustomPluginOptions { 215 [plugin: string]: any; 216 } 214 export type CustomPluginOptions = Record<string, any>; 217 215 218 216 type LoggingFunctionWithPosition = ( … … 223 221 export type ParseAst = ( 224 222 input: string, 225 options?: { allowReturnOutsideFunction?: boolean }223 options?: { allowReturnOutsideFunction?: boolean; jsx?: boolean } 226 224 ) => ProgramNode; 227 225 228 226 // declare AbortSignal here for environments without DOM lib or @types/node 229 227 declare global { 228 // eslint-disable-next-line @typescript-eslint/no-empty-object-type 230 229 interface AbortSignal {} 231 230 } … … 233 232 export type ParseAstAsync = ( 234 233 input: string, 235 options?: { allowReturnOutsideFunction?: boolean; signal?: AbortSignal }234 options?: { allowReturnOutsideFunction?: boolean; jsx?: boolean; signal?: AbortSignal } 236 235 ) => Promise<ProgramNode>; 237 236 … … 276 275 } 277 276 278 export interface ResolvedIdMap { 279 [key: string]: ResolvedId; 280 } 277 export type ResolvedIdMap = Record<string, ResolvedId>; 281 278 282 279 interface PartialResolvedId extends Partial<PartialNull<ModuleOptions>> { … … 396 393 * ``` 397 394 */ 398 // eslint-disable-next-line @typescript-eslint/ban-types399 395 export type PluginImpl<O extends object = object, A = any> = (options?: O) => Plugin<A>; 400 396 401 export interface OutputBundle { 402 [fileName: string]: OutputAsset | OutputChunk; 403 } 397 export type OutputBundle = Record<string, OutputAsset | OutputChunk>; 404 398 405 399 export interface FunctionPluginHooks { … … 506 500 : never; 507 501 508 // eslint-disable-next-line @typescript-eslint/ ban-types502 // eslint-disable-next-line @typescript-eslint/no-empty-object-type 509 503 type ObjectHook<T, O = {}> = T | ({ handler: T; order?: 'pre' | 'post' | null } & O); 510 504 … … 512 506 [K in keyof FunctionPluginHooks]: ObjectHook< 513 507 K extends AsyncPluginHooks ? MakeAsync<FunctionPluginHooks[K]> : FunctionPluginHooks[K], 514 // eslint-disable-next-line @typescript-eslint/ ban-types508 // eslint-disable-next-line @typescript-eslint/no-empty-object-type 515 509 K extends ParallelPluginHooks ? { sequential?: boolean } : {} 516 510 >; … … 519 513 export interface OutputPlugin 520 514 extends Partial<{ [K in OutputPluginHooks]: PluginHooks[K] }>, 521 Partial< { [K in AddonHooks]: ObjectHook<AddonHook> }> {515 Partial<Record<AddonHooks, ObjectHook<AddonHook>>> { 522 516 cacheKey?: string; 523 517 name: string; … … 529 523 api?: A; 530 524 } 525 526 export type JsxPreset = 'react' | 'react-jsx' | 'preserve' | 'preserve-react'; 527 528 export type NormalizedJsxOptions = 529 | NormalizedJsxPreserveOptions 530 | NormalizedJsxClassicOptions 531 | NormalizedJsxAutomaticOptions; 532 533 interface NormalizedJsxPreserveOptions { 534 factory: string | null; 535 fragment: string | null; 536 importSource: string | null; 537 mode: 'preserve'; 538 } 539 540 interface NormalizedJsxClassicOptions { 541 factory: string; 542 fragment: string; 543 importSource: string | null; 544 mode: 'classic'; 545 } 546 547 interface NormalizedJsxAutomaticOptions { 548 factory: string; 549 importSource: string | null; 550 jsxImportSource: string; 551 mode: 'automatic'; 552 } 553 554 export type JsxOptions = Partial<NormalizedJsxOptions> & { 555 preset?: JsxPreset; 556 }; 531 557 532 558 export type TreeshakingPreset = 'smallest' | 'safest' | 'recommended'; … … 552 578 getModuleInfo: GetModuleInfo; 553 579 } 580 554 581 export type GetManualChunk = (id: string, meta: ManualChunkMeta) => string | NullValue; 555 582 … … 560 587 | ((source: string, importer: string | undefined, isResolved: boolean) => boolean | NullValue); 561 588 562 export type GlobalsOption = { [name: string]: string }| ((name: string) => string);563 564 export type InputOption = string | string[] | { [entryAlias: string]: string };565 566 export type ManualChunksOption = { [chunkAlias: string]: string[] }| GetManualChunk;589 export type GlobalsOption = Record<string, string> | ((name: string) => string); 590 591 export type InputOption = string | string[] | Record<string, string>; 592 593 export type ManualChunksOption = Record<string, string[]> | GetManualChunk; 567 594 568 595 export type LogHandlerWithDefault = ( … … 599 626 external?: ExternalOption; 600 627 input?: InputOption; 628 jsx?: false | JsxPreset | JsxOptions; 601 629 logLevel?: LogLevelOption; 602 630 makeAbsoluteExternalsRelative?: boolean | 'ifRelativeSource'; 603 631 maxParallelFileOps?: number; 604 moduleContext?: ((id: string) => string | NullValue) | { [id: string]: string };632 moduleContext?: ((id: string) => string | NullValue) | Record<string, string>; 605 633 onLog?: LogHandlerWithDefault; 606 634 onwarn?: WarningHandlerWithDefault; … … 625 653 experimentalLogSideEffects: boolean; 626 654 external: IsExternal; 627 input: string[] | { [entryAlias: string]: string }; 655 input: string[] | Record<string, string>; 656 jsx: false | NormalizedJsxOptions; 628 657 logLevel: LogLevelOption; 629 658 makeAbsoluteExternalsRelative: boolean | 'ifRelativeSource'; … … 754 783 sourcemapIgnoreList?: boolean | SourcemapIgnoreListOption; 755 784 sourcemapPathTransform?: SourcemapPathTransformOption; 785 sourcemapDebugIds?: boolean; 756 786 strict?: boolean; 757 787 systemNullSetters?: boolean; 758 788 validate?: boolean; 789 virtualDirname?: string; 759 790 } 760 791 … … 807 838 sourcemapIgnoreList: SourcemapIgnoreListOption; 808 839 sourcemapPathTransform: SourcemapPathTransformOption | undefined; 840 sourcemapDebugIds: boolean; 809 841 strict: boolean; 810 842 systemNullSetters: boolean; 811 843 validate: boolean; 844 virtualDirname: string; 812 845 } 813 846 … … 817 850 ) => void; 818 851 819 export interface SerializedTimings { 820 [label: string]: [number, number, number]; 821 } 852 export type SerializedTimings = Record<string, [number, number, number]>; 822 853 823 854 export interface PreRenderedAsset { 855 /** @deprecated Use "names" instead. */ 824 856 name: string | undefined; 857 names: string[]; 858 /** @deprecated Use "originalFileNames" instead. */ 825 859 originalFileName: string | null; 860 originalFileNames: string[]; 826 861 source: string | Uint8Array; 827 862 type: 'asset'; … … 856 891 fileName: string; 857 892 implicitlyLoadedBefore: string[]; 858 importedBindings: { 859 [imported: string]: string[]; 860 }; 893 importedBindings: Record<string, string[]>; 861 894 imports: string[]; 862 modules: { 863 [id: string]: RenderedModule; 864 }; 895 modules: Record<string, RenderedModule>; 865 896 referencedFiles: string[]; 866 897 } … … 873 904 } 874 905 875 export interface SerializablePluginCache { 876 [key: string]: [number, any]; 877 } 906 export type SerializablePluginCache = Record<string, [number, any]>; 878 907 879 908 export interface RollupCache { … … 890 919 close: () => Promise<void>; 891 920 closed: boolean; 921 [Symbol.asyncDispose](): Promise<void>; 892 922 generate: (outputOptions: OutputOptions) => Promise<RollupOutput>; 893 923 getTimings?: () => SerializedTimings; … … 947 977 948 978 export type AwaitedEventListener< 949 T extends { [event: string]: (...parameters: any) => any },979 T extends Record<string, (...parameters: any) => any>, 950 980 K extends keyof T 951 981 > = (...parameters: Parameters<T[K]>) => void | Promise<void>; 952 982 953 export interface AwaitingEventEmitter<T extends { [event: string]: (...parameters: any) => any }> {983 export interface AwaitingEventEmitter<T extends Record<string, (...parameters: any) => any>> { 954 984 close(): Promise<void>; 955 985 emit<K extends keyof T>(event: K, ...parameters: Parameters<T[K]>): Promise<unknown>; -
imaps-frontend/node_modules/rollup/dist/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 -
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.