glob.js 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.globSync = globSync;
  4. const pathModule = require("path");
  5. const util_1 = require("./util");
  6. const { sep, join, relative, resolve } = pathModule.posix;
  7. /**
  8. * Convert a glob pattern to a regular expression
  9. * Supports: *, ?, **, [abc], [!abc], [a-z]
  10. */
  11. function globToRegex(pattern) {
  12. let regexStr = '';
  13. let i = 0;
  14. while (i < pattern.length) {
  15. const char = pattern[i];
  16. switch (char) {
  17. case '*':
  18. if (pattern[i + 1] === '*') {
  19. // Handle **
  20. if (pattern[i + 2] === '/' || i + 2 === pattern.length) {
  21. regexStr += '(?:.*\\/)?'; // Match zero or more directories
  22. i += pattern[i + 2] === '/' ? 3 : 2;
  23. }
  24. else {
  25. regexStr += '[^/]*'; // Single *
  26. i++;
  27. }
  28. }
  29. else {
  30. regexStr += '[^/]*'; // Single *
  31. i++;
  32. }
  33. break;
  34. case '?':
  35. regexStr += '[^/]';
  36. i++;
  37. break;
  38. case '[':
  39. regexStr += '[';
  40. i++;
  41. if (i < pattern.length && pattern[i] === '!') {
  42. regexStr += '^';
  43. i++;
  44. }
  45. while (i < pattern.length && pattern[i] !== ']') {
  46. if (pattern[i] === '\\') {
  47. regexStr += '\\\\';
  48. i++;
  49. }
  50. regexStr += pattern[i];
  51. i++;
  52. }
  53. regexStr += ']';
  54. i++;
  55. break;
  56. case '.':
  57. case '^':
  58. case '$':
  59. case '+':
  60. case '{':
  61. case '}':
  62. case '(':
  63. case ')':
  64. case '|':
  65. case '\\':
  66. regexStr += '\\' + char;
  67. i++;
  68. break;
  69. default:
  70. regexStr += char;
  71. i++;
  72. break;
  73. }
  74. }
  75. return new RegExp('^' + regexStr + '$');
  76. }
  77. /**
  78. * Check if a path matches a glob pattern
  79. */
  80. function matchesPattern(path, pattern) {
  81. const regex = globToRegex(pattern);
  82. return regex.test(path);
  83. }
  84. /**
  85. * Check if a path should be excluded based on exclude patterns
  86. */
  87. function isExcluded(path, exclude) {
  88. if (!exclude)
  89. return false;
  90. if (typeof exclude === 'function') {
  91. return exclude(path);
  92. }
  93. const patterns = Array.isArray(exclude) ? exclude : [exclude];
  94. return patterns.some(pattern => matchesPattern(path, pattern));
  95. }
  96. /**
  97. * Walk directory tree and collect matching paths
  98. */
  99. function walkDirectory(fs, dir, patterns, options, currentDepth = 0) {
  100. var _a;
  101. const results = [];
  102. const maxDepth = (_a = options.maxdepth) !== null && _a !== void 0 ? _a : Infinity;
  103. const baseCwd = options.cwd ? (0, util_1.pathToFilename)(options.cwd) : process.cwd();
  104. if (currentDepth > maxDepth) {
  105. return results;
  106. }
  107. try {
  108. const entries = fs.readdirSync(dir, { withFileTypes: true });
  109. for (const entry of entries) {
  110. const fullPath = join(dir, entry.name.toString());
  111. const relativePath = relative(baseCwd, fullPath);
  112. // Skip if excluded
  113. if (isExcluded(relativePath, options.exclude)) {
  114. continue;
  115. }
  116. // Check if this path matches any pattern
  117. const matches = patterns.some(pattern => matchesPattern(relativePath, pattern));
  118. if (matches) {
  119. results.push(relativePath);
  120. }
  121. // Recurse into directories
  122. if (entry.isDirectory() && currentDepth < maxDepth) {
  123. const subResults = walkDirectory(fs, fullPath, patterns, options, currentDepth + 1);
  124. results.push(...subResults);
  125. }
  126. }
  127. }
  128. catch (err) {
  129. // Skip directories we can't read
  130. }
  131. return results;
  132. }
  133. /**
  134. * Main glob implementation
  135. */
  136. function globSync(fs, pattern, options = {}) {
  137. const cwd = options.cwd ? (0, util_1.pathToFilename)(options.cwd) : process.cwd();
  138. const resolvedCwd = resolve(cwd);
  139. const globOptions = {
  140. cwd: resolvedCwd,
  141. exclude: options.exclude,
  142. maxdepth: options.maxdepth,
  143. withFileTypes: options.withFileTypes || false,
  144. };
  145. let results = [];
  146. // Handle absolute patterns
  147. if (pathModule.posix.isAbsolute(pattern)) {
  148. const dir = pathModule.posix.dirname(pattern);
  149. const basename = pathModule.posix.basename(pattern);
  150. const dirResults = walkDirectory(fs, dir, [basename], Object.assign(Object.assign({}, globOptions), { cwd: dir }));
  151. results.push(...dirResults.map(r => pathModule.posix.resolve(dir, r)));
  152. }
  153. else {
  154. // Handle relative patterns
  155. const dirResults = walkDirectory(fs, resolvedCwd, [pattern], globOptions);
  156. results.push(...dirResults);
  157. }
  158. // Remove duplicates and sort
  159. results = [...new Set(results)].sort();
  160. return results;
  161. }
  162. //# sourceMappingURL=glob.js.map