You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
4.3 KiB

2 years ago
  1. 'use strict';
  2. const stringify = require('./lib/stringify');
  3. const compile = require('./lib/compile');
  4. const expand = require('./lib/expand');
  5. const parse = require('./lib/parse');
  6. /**
  7. * Expand the given pattern or create a regex-compatible string.
  8. *
  9. * ```js
  10. * const braces = require('braces');
  11. * console.log(braces('{a,b,c}', { compile: true })); //=> ['(a|b|c)']
  12. * console.log(braces('{a,b,c}')); //=> ['a', 'b', 'c']
  13. * ```
  14. * @param {String} `str`
  15. * @param {Object} `options`
  16. * @return {String}
  17. * @api public
  18. */
  19. const braces = (input, options = {}) => {
  20. let output = [];
  21. if (Array.isArray(input)) {
  22. for (let pattern of input) {
  23. let result = braces.create(pattern, options);
  24. if (Array.isArray(result)) {
  25. output.push(...result);
  26. } else {
  27. output.push(result);
  28. }
  29. }
  30. } else {
  31. output = [].concat(braces.create(input, options));
  32. }
  33. if (options && options.expand === true && options.nodupes === true) {
  34. output = [...new Set(output)];
  35. }
  36. return output;
  37. };
  38. /**
  39. * Parse the given `str` with the given `options`.
  40. *
  41. * ```js
  42. * // braces.parse(pattern, [, options]);
  43. * const ast = braces.parse('a/{b,c}/d');
  44. * console.log(ast);
  45. * ```
  46. * @param {String} pattern Brace pattern to parse
  47. * @param {Object} options
  48. * @return {Object} Returns an AST
  49. * @api public
  50. */
  51. braces.parse = (input, options = {}) => parse(input, options);
  52. /**
  53. * Creates a braces string from an AST, or an AST node.
  54. *
  55. * ```js
  56. * const braces = require('braces');
  57. * let ast = braces.parse('foo/{a,b}/bar');
  58. * console.log(stringify(ast.nodes[2])); //=> '{a,b}'
  59. * ```
  60. * @param {String} `input` Brace pattern or AST.
  61. * @param {Object} `options`
  62. * @return {Array} Returns an array of expanded values.
  63. * @api public
  64. */
  65. braces.stringify = (input, options = {}) => {
  66. if (typeof input === 'string') {
  67. return stringify(braces.parse(input, options), options);
  68. }
  69. return stringify(input, options);
  70. };
  71. /**
  72. * Compiles a brace pattern into a regex-compatible, optimized string.
  73. * This method is called by the main [braces](#braces) function by default.
  74. *
  75. * ```js
  76. * const braces = require('braces');
  77. * console.log(braces.compile('a/{b,c}/d'));
  78. * //=> ['a/(b|c)/d']
  79. * ```
  80. * @param {String} `input` Brace pattern or AST.
  81. * @param {Object} `options`
  82. * @return {Array} Returns an array of expanded values.
  83. * @api public
  84. */
  85. braces.compile = (input, options = {}) => {
  86. if (typeof input === 'string') {
  87. input = braces.parse(input, options);
  88. }
  89. return compile(input, options);
  90. };
  91. /**
  92. * Expands a brace pattern into an array. This method is called by the
  93. * main [braces](#braces) function when `options.expand` is true. Before
  94. * using this method it's recommended that you read the [performance notes](#performance))
  95. * and advantages of using [.compile](#compile) instead.
  96. *
  97. * ```js
  98. * const braces = require('braces');
  99. * console.log(braces.expand('a/{b,c}/d'));
  100. * //=> ['a/b/d', 'a/c/d'];
  101. * ```
  102. * @param {String} `pattern` Brace pattern
  103. * @param {Object} `options`
  104. * @return {Array} Returns an array of expanded values.
  105. * @api public
  106. */
  107. braces.expand = (input, options = {}) => {
  108. if (typeof input === 'string') {
  109. input = braces.parse(input, options);
  110. }
  111. let result = expand(input, options);
  112. // filter out empty strings if specified
  113. if (options.noempty === true) {
  114. result = result.filter(Boolean);
  115. }
  116. // filter out duplicates if specified
  117. if (options.nodupes === true) {
  118. result = [...new Set(result)];
  119. }
  120. return result;
  121. };
  122. /**
  123. * Processes a brace pattern and returns either an expanded array
  124. * (if `options.expand` is true), a highly optimized regex-compatible string.
  125. * This method is called by the main [braces](#braces) function.
  126. *
  127. * ```js
  128. * const braces = require('braces');
  129. * console.log(braces.create('user-{200..300}/project-{a,b,c}-{1..10}'))
  130. * //=> 'user-(20[0-9]|2[1-9][0-9]|300)/project-(a|b|c)-([1-9]|10)'
  131. * ```
  132. * @param {String} `pattern` Brace pattern
  133. * @param {Object} `options`
  134. * @return {Array} Returns an array of expanded values.
  135. * @api public
  136. */
  137. braces.create = (input, options = {}) => {
  138. if (input === '' || input.length < 3) {
  139. return [input];
  140. }
  141. return options.expand !== true
  142. ? braces.compile(input, options)
  143. : braces.expand(input, options);
  144. };
  145. /**
  146. * Expose "braces"
  147. */
  148. module.exports = braces;