保誠-保戶業務員媒合平台
HelenHuang
2022-06-09 9bdb95c9e34cef640534e5e5a1e2225a80442000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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;