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.
|
|
'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;
|