| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113 | 'use strict';const fill = require('fill-range');const stringify = require('./stringify');const utils = require('./utils');const append = (queue = '', stash = '', enclose = false) => {  const 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 (const item of queue) {    if (Array.isArray(item)) {      for (const 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 = {}) => {  const rangeLimit = options.rangeLimit === undefined ? 1000 : options.rangeLimit;  const 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) {      const 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;    }    const 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++) {      const 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;
 |