diff options
Diffstat (limited to 'node_modules/braces/lib')
| -rw-r--r-- | node_modules/braces/lib/compile.js | 57 | ||||
| -rw-r--r-- | node_modules/braces/lib/constants.js | 57 | ||||
| -rw-r--r-- | node_modules/braces/lib/expand.js | 113 | ||||
| -rw-r--r-- | node_modules/braces/lib/parse.js | 333 | ||||
| -rw-r--r-- | node_modules/braces/lib/stringify.js | 32 | ||||
| -rw-r--r-- | node_modules/braces/lib/utils.js | 112 | 
6 files changed, 704 insertions, 0 deletions
diff --git a/node_modules/braces/lib/compile.js b/node_modules/braces/lib/compile.js new file mode 100644 index 0000000..3e984a4 --- /dev/null +++ b/node_modules/braces/lib/compile.js @@ -0,0 +1,57 @@ +'use strict'; + +const fill = require('fill-range'); +const utils = require('./utils'); + +const compile = (ast, options = {}) => { +  let walk = (node, parent = {}) => { +    let invalidBlock = utils.isInvalidBrace(parent); +    let invalidNode = node.invalid === true && options.escapeInvalid === true; +    let invalid = invalidBlock === true || invalidNode === true; +    let prefix = options.escapeInvalid === true ? '\\' : ''; +    let output = ''; + +    if (node.isOpen === true) { +      return prefix + node.value; +    } +    if (node.isClose === true) { +      return prefix + node.value; +    } + +    if (node.type === 'open') { +      return invalid ? (prefix + node.value) : '('; +    } + +    if (node.type === 'close') { +      return invalid ? (prefix + node.value) : ')'; +    } + +    if (node.type === 'comma') { +      return node.prev.type === 'comma' ? '' : (invalid ? node.value : '|'); +    } + +    if (node.value) { +      return node.value; +    } + +    if (node.nodes && node.ranges > 0) { +      let args = utils.reduce(node.nodes); +      let range = fill(...args, { ...options, wrap: false, toRegex: true }); + +      if (range.length !== 0) { +        return args.length > 1 && range.length > 1 ? `(${range})` : range; +      } +    } + +    if (node.nodes) { +      for (let child of node.nodes) { +        output += walk(child, node); +      } +    } +    return output; +  }; + +  return walk(ast); +}; + +module.exports = compile; diff --git a/node_modules/braces/lib/constants.js b/node_modules/braces/lib/constants.js new file mode 100644 index 0000000..a937943 --- /dev/null +++ b/node_modules/braces/lib/constants.js @@ -0,0 +1,57 @@ +'use strict'; + +module.exports = { +  MAX_LENGTH: 1024 * 64, + +  // Digits +  CHAR_0: '0', /* 0 */ +  CHAR_9: '9', /* 9 */ + +  // Alphabet chars. +  CHAR_UPPERCASE_A: 'A', /* A */ +  CHAR_LOWERCASE_A: 'a', /* a */ +  CHAR_UPPERCASE_Z: 'Z', /* Z */ +  CHAR_LOWERCASE_Z: 'z', /* z */ + +  CHAR_LEFT_PARENTHESES: '(', /* ( */ +  CHAR_RIGHT_PARENTHESES: ')', /* ) */ + +  CHAR_ASTERISK: '*', /* * */ + +  // Non-alphabetic chars. +  CHAR_AMPERSAND: '&', /* & */ +  CHAR_AT: '@', /* @ */ +  CHAR_BACKSLASH: '\\', /* \ */ +  CHAR_BACKTICK: '`', /* ` */ +  CHAR_CARRIAGE_RETURN: '\r', /* \r */ +  CHAR_CIRCUMFLEX_ACCENT: '^', /* ^ */ +  CHAR_COLON: ':', /* : */ +  CHAR_COMMA: ',', /* , */ +  CHAR_DOLLAR: '$', /* . */ +  CHAR_DOT: '.', /* . */ +  CHAR_DOUBLE_QUOTE: '"', /* " */ +  CHAR_EQUAL: '=', /* = */ +  CHAR_EXCLAMATION_MARK: '!', /* ! */ +  CHAR_FORM_FEED: '\f', /* \f */ +  CHAR_FORWARD_SLASH: '/', /* / */ +  CHAR_HASH: '#', /* # */ +  CHAR_HYPHEN_MINUS: '-', /* - */ +  CHAR_LEFT_ANGLE_BRACKET: '<', /* < */ +  CHAR_LEFT_CURLY_BRACE: '{', /* { */ +  CHAR_LEFT_SQUARE_BRACKET: '[', /* [ */ +  CHAR_LINE_FEED: '\n', /* \n */ +  CHAR_NO_BREAK_SPACE: '\u00A0', /* \u00A0 */ +  CHAR_PERCENT: '%', /* % */ +  CHAR_PLUS: '+', /* + */ +  CHAR_QUESTION_MARK: '?', /* ? */ +  CHAR_RIGHT_ANGLE_BRACKET: '>', /* > */ +  CHAR_RIGHT_CURLY_BRACE: '}', /* } */ +  CHAR_RIGHT_SQUARE_BRACKET: ']', /* ] */ +  CHAR_SEMICOLON: ';', /* ; */ +  CHAR_SINGLE_QUOTE: '\'', /* ' */ +  CHAR_SPACE: ' ', /*   */ +  CHAR_TAB: '\t', /* \t */ +  CHAR_UNDERSCORE: '_', /* _ */ +  CHAR_VERTICAL_LINE: '|', /* | */ +  CHAR_ZERO_WIDTH_NOBREAK_SPACE: '\uFEFF' /* \uFEFF */ +}; diff --git a/node_modules/braces/lib/expand.js b/node_modules/braces/lib/expand.js new file mode 100644 index 0000000..376c748 --- /dev/null +++ b/node_modules/braces/lib/expand.js @@ -0,0 +1,113 @@ +'use strict'; + +const fill = require('fill-range'); +const stringify = require('./stringify'); +const utils = require('./utils'); + +const append = (queue = '', stash = '', enclose = false) => { +  let result = []; + +  queue = [].concat(queue); +  stash = [].concat(stash); + +  if (!stash.length) return queue; +  if (!queue.length) { +    return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash; +  } + +  for (let item of queue) { +    if (Array.isArray(item)) { +      for (let value of item) { +        result.push(append(value, stash, enclose)); +      } +    } else { +      for (let ele of stash) { +        if (enclose === true && typeof ele === 'string') ele = `{${ele}}`; +        result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele)); +      } +    } +  } +  return utils.flatten(result); +}; + +const expand = (ast, options = {}) => { +  let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit; + +  let walk = (node, parent = {}) => { +    node.queue = []; + +    let p = parent; +    let q = parent.queue; + +    while (p.type !== 'brace' && p.type !== 'root' && p.parent) { +      p = p.parent; +      q = p.queue; +    } + +    if (node.invalid || node.dollar) { +      q.push(append(q.pop(), stringify(node, options))); +      return; +    } + +    if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) { +      q.push(append(q.pop(), ['{}'])); +      return; +    } + +    if (node.nodes && node.ranges > 0) { +      let args = utils.reduce(node.nodes); + +      if (utils.exceedsLimit(...args, options.step, rangeLimit)) { +        throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.'); +      } + +      let range = fill(...args, options); +      if (range.length === 0) { +        range = stringify(node, options); +      } + +      q.push(append(q.pop(), range)); +      node.nodes = []; +      return; +    } + +    let enclose = utils.encloseBrace(node); +    let queue = node.queue; +    let block = node; + +    while (block.type !== 'brace' && block.type !== 'root' && block.parent) { +      block = block.parent; +      queue = block.queue; +    } + +    for (let i = 0; i < node.nodes.length; i++) { +      let child = node.nodes[i]; + +      if (child.type === 'comma' && node.type === 'brace') { +        if (i === 1) queue.push(''); +        queue.push(''); +        continue; +      } + +      if (child.type === 'close') { +        q.push(append(q.pop(), queue, enclose)); +        continue; +      } + +      if (child.value && child.type !== 'open') { +        queue.push(append(queue.pop(), child.value)); +        continue; +      } + +      if (child.nodes) { +        walk(child, node); +      } +    } + +    return queue; +  }; + +  return utils.flatten(walk(ast)); +}; + +module.exports = expand; diff --git a/node_modules/braces/lib/parse.js b/node_modules/braces/lib/parse.js new file mode 100644 index 0000000..145ea26 --- /dev/null +++ b/node_modules/braces/lib/parse.js @@ -0,0 +1,333 @@ +'use strict'; + +const stringify = require('./stringify'); + +/** + * Constants + */ + +const { +  MAX_LENGTH, +  CHAR_BACKSLASH, /* \ */ +  CHAR_BACKTICK, /* ` */ +  CHAR_COMMA, /* , */ +  CHAR_DOT, /* . */ +  CHAR_LEFT_PARENTHESES, /* ( */ +  CHAR_RIGHT_PARENTHESES, /* ) */ +  CHAR_LEFT_CURLY_BRACE, /* { */ +  CHAR_RIGHT_CURLY_BRACE, /* } */ +  CHAR_LEFT_SQUARE_BRACKET, /* [ */ +  CHAR_RIGHT_SQUARE_BRACKET, /* ] */ +  CHAR_DOUBLE_QUOTE, /* " */ +  CHAR_SINGLE_QUOTE, /* ' */ +  CHAR_NO_BREAK_SPACE, +  CHAR_ZERO_WIDTH_NOBREAK_SPACE +} = require('./constants'); + +/** + * parse + */ + +const parse = (input, options = {}) => { +  if (typeof input !== 'string') { +    throw new TypeError('Expected a string'); +  } + +  let opts = options || {}; +  let max = typeof opts.maxLength === 'number' ? Math.min(MAX_LENGTH, opts.maxLength) : MAX_LENGTH; +  if (input.length > max) { +    throw new SyntaxError(`Input length (${input.length}), exceeds max characters (${max})`); +  } + +  let ast = { type: 'root', input, nodes: [] }; +  let stack = [ast]; +  let block = ast; +  let prev = ast; +  let brackets = 0; +  let length = input.length; +  let index = 0; +  let depth = 0; +  let value; +  let memo = {}; + +  /** +   * Helpers +   */ + +  const advance = () => input[index++]; +  const push = node => { +    if (node.type === 'text' && prev.type === 'dot') { +      prev.type = 'text'; +    } + +    if (prev && prev.type === 'text' && node.type === 'text') { +      prev.value += node.value; +      return; +    } + +    block.nodes.push(node); +    node.parent = block; +    node.prev = prev; +    prev = node; +    return node; +  }; + +  push({ type: 'bos' }); + +  while (index < length) { +    block = stack[stack.length - 1]; +    value = advance(); + +    /** +     * Invalid chars +     */ + +    if (value === CHAR_ZERO_WIDTH_NOBREAK_SPACE || value === CHAR_NO_BREAK_SPACE) { +      continue; +    } + +    /** +     * Escaped chars +     */ + +    if (value === CHAR_BACKSLASH) { +      push({ type: 'text', value: (options.keepEscaping ? value : '') + advance() }); +      continue; +    } + +    /** +     * Right square bracket (literal): ']' +     */ + +    if (value === CHAR_RIGHT_SQUARE_BRACKET) { +      push({ type: 'text', value: '\\' + value }); +      continue; +    } + +    /** +     * Left square bracket: '[' +     */ + +    if (value === CHAR_LEFT_SQUARE_BRACKET) { +      brackets++; + +      let closed = true; +      let next; + +      while (index < length && (next = advance())) { +        value += next; + +        if (next === CHAR_LEFT_SQUARE_BRACKET) { +          brackets++; +          continue; +        } + +        if (next === CHAR_BACKSLASH) { +          value += advance(); +          continue; +        } + +        if (next === CHAR_RIGHT_SQUARE_BRACKET) { +          brackets--; + +          if (brackets === 0) { +            break; +          } +        } +      } + +      push({ type: 'text', value }); +      continue; +    } + +    /** +     * Parentheses +     */ + +    if (value === CHAR_LEFT_PARENTHESES) { +      block = push({ type: 'paren', nodes: [] }); +      stack.push(block); +      push({ type: 'text', value }); +      continue; +    } + +    if (value === CHAR_RIGHT_PARENTHESES) { +      if (block.type !== 'paren') { +        push({ type: 'text', value }); +        continue; +      } +      block = stack.pop(); +      push({ type: 'text', value }); +      block = stack[stack.length - 1]; +      continue; +    } + +    /** +     * Quotes: '|"|` +     */ + +    if (value === CHAR_DOUBLE_QUOTE || value === CHAR_SINGLE_QUOTE || value === CHAR_BACKTICK) { +      let open = value; +      let next; + +      if (options.keepQuotes !== true) { +        value = ''; +      } + +      while (index < length && (next = advance())) { +        if (next === CHAR_BACKSLASH) { +          value += next + advance(); +          continue; +        } + +        if (next === open) { +          if (options.keepQuotes === true) value += next; +          break; +        } + +        value += next; +      } + +      push({ type: 'text', value }); +      continue; +    } + +    /** +     * Left curly brace: '{' +     */ + +    if (value === CHAR_LEFT_CURLY_BRACE) { +      depth++; + +      let dollar = prev.value && prev.value.slice(-1) === '$' || block.dollar === true; +      let brace = { +        type: 'brace', +        open: true, +        close: false, +        dollar, +        depth, +        commas: 0, +        ranges: 0, +        nodes: [] +      }; + +      block = push(brace); +      stack.push(block); +      push({ type: 'open', value }); +      continue; +    } + +    /** +     * Right curly brace: '}' +     */ + +    if (value === CHAR_RIGHT_CURLY_BRACE) { +      if (block.type !== 'brace') { +        push({ type: 'text', value }); +        continue; +      } + +      let type = 'close'; +      block = stack.pop(); +      block.close = true; + +      push({ type, value }); +      depth--; + +      block = stack[stack.length - 1]; +      continue; +    } + +    /** +     * Comma: ',' +     */ + +    if (value === CHAR_COMMA && depth > 0) { +      if (block.ranges > 0) { +        block.ranges = 0; +        let open = block.nodes.shift(); +        block.nodes = [open, { type: 'text', value: stringify(block) }]; +      } + +      push({ type: 'comma', value }); +      block.commas++; +      continue; +    } + +    /** +     * Dot: '.' +     */ + +    if (value === CHAR_DOT && depth > 0 && block.commas === 0) { +      let siblings = block.nodes; + +      if (depth === 0 || siblings.length === 0) { +        push({ type: 'text', value }); +        continue; +      } + +      if (prev.type === 'dot') { +        block.range = []; +        prev.value += value; +        prev.type = 'range'; + +        if (block.nodes.length !== 3 && block.nodes.length !== 5) { +          block.invalid = true; +          block.ranges = 0; +          prev.type = 'text'; +          continue; +        } + +        block.ranges++; +        block.args = []; +        continue; +      } + +      if (prev.type === 'range') { +        siblings.pop(); + +        let before = siblings[siblings.length - 1]; +        before.value += prev.value + value; +        prev = before; +        block.ranges--; +        continue; +      } + +      push({ type: 'dot', value }); +      continue; +    } + +    /** +     * Text +     */ + +    push({ type: 'text', value }); +  } + +  // Mark imbalanced braces and brackets as invalid +  do { +    block = stack.pop(); + +    if (block.type !== 'root') { +      block.nodes.forEach(node => { +        if (!node.nodes) { +          if (node.type === 'open') node.isOpen = true; +          if (node.type === 'close') node.isClose = true; +          if (!node.nodes) node.type = 'text'; +          node.invalid = true; +        } +      }); + +      // get the location of the block on parent.nodes (block's siblings) +      let parent = stack[stack.length - 1]; +      let index = parent.nodes.indexOf(block); +      // replace the (invalid) block with it's nodes +      parent.nodes.splice(index, 1, ...block.nodes); +    } +  } while (stack.length > 0); + +  push({ type: 'eos' }); +  return ast; +}; + +module.exports = parse; diff --git a/node_modules/braces/lib/stringify.js b/node_modules/braces/lib/stringify.js new file mode 100644 index 0000000..414b7bc --- /dev/null +++ b/node_modules/braces/lib/stringify.js @@ -0,0 +1,32 @@ +'use strict'; + +const utils = require('./utils'); + +module.exports = (ast, options = {}) => { +  let stringify = (node, parent = {}) => { +    let invalidBlock = options.escapeInvalid && utils.isInvalidBrace(parent); +    let invalidNode = node.invalid === true && options.escapeInvalid === true; +    let output = ''; + +    if (node.value) { +      if ((invalidBlock || invalidNode) && utils.isOpenOrClose(node)) { +        return '\\' + node.value; +      } +      return node.value; +    } + +    if (node.value) { +      return node.value; +    } + +    if (node.nodes) { +      for (let child of node.nodes) { +        output += stringify(child); +      } +    } +    return output; +  }; + +  return stringify(ast); +}; + diff --git a/node_modules/braces/lib/utils.js b/node_modules/braces/lib/utils.js new file mode 100644 index 0000000..e3551a6 --- /dev/null +++ b/node_modules/braces/lib/utils.js @@ -0,0 +1,112 @@ +'use strict'; + +exports.isInteger = num => { +  if (typeof num === 'number') { +    return Number.isInteger(num); +  } +  if (typeof num === 'string' && num.trim() !== '') { +    return Number.isInteger(Number(num)); +  } +  return false; +}; + +/** + * Find a node of the given type + */ + +exports.find = (node, type) => node.nodes.find(node => node.type === type); + +/** + * Find a node of the given type + */ + +exports.exceedsLimit = (min, max, step = 1, limit) => { +  if (limit === false) return false; +  if (!exports.isInteger(min) || !exports.isInteger(max)) return false; +  return ((Number(max) - Number(min)) / Number(step)) >= limit; +}; + +/** + * Escape the given node with '\\' before node.value + */ + +exports.escapeNode = (block, n = 0, type) => { +  let node = block.nodes[n]; +  if (!node) return; + +  if ((type && node.type === type) || node.type === 'open' || node.type === 'close') { +    if (node.escaped !== true) { +      node.value = '\\' + node.value; +      node.escaped = true; +    } +  } +}; + +/** + * Returns true if the given brace node should be enclosed in literal braces + */ + +exports.encloseBrace = node => { +  if (node.type !== 'brace') return false; +  if ((node.commas >> 0 + node.ranges >> 0) === 0) { +    node.invalid = true; +    return true; +  } +  return false; +}; + +/** + * Returns true if a brace node is invalid. + */ + +exports.isInvalidBrace = block => { +  if (block.type !== 'brace') return false; +  if (block.invalid === true || block.dollar) return true; +  if ((block.commas >> 0 + block.ranges >> 0) === 0) { +    block.invalid = true; +    return true; +  } +  if (block.open !== true || block.close !== true) { +    block.invalid = true; +    return true; +  } +  return false; +}; + +/** + * Returns true if a node is an open or close node + */ + +exports.isOpenOrClose = node => { +  if (node.type === 'open' || node.type === 'close') { +    return true; +  } +  return node.open === true || node.close === true; +}; + +/** + * Reduce an array of text nodes. + */ + +exports.reduce = nodes => nodes.reduce((acc, node) => { +  if (node.type === 'text') acc.push(node.value); +  if (node.type === 'range') node.type = 'text'; +  return acc; +}, []); + +/** + * Flatten an array + */ + +exports.flatten = (...args) => { +  const result = []; +  const flat = arr => { +    for (let i = 0; i < arr.length; i++) { +      let ele = arr[i]; +      Array.isArray(ele) ? flat(ele, result) : ele !== void 0 && result.push(ele); +    } +    return result; +  }; +  flat(args); +  return result; +};  | 
