.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / fast-glob / node_modules / braces / lib / utils.js
1 'use strict';
2
3 var splitString = require('split-string');
4 var utils = module.exports;
5
6 /**
7  * Module dependencies
8  */
9
10 utils.extend = require('extend-shallow');
11 utils.flatten = require('arr-flatten');
12 utils.isObject = require('isobject');
13 utils.fillRange = require('fill-range');
14 utils.repeat = require('repeat-element');
15 utils.unique = require('array-unique');
16
17 utils.define = function(obj, key, val) {
18   Object.defineProperty(obj, key, {
19     writable: true,
20     configurable: true,
21     enumerable: false,
22     value: val
23   });
24 };
25
26 /**
27  * Returns true if the given string contains only empty brace sets.
28  */
29
30 utils.isEmptySets = function(str) {
31   return /^(?:\{,\})+$/.test(str);
32 };
33
34 /**
35  * Returns true if the given string contains only empty brace sets.
36  */
37
38 utils.isQuotedString = function(str) {
39   var open = str.charAt(0);
40   if (open === '\'' || open === '"' || open === '`') {
41     return str.slice(-1) === open;
42   }
43   return false;
44 };
45
46 /**
47  * Create the key to use for memoization. The unique key is generated
48  * by iterating over the options and concatenating key-value pairs
49  * to the pattern string.
50  */
51
52 utils.createKey = function(pattern, options) {
53   var id = pattern;
54   if (typeof options === 'undefined') {
55     return id;
56   }
57   var keys = Object.keys(options);
58   for (var i = 0; i < keys.length; i++) {
59     var key = keys[i];
60     id += ';' + key + '=' + String(options[key]);
61   }
62   return id;
63 };
64
65 /**
66  * Normalize options
67  */
68
69 utils.createOptions = function(options) {
70   var opts = utils.extend.apply(null, arguments);
71   if (typeof opts.expand === 'boolean') {
72     opts.optimize = !opts.expand;
73   }
74   if (typeof opts.optimize === 'boolean') {
75     opts.expand = !opts.optimize;
76   }
77   if (opts.optimize === true) {
78     opts.makeRe = true;
79   }
80   return opts;
81 };
82
83 /**
84  * Join patterns in `a` to patterns in `b`
85  */
86
87 utils.join = function(a, b, options) {
88   options = options || {};
89   a = utils.arrayify(a);
90   b = utils.arrayify(b);
91
92   if (!a.length) return b;
93   if (!b.length) return a;
94
95   var len = a.length;
96   var idx = -1;
97   var arr = [];
98
99   while (++idx < len) {
100     var val = a[idx];
101     if (Array.isArray(val)) {
102       for (var i = 0; i < val.length; i++) {
103         val[i] = utils.join(val[i], b, options);
104       }
105       arr.push(val);
106       continue;
107     }
108
109     for (var j = 0; j < b.length; j++) {
110       var bval = b[j];
111
112       if (Array.isArray(bval)) {
113         arr.push(utils.join(val, bval, options));
114       } else {
115         arr.push(val + bval);
116       }
117     }
118   }
119   return arr;
120 };
121
122 /**
123  * Split the given string on `,` if not escaped.
124  */
125
126 utils.split = function(str, options) {
127   var opts = utils.extend({sep: ','}, options);
128   if (typeof opts.keepQuotes !== 'boolean') {
129     opts.keepQuotes = true;
130   }
131   if (opts.unescape === false) {
132     opts.keepEscaping = true;
133   }
134   return splitString(str, opts, utils.escapeBrackets(opts));
135 };
136
137 /**
138  * Expand ranges or sets in the given `pattern`.
139  *
140  * @param {String} `str`
141  * @param {Object} `options`
142  * @return {Object}
143  */
144
145 utils.expand = function(str, options) {
146   var opts = utils.extend({rangeLimit: 10000}, options);
147   var segs = utils.split(str, opts);
148   var tok = { segs: segs };
149
150   if (utils.isQuotedString(str)) {
151     return tok;
152   }
153
154   if (opts.rangeLimit === true) {
155     opts.rangeLimit = 10000;
156   }
157
158   if (segs.length > 1) {
159     if (opts.optimize === false) {
160       tok.val = segs[0];
161       return tok;
162     }
163
164     tok.segs = utils.stringifyArray(tok.segs);
165   } else if (segs.length === 1) {
166     var arr = str.split('..');
167
168     if (arr.length === 1) {
169       tok.val = tok.segs[tok.segs.length - 1] || tok.val || str;
170       tok.segs = [];
171       return tok;
172     }
173
174     if (arr.length === 2 && arr[0] === arr[1]) {
175       tok.escaped = true;
176       tok.val = arr[0];
177       tok.segs = [];
178       return tok;
179     }
180
181     if (arr.length > 1) {
182       if (opts.optimize !== false) {
183         opts.optimize = true;
184         delete opts.expand;
185       }
186
187       if (opts.optimize !== true) {
188         var min = Math.min(arr[0], arr[1]);
189         var max = Math.max(arr[0], arr[1]);
190         var step = arr[2] || 1;
191
192         if (opts.rangeLimit !== false && ((max - min) / step >= opts.rangeLimit)) {
193           throw new RangeError('expanded array length exceeds range limit. Use options.rangeLimit to increase or disable the limit.');
194         }
195       }
196
197       arr.push(opts);
198       tok.segs = utils.fillRange.apply(null, arr);
199
200       if (!tok.segs.length) {
201         tok.escaped = true;
202         tok.val = str;
203         return tok;
204       }
205
206       if (opts.optimize === true) {
207         tok.segs = utils.stringifyArray(tok.segs);
208       }
209
210       if (tok.segs === '') {
211         tok.val = str;
212       } else {
213         tok.val = tok.segs[0];
214       }
215       return tok;
216     }
217   } else {
218     tok.val = str;
219   }
220   return tok;
221 };
222
223 /**
224  * Ensure commas inside brackets and parens are not split.
225  * @param {Object} `tok` Token from the `split-string` module
226  * @return {undefined}
227  */
228
229 utils.escapeBrackets = function(options) {
230   return function(tok) {
231     if (tok.escaped && tok.val === 'b') {
232       tok.val = '\\b';
233       return;
234     }
235
236     if (tok.val !== '(' && tok.val !== '[') return;
237     var opts = utils.extend({}, options);
238     var brackets = [];
239     var parens = [];
240     var stack = [];
241     var val = tok.val;
242     var str = tok.str;
243     var i = tok.idx - 1;
244
245     while (++i < str.length) {
246       var ch = str[i];
247
248       if (ch === '\\') {
249         val += (opts.keepEscaping === false ? '' : ch) + str[++i];
250         continue;
251       }
252
253       if (ch === '(') {
254         parens.push(ch);
255         stack.push(ch);
256       }
257
258       if (ch === '[') {
259         brackets.push(ch);
260         stack.push(ch);
261       }
262
263       if (ch === ')') {
264         parens.pop();
265         stack.pop();
266         if (!stack.length) {
267           val += ch;
268           break;
269         }
270       }
271
272       if (ch === ']') {
273         brackets.pop();
274         stack.pop();
275         if (!stack.length) {
276           val += ch;
277           break;
278         }
279       }
280       val += ch;
281     }
282
283     tok.split = false;
284     tok.val = val.slice(1);
285     tok.idx = i;
286   };
287 };
288
289 /**
290  * Returns true if the given string looks like a regex quantifier
291  * @return {Boolean}
292  */
293
294 utils.isQuantifier = function(str) {
295   return /^(?:[0-9]?,[0-9]|[0-9],)$/.test(str);
296 };
297
298 /**
299  * Cast `val` to an array.
300  * @param {*} `val`
301  */
302
303 utils.stringifyArray = function(arr) {
304   return [utils.arrayify(arr).join('|')];
305 };
306
307 /**
308  * Cast `val` to an array.
309  * @param {*} `val`
310  */
311
312 utils.arrayify = function(arr) {
313   if (typeof arr === 'undefined') {
314     return [];
315   }
316   if (typeof arr === 'string') {
317     return [arr];
318   }
319   return arr;
320 };
321
322 /**
323  * Returns true if the given `str` is a non-empty string
324  * @return {Boolean}
325  */
326
327 utils.isString = function(str) {
328   return str != null && typeof str === 'string';
329 };
330
331 /**
332  * Get the last element from `array`
333  * @param {Array} `array`
334  * @return {*}
335  */
336
337 utils.last = function(arr, n) {
338   return arr[arr.length - (n || 1)];
339 };
340
341 utils.escapeRegex = function(str) {
342   return str.replace(/\\?([!^*?()[\]{}+?/])/g, '\\$1');
343 };