Changeset 0c6b92a for imaps-frontend/node_modules/rollup/dist/es/shared
- Timestamp:
- 12/12/24 17:06:06 (5 weeks ago)
- Branches:
- main
- Parents:
- d565449
- Location:
- imaps-frontend/node_modules/rollup/dist/es/shared
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
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 });
Note:
See TracChangeset
for help on using the changeset viewer.