glob.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. (function (factory) {
  2. if (typeof module === "object" && typeof module.exports === "object") {
  3. var v = factory(require, exports);
  4. if (v !== undefined) module.exports = v;
  5. }
  6. else if (typeof define === "function" && define.amd) {
  7. define(["require", "exports"], factory);
  8. }
  9. })(function (require, exports) {
  10. "use strict";
  11. Object.defineProperty(exports, "__esModule", { value: true });
  12. exports.createRegex = void 0;
  13. /*---------------------------------------------------------------------------------------------
  14. * Copyright (c) Microsoft Corporation. All rights reserved.
  15. * Copyright (c) 2013, Nick Fitzgerald
  16. * Licensed under the MIT License. See LICENCE.md in the project root for license information.
  17. *--------------------------------------------------------------------------------------------*/
  18. function createRegex(glob, opts) {
  19. if (typeof glob !== 'string') {
  20. throw new TypeError('Expected a string');
  21. }
  22. var str = String(glob);
  23. // The regexp we are building, as a string.
  24. var reStr = "";
  25. // Whether we are matching so called "extended" globs (like bash) and should
  26. // support single character matching, matching ranges of characters, group
  27. // matching, etc.
  28. var extended = opts ? !!opts.extended : false;
  29. // When globstar is _false_ (default), '/foo/*' is translated a regexp like
  30. // '^\/foo\/.*$' which will match any string beginning with '/foo/'
  31. // When globstar is _true_, '/foo/*' is translated to regexp like
  32. // '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT
  33. // which does not have a '/' to the right of it.
  34. // E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but
  35. // these will not '/foo/bar/baz', '/foo/bar/baz.txt'
  36. // Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when
  37. // globstar is _false_
  38. var globstar = opts ? !!opts.globstar : false;
  39. // If we are doing extended matching, this boolean is true when we are inside
  40. // a group (eg {*.html,*.js}), and false otherwise.
  41. var inGroup = false;
  42. // RegExp flags (eg "i" ) to pass in to RegExp constructor.
  43. var flags = opts && typeof (opts.flags) === "string" ? opts.flags : "";
  44. var c;
  45. for (var i = 0, len = str.length; i < len; i++) {
  46. c = str[i];
  47. switch (c) {
  48. case "/":
  49. case "$":
  50. case "^":
  51. case "+":
  52. case ".":
  53. case "(":
  54. case ")":
  55. case "=":
  56. case "!":
  57. case "|":
  58. reStr += "\\" + c;
  59. break;
  60. case "?":
  61. if (extended) {
  62. reStr += ".";
  63. break;
  64. }
  65. case "[":
  66. case "]":
  67. if (extended) {
  68. reStr += c;
  69. break;
  70. }
  71. case "{":
  72. if (extended) {
  73. inGroup = true;
  74. reStr += "(";
  75. break;
  76. }
  77. case "}":
  78. if (extended) {
  79. inGroup = false;
  80. reStr += ")";
  81. break;
  82. }
  83. case ",":
  84. if (inGroup) {
  85. reStr += "|";
  86. break;
  87. }
  88. reStr += "\\" + c;
  89. break;
  90. case "*":
  91. // Move over all consecutive "*"'s.
  92. // Also store the previous and next characters
  93. var prevChar = str[i - 1];
  94. var starCount = 1;
  95. while (str[i + 1] === "*") {
  96. starCount++;
  97. i++;
  98. }
  99. var nextChar = str[i + 1];
  100. if (!globstar) {
  101. // globstar is disabled, so treat any number of "*" as one
  102. reStr += ".*";
  103. }
  104. else {
  105. // globstar is enabled, so determine if this is a globstar segment
  106. var isGlobstar = starCount > 1 // multiple "*"'s
  107. && (prevChar === "/" || prevChar === undefined || prevChar === '{' || prevChar === ',') // from the start of the segment
  108. && (nextChar === "/" || nextChar === undefined || nextChar === ',' || nextChar === '}'); // to the end of the segment
  109. if (isGlobstar) {
  110. if (nextChar === "/") {
  111. i++; // move over the "/"
  112. }
  113. else if (prevChar === '/' && reStr.endsWith('\\/')) {
  114. reStr = reStr.substr(0, reStr.length - 2);
  115. }
  116. // it's a globstar, so match zero or more path segments
  117. reStr += "((?:[^/]*(?:\/|$))*)";
  118. }
  119. else {
  120. // it's not a globstar, so only match one path segment
  121. reStr += "([^/]*)";
  122. }
  123. }
  124. break;
  125. default:
  126. reStr += c;
  127. }
  128. }
  129. // When regexp 'g' flag is specified don't
  130. // constrain the regular expression with ^ & $
  131. if (!flags || !~flags.indexOf('g')) {
  132. reStr = "^" + reStr + "$";
  133. }
  134. return new RegExp(reStr, flags);
  135. }
  136. exports.createRegex = createRegex;
  137. ;
  138. });