glob.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.Glob = void 0;
  4. const minimatch_1 = require("minimatch");
  5. const path_scurry_1 = require("path-scurry");
  6. const url_1 = require("url");
  7. const pattern_js_1 = require("./pattern.js");
  8. const walker_js_1 = require("./walker.js");
  9. // if no process global, just call it linux.
  10. // so we default to case-sensitive, / separators
  11. const defaultPlatform = typeof process === 'object' &&
  12. process &&
  13. typeof process.platform === 'string'
  14. ? process.platform
  15. : 'linux';
  16. /**
  17. * An object that can perform glob pattern traversals.
  18. */
  19. class Glob {
  20. absolute;
  21. cwd;
  22. dot;
  23. follow;
  24. ignore;
  25. mark;
  26. matchBase;
  27. nobrace;
  28. nocase;
  29. nodir;
  30. noext;
  31. noglobstar;
  32. pattern;
  33. platform;
  34. realpath;
  35. scurry;
  36. signal;
  37. windowsPathsNoEscape;
  38. withFileTypes;
  39. /**
  40. * The options provided to the constructor.
  41. */
  42. opts;
  43. /**
  44. * An array of parsed immutable {@link Pattern} objects.
  45. */
  46. patterns;
  47. /**
  48. * All options are stored as properties on the `Glob` object.
  49. *
  50. * See {@link GlobOptions} for full options descriptions.
  51. *
  52. * Note that a previous `Glob` object can be passed as the
  53. * `GlobOptions` to another `Glob` instantiation to re-use settings
  54. * and caches with a new pattern.
  55. *
  56. * Traversal functions can be called multiple times to run the walk
  57. * again.
  58. */
  59. constructor(pattern, opts) {
  60. this.withFileTypes = !!opts.withFileTypes;
  61. this.signal = opts.signal;
  62. this.follow = !!opts.follow;
  63. this.dot = !!opts.dot;
  64. this.nodir = !!opts.nodir;
  65. this.mark = !!opts.mark;
  66. if (!opts.cwd) {
  67. this.cwd = '';
  68. }
  69. else if (opts.cwd instanceof URL || opts.cwd.startsWith('file://')) {
  70. opts.cwd = (0, url_1.fileURLToPath)(opts.cwd);
  71. }
  72. this.cwd = opts.cwd || '';
  73. this.nobrace = !!opts.nobrace;
  74. this.noext = !!opts.noext;
  75. this.realpath = !!opts.realpath;
  76. this.absolute = !!opts.absolute;
  77. this.noglobstar = !!opts.noglobstar;
  78. this.matchBase = !!opts.matchBase;
  79. if (this.withFileTypes && this.absolute) {
  80. throw new Error('cannot set absolute:true and withFileTypes:true');
  81. }
  82. if (typeof pattern === 'string') {
  83. pattern = [pattern];
  84. }
  85. this.windowsPathsNoEscape =
  86. !!opts.windowsPathsNoEscape ||
  87. opts.allowWindowsEscape === false;
  88. if (this.windowsPathsNoEscape) {
  89. pattern = pattern.map(p => p.replace(/\\/g, '/'));
  90. }
  91. if (this.matchBase) {
  92. if (opts.noglobstar) {
  93. throw new TypeError('base matching requires globstar');
  94. }
  95. pattern = pattern.map(p => (p.includes('/') ? p : `./**/${p}`));
  96. }
  97. this.pattern = pattern;
  98. this.platform = opts.platform || defaultPlatform;
  99. this.opts = { ...opts, platform: this.platform };
  100. if (opts.scurry) {
  101. this.scurry = opts.scurry;
  102. if (opts.nocase !== undefined &&
  103. opts.nocase !== opts.scurry.nocase) {
  104. throw new Error('nocase option contradicts provided scurry option');
  105. }
  106. }
  107. else {
  108. const Scurry = opts.platform === 'win32'
  109. ? path_scurry_1.PathScurryWin32
  110. : opts.platform === 'darwin'
  111. ? path_scurry_1.PathScurryDarwin
  112. : opts.platform
  113. ? path_scurry_1.PathScurryPosix
  114. : path_scurry_1.PathScurry;
  115. this.scurry = new Scurry(this.cwd, { nocase: opts.nocase });
  116. }
  117. this.nocase = this.scurry.nocase;
  118. const mmo = {
  119. // default nocase based on platform
  120. ...opts,
  121. dot: this.dot,
  122. matchBase: this.matchBase,
  123. nobrace: this.nobrace,
  124. nocase: this.nocase,
  125. nocaseMagicOnly: true,
  126. nocomment: true,
  127. noext: this.noext,
  128. nonegate: true,
  129. optimizationLevel: 2,
  130. platform: this.platform,
  131. windowsPathsNoEscape: this.windowsPathsNoEscape,
  132. };
  133. const mms = this.pattern.map(p => new minimatch_1.Minimatch(p, mmo));
  134. const [matchSet, globParts] = mms.reduce((set, m) => {
  135. set[0].push(...m.set);
  136. set[1].push(...m.globParts);
  137. return set;
  138. }, [[], []]);
  139. this.patterns = matchSet.map((set, i) => {
  140. return new pattern_js_1.Pattern(set, globParts[i], 0, this.platform);
  141. });
  142. }
  143. async walk() {
  144. // Walkers always return array of Path objects, so we just have to
  145. // coerce them into the right shape. It will have already called
  146. // realpath() if the option was set to do so, so we know that's cached.
  147. // start out knowing the cwd, at least
  148. return [
  149. ...(await new walker_js_1.GlobWalker(this.patterns, this.scurry.cwd, {
  150. ...this.opts,
  151. platform: this.platform,
  152. nocase: this.nocase,
  153. }).walk()),
  154. ];
  155. }
  156. walkSync() {
  157. return [
  158. ...new walker_js_1.GlobWalker(this.patterns, this.scurry.cwd, {
  159. ...this.opts,
  160. platform: this.platform,
  161. nocase: this.nocase,
  162. }).walkSync(),
  163. ];
  164. }
  165. stream() {
  166. return new walker_js_1.GlobStream(this.patterns, this.scurry.cwd, {
  167. ...this.opts,
  168. platform: this.platform,
  169. nocase: this.nocase,
  170. }).stream();
  171. }
  172. streamSync() {
  173. return new walker_js_1.GlobStream(this.patterns, this.scurry.cwd, {
  174. ...this.opts,
  175. platform: this.platform,
  176. nocase: this.nocase,
  177. }).streamSync();
  178. }
  179. /**
  180. * Default sync iteration function. Returns a Generator that
  181. * iterates over the results.
  182. */
  183. iterateSync() {
  184. return this.streamSync()[Symbol.iterator]();
  185. }
  186. [Symbol.iterator]() {
  187. return this.iterateSync();
  188. }
  189. /**
  190. * Default async iteration function. Returns an AsyncGenerator that
  191. * iterates over the results.
  192. */
  193. iterate() {
  194. return this.stream()[Symbol.asyncIterator]();
  195. }
  196. [Symbol.asyncIterator]() {
  197. return this.iterate();
  198. }
  199. }
  200. exports.Glob = Glob;
  201. //# sourceMappingURL=glob.js.map