[6a3a178] | 1 | 'use strict';
|
---|
| 2 |
|
---|
| 3 | const fill = require('fill-range');
|
---|
| 4 | const stringify = require('./stringify');
|
---|
| 5 | const utils = require('./utils');
|
---|
| 6 |
|
---|
| 7 | const append = (queue = '', stash = '', enclose = false) => {
|
---|
| 8 | let result = [];
|
---|
| 9 |
|
---|
| 10 | queue = [].concat(queue);
|
---|
| 11 | stash = [].concat(stash);
|
---|
| 12 |
|
---|
| 13 | if (!stash.length) return queue;
|
---|
| 14 | if (!queue.length) {
|
---|
| 15 | return enclose ? utils.flatten(stash).map(ele => `{${ele}}`) : stash;
|
---|
| 16 | }
|
---|
| 17 |
|
---|
| 18 | for (let item of queue) {
|
---|
| 19 | if (Array.isArray(item)) {
|
---|
| 20 | for (let value of item) {
|
---|
| 21 | result.push(append(value, stash, enclose));
|
---|
| 22 | }
|
---|
| 23 | } else {
|
---|
| 24 | for (let ele of stash) {
|
---|
| 25 | if (enclose === true && typeof ele === 'string') ele = `{${ele}}`;
|
---|
| 26 | result.push(Array.isArray(ele) ? append(item, ele, enclose) : (item + ele));
|
---|
| 27 | }
|
---|
| 28 | }
|
---|
| 29 | }
|
---|
| 30 | return utils.flatten(result);
|
---|
| 31 | };
|
---|
| 32 |
|
---|
| 33 | const expand = (ast, options = {}) => {
|
---|
| 34 | let rangeLimit = options.rangeLimit === void 0 ? 1000 : options.rangeLimit;
|
---|
| 35 |
|
---|
| 36 | let walk = (node, parent = {}) => {
|
---|
| 37 | node.queue = [];
|
---|
| 38 |
|
---|
| 39 | let p = parent;
|
---|
| 40 | let q = parent.queue;
|
---|
| 41 |
|
---|
| 42 | while (p.type !== 'brace' && p.type !== 'root' && p.parent) {
|
---|
| 43 | p = p.parent;
|
---|
| 44 | q = p.queue;
|
---|
| 45 | }
|
---|
| 46 |
|
---|
| 47 | if (node.invalid || node.dollar) {
|
---|
| 48 | q.push(append(q.pop(), stringify(node, options)));
|
---|
| 49 | return;
|
---|
| 50 | }
|
---|
| 51 |
|
---|
| 52 | if (node.type === 'brace' && node.invalid !== true && node.nodes.length === 2) {
|
---|
| 53 | q.push(append(q.pop(), ['{}']));
|
---|
| 54 | return;
|
---|
| 55 | }
|
---|
| 56 |
|
---|
| 57 | if (node.nodes && node.ranges > 0) {
|
---|
| 58 | let args = utils.reduce(node.nodes);
|
---|
| 59 |
|
---|
| 60 | if (utils.exceedsLimit(...args, options.step, rangeLimit)) {
|
---|
| 61 | throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | let range = fill(...args, options);
|
---|
| 65 | if (range.length === 0) {
|
---|
| 66 | range = stringify(node, options);
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | q.push(append(q.pop(), range));
|
---|
| 70 | node.nodes = [];
|
---|
| 71 | return;
|
---|
| 72 | }
|
---|
| 73 |
|
---|
| 74 | let enclose = utils.encloseBrace(node);
|
---|
| 75 | let queue = node.queue;
|
---|
| 76 | let block = node;
|
---|
| 77 |
|
---|
| 78 | while (block.type !== 'brace' && block.type !== 'root' && block.parent) {
|
---|
| 79 | block = block.parent;
|
---|
| 80 | queue = block.queue;
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | for (let i = 0; i < node.nodes.length; i++) {
|
---|
| 84 | let child = node.nodes[i];
|
---|
| 85 |
|
---|
| 86 | if (child.type === 'comma' && node.type === 'brace') {
|
---|
| 87 | if (i === 1) queue.push('');
|
---|
| 88 | queue.push('');
|
---|
| 89 | continue;
|
---|
| 90 | }
|
---|
| 91 |
|
---|
| 92 | if (child.type === 'close') {
|
---|
| 93 | q.push(append(q.pop(), queue, enclose));
|
---|
| 94 | continue;
|
---|
| 95 | }
|
---|
| 96 |
|
---|
| 97 | if (child.value && child.type !== 'open') {
|
---|
| 98 | queue.push(append(queue.pop(), child.value));
|
---|
| 99 | continue;
|
---|
| 100 | }
|
---|
| 101 |
|
---|
| 102 | if (child.nodes) {
|
---|
| 103 | walk(child, node);
|
---|
| 104 | }
|
---|
| 105 | }
|
---|
| 106 |
|
---|
| 107 | return queue;
|
---|
| 108 | };
|
---|
| 109 |
|
---|
| 110 | return utils.flatten(walk(ast));
|
---|
| 111 | };
|
---|
| 112 |
|
---|
| 113 | module.exports = expand;
|
---|