brace-expansion 2.0.1 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ name: CI
2
+ on: [push]
3
+ jobs:
4
+ build:
5
+ runs-on: ubuntu-latest
6
+ strategy:
7
+ matrix:
8
+ node: ['18', '20']
9
+ steps:
10
+ - uses: actions/checkout@v2
11
+ - uses: actions/setup-node@v2
12
+ with:
13
+ node-version: ${{ matrix.node }}
14
+ - run: npm ci
15
+ - run: npm test
package/README.md CHANGED
@@ -1,18 +1,15 @@
1
1
  # brace-expansion
2
2
 
3
- [Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html),
3
+ [Brace expansion](https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html),
4
4
  as known from sh/bash, in JavaScript.
5
5
 
6
- [![build status](https://secure.travis-ci.org/juliangruber/brace-expansion.svg)](http://travis-ci.org/juliangruber/brace-expansion)
6
+ [![CI](https://github.com/juliangruber/brace-expansion/actions/workflows/ci.yml/badge.svg)](https://github.com/juliangruber/brace-expansion/actions/workflows/ci.yml)
7
7
  [![downloads](https://img.shields.io/npm/dm/brace-expansion.svg)](https://www.npmjs.org/package/brace-expansion)
8
- [![Greenkeeper badge](https://badges.greenkeeper.io/juliangruber/brace-expansion.svg)](https://greenkeeper.io/)
9
-
10
- [![testling badge](https://ci.testling.com/juliangruber/brace-expansion.png)](https://ci.testling.com/juliangruber/brace-expansion)
11
8
 
12
9
  ## Example
13
10
 
14
11
  ```js
15
- var expand = require('brace-expansion');
12
+ import expand from 'brace-expansion'
16
13
 
17
14
  expand('file-{a,b,c}.jpg')
18
15
  // => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
@@ -48,10 +45,10 @@ expand('ppp{,config,oe{,conf}}')
48
45
  ## API
49
46
 
50
47
  ```js
51
- var expand = require('brace-expansion');
48
+ import expand from 'brace-expansion'
52
49
  ```
53
50
 
54
- ### var expanded = expand(str)
51
+ ### const expanded = expand(str)
55
52
 
56
53
  Return an array of all possible and valid expansions of `str`. If none are
57
54
  found, `[str]` is returned.
@@ -97,6 +94,7 @@ npm install brace-expansion
97
94
 
98
95
  - [Julian Gruber](https://github.com/juliangruber)
99
96
  - [Isaac Z. Schlueter](https://github.com/isaacs)
97
+ - [Haelwenn Monnier](https://github.com/lanodan)
100
98
 
101
99
  ## Sponsors
102
100
 
package/bench/bench.js ADDED
@@ -0,0 +1,13 @@
1
+ /* global bench */
2
+
3
+ import expand from '..'
4
+ import fs from 'fs'
5
+
6
+ const resfile = new URL('../test/cases.txt', import.meta.url)
7
+ const cases = fs.readFileSync(resfile, 'utf8').split('\n')
8
+
9
+ bench('Average', function () {
10
+ cases.forEach(function (testcase) {
11
+ expand(testcase)
12
+ })
13
+ })
package/index.js CHANGED
@@ -1,69 +1,76 @@
1
- var balanced = require('balanced-match');
2
-
3
- module.exports = expandTop;
4
-
5
- var escSlash = '\0SLASH'+Math.random()+'\0';
6
- var escOpen = '\0OPEN'+Math.random()+'\0';
7
- var escClose = '\0CLOSE'+Math.random()+'\0';
8
- var escComma = '\0COMMA'+Math.random()+'\0';
9
- var escPeriod = '\0PERIOD'+Math.random()+'\0';
10
-
11
- function numeric(str) {
12
- return parseInt(str, 10) == str
1
+ import balanced from 'balanced-match'
2
+
3
+ const escSlash = '\0SLASH' + Math.random() + '\0'
4
+ const escOpen = '\0OPEN' + Math.random() + '\0'
5
+ const escClose = '\0CLOSE' + Math.random() + '\0'
6
+ const escComma = '\0COMMA' + Math.random() + '\0'
7
+ const escPeriod = '\0PERIOD' + Math.random() + '\0'
8
+
9
+ /**
10
+ * @return {number}
11
+ */
12
+ function numeric (str) {
13
+ return !isNaN(str)
13
14
  ? parseInt(str, 10)
14
- : str.charCodeAt(0);
15
+ : str.charCodeAt(0)
15
16
  }
16
17
 
17
- function escapeBraces(str) {
18
+ /**
19
+ * @param {string} str
20
+ */
21
+ function escapeBraces (str) {
18
22
  return str.split('\\\\').join(escSlash)
19
- .split('\\{').join(escOpen)
20
- .split('\\}').join(escClose)
21
- .split('\\,').join(escComma)
22
- .split('\\.').join(escPeriod);
23
+ .split('\\{').join(escOpen)
24
+ .split('\\}').join(escClose)
25
+ .split('\\,').join(escComma)
26
+ .split('\\.').join(escPeriod)
23
27
  }
24
28
 
25
- function unescapeBraces(str) {
29
+ /**
30
+ * @param {string} str
31
+ */
32
+ function unescapeBraces (str) {
26
33
  return str.split(escSlash).join('\\')
27
- .split(escOpen).join('{')
28
- .split(escClose).join('}')
29
- .split(escComma).join(',')
30
- .split(escPeriod).join('.');
34
+ .split(escOpen).join('{')
35
+ .split(escClose).join('}')
36
+ .split(escComma).join(',')
37
+ .split(escPeriod).join('.')
31
38
  }
32
39
 
40
+ /**
41
+ * Basically just str.split(","), but handling cases
42
+ * where we have nested braced sections, which should be
43
+ * treated as individual members, like {a,{b,c},d}
44
+ * @param {string} str
45
+ */
46
+ function parseCommaParts (str) {
47
+ if (!str) { return [''] }
33
48
 
34
- // Basically just str.split(","), but handling cases
35
- // where we have nested braced sections, which should be
36
- // treated as individual members, like {a,{b,c},d}
37
- function parseCommaParts(str) {
38
- if (!str)
39
- return [''];
40
-
41
- var parts = [];
42
- var m = balanced('{', '}', str);
49
+ const parts = []
50
+ const m = balanced('{', '}', str)
43
51
 
44
- if (!m)
45
- return str.split(',');
52
+ if (!m) { return str.split(',') }
46
53
 
47
- var pre = m.pre;
48
- var body = m.body;
49
- var post = m.post;
50
- var p = pre.split(',');
54
+ const { pre, body, post } = m
55
+ const p = pre.split(',')
51
56
 
52
- p[p.length-1] += '{' + body + '}';
53
- var postParts = parseCommaParts(post);
57
+ p[p.length - 1] += '{' + body + '}'
58
+ const postParts = parseCommaParts(post)
54
59
  if (post.length) {
55
- p[p.length-1] += postParts.shift();
56
- p.push.apply(p, postParts);
60
+ p[p.length - 1] += postParts.shift()
61
+ p.push.apply(p, postParts)
57
62
  }
58
63
 
59
- parts.push.apply(parts, p);
64
+ parts.push.apply(parts, p)
60
65
 
61
- return parts;
66
+ return parts
62
67
  }
63
68
 
64
- function expandTop(str) {
65
- if (!str)
66
- return [];
69
+ /**
70
+ * @param {string} str
71
+ */
72
+ export default function expandTop (str) {
73
+ if (!str) { return [] }
67
74
 
68
75
  // I don't know why Bash 4.3 does this, but it does.
69
76
  // Anything starting with {} will have the first two bytes preserved
@@ -71,133 +78,148 @@ function expandTop(str) {
71
78
  // but a{},b}c will be expanded to [a}c,abc].
72
79
  // One could argue that this is a bug in Bash, but since the goal of
73
80
  // this module is to match Bash's rules, we escape a leading {}
74
- if (str.substr(0, 2) === '{}') {
75
- str = '\\{\\}' + str.substr(2);
81
+ if (str.slice(0, 2) === '{}') {
82
+ str = '\\{\\}' + str.slice(2)
76
83
  }
77
84
 
78
- return expand(escapeBraces(str), true).map(unescapeBraces);
85
+ return expand(escapeBraces(str), true).map(unescapeBraces)
79
86
  }
80
87
 
81
- function embrace(str) {
82
- return '{' + str + '}';
88
+ /**
89
+ * @param {string} str
90
+ */
91
+ function embrace (str) {
92
+ return '{' + str + '}'
83
93
  }
84
- function isPadded(el) {
85
- return /^-?0\d/.test(el);
94
+
95
+ /**
96
+ * @param {string} el
97
+ */
98
+ function isPadded (el) {
99
+ return /^-?0\d/.test(el)
86
100
  }
87
101
 
88
- function lte(i, y) {
89
- return i <= y;
102
+ /**
103
+ * @param {number} i
104
+ * @param {number} y
105
+ */
106
+ function lte (i, y) {
107
+ return i <= y
90
108
  }
91
- function gte(i, y) {
92
- return i >= y;
109
+
110
+ /**
111
+ * @param {number} i
112
+ * @param {number} y
113
+ */
114
+ function gte (i, y) {
115
+ return i >= y
93
116
  }
94
117
 
95
- function expand(str, isTop) {
96
- var expansions = [];
118
+ /**
119
+ * @param {string} str
120
+ * @param {boolean} [isTop]
121
+ */
122
+ function expand (str, isTop) {
123
+ /** @type {string[]} */
124
+ const expansions = []
97
125
 
98
- var m = balanced('{', '}', str);
99
- if (!m) return [str];
126
+ const m = balanced('{', '}', str)
127
+ if (!m) return [str]
100
128
 
101
129
  // no need to expand pre, since it is guaranteed to be free of brace-sets
102
- var pre = m.pre;
103
- var post = m.post.length
130
+ const pre = m.pre
131
+ const post = m.post.length
104
132
  ? expand(m.post, false)
105
- : [''];
133
+ : ['']
106
134
 
107
- if (/\$$/.test(m.pre)) {
108
- for (var k = 0; k < post.length; k++) {
109
- var expansion = pre+ '{' + m.body + '}' + post[k];
110
- expansions.push(expansion);
135
+ if (/\$$/.test(m.pre)) {
136
+ for (let k = 0; k < post.length; k++) {
137
+ const expansion = pre + '{' + m.body + '}' + post[k]
138
+ expansions.push(expansion)
111
139
  }
112
140
  } else {
113
- var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
114
- var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
115
- var isSequence = isNumericSequence || isAlphaSequence;
116
- var isOptions = m.body.indexOf(',') >= 0;
141
+ const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body)
142
+ const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body)
143
+ const isSequence = isNumericSequence || isAlphaSequence
144
+ const isOptions = m.body.indexOf(',') >= 0
117
145
  if (!isSequence && !isOptions) {
118
146
  // {a},b}
119
147
  if (m.post.match(/,.*\}/)) {
120
- str = m.pre + '{' + m.body + escClose + m.post;
121
- return expand(str);
148
+ str = m.pre + '{' + m.body + escClose + m.post
149
+ return expand(str)
122
150
  }
123
- return [str];
151
+ return [str]
124
152
  }
125
153
 
126
- var n;
154
+ let n
127
155
  if (isSequence) {
128
- n = m.body.split(/\.\./);
156
+ n = m.body.split(/\.\./)
129
157
  } else {
130
- n = parseCommaParts(m.body);
158
+ n = parseCommaParts(m.body)
131
159
  if (n.length === 1) {
132
160
  // x{{a,b}}y ==> x{a}y x{b}y
133
- n = expand(n[0], false).map(embrace);
161
+ n = expand(n[0], false).map(embrace)
134
162
  if (n.length === 1) {
135
- return post.map(function(p) {
136
- return m.pre + n[0] + p;
137
- });
163
+ return post.map(function (p) {
164
+ return m.pre + n[0] + p
165
+ })
138
166
  }
139
167
  }
140
168
  }
141
169
 
142
170
  // at this point, n is the parts, and we know it's not a comma set
143
171
  // with a single entry.
144
- var N;
172
+ let N
145
173
 
146
174
  if (isSequence) {
147
- var x = numeric(n[0]);
148
- var y = numeric(n[1]);
149
- var width = Math.max(n[0].length, n[1].length)
150
- var incr = n.length == 3
175
+ const x = numeric(n[0])
176
+ const y = numeric(n[1])
177
+ const width = Math.max(n[0].length, n[1].length)
178
+ let incr = n.length === 3
151
179
  ? Math.abs(numeric(n[2]))
152
- : 1;
153
- var test = lte;
154
- var reverse = y < x;
180
+ : 1
181
+ let test = lte
182
+ const reverse = y < x
155
183
  if (reverse) {
156
- incr *= -1;
157
- test = gte;
184
+ incr *= -1
185
+ test = gte
158
186
  }
159
- var pad = n.some(isPadded);
187
+ const pad = n.some(isPadded)
160
188
 
161
- N = [];
189
+ N = []
162
190
 
163
- for (var i = x; test(i, y); i += incr) {
164
- var c;
191
+ for (let i = x; test(i, y); i += incr) {
192
+ let c
165
193
  if (isAlphaSequence) {
166
- c = String.fromCharCode(i);
167
- if (c === '\\')
168
- c = '';
194
+ c = String.fromCharCode(i)
195
+ if (c === '\\') { c = '' }
169
196
  } else {
170
- c = String(i);
197
+ c = String(i)
171
198
  if (pad) {
172
- var need = width - c.length;
199
+ const need = width - c.length
173
200
  if (need > 0) {
174
- var z = new Array(need + 1).join('0');
175
- if (i < 0)
176
- c = '-' + z + c.slice(1);
177
- else
178
- c = z + c;
201
+ const z = new Array(need + 1).join('0')
202
+ if (i < 0) { c = '-' + z + c.slice(1) } else { c = z + c }
179
203
  }
180
204
  }
181
205
  }
182
- N.push(c);
206
+ N.push(c)
183
207
  }
184
208
  } else {
185
- N = [];
209
+ N = []
186
210
 
187
- for (var j = 0; j < n.length; j++) {
188
- N.push.apply(N, expand(n[j], false));
211
+ for (let j = 0; j < n.length; j++) {
212
+ N.push.apply(N, expand(n[j], false))
189
213
  }
190
214
  }
191
215
 
192
- for (var j = 0; j < N.length; j++) {
193
- for (var k = 0; k < post.length; k++) {
194
- var expansion = pre + N[j] + post[k];
195
- if (!isTop || isSequence || expansion)
196
- expansions.push(expansion);
216
+ for (let j = 0; j < N.length; j++) {
217
+ for (let k = 0; k < post.length; k++) {
218
+ const expansion = pre + N[j] + post[k]
219
+ if (!isTop || isSequence || expansion) { expansions.push(expansion) }
197
220
  }
198
221
  }
199
222
  }
200
223
 
201
- return expansions;
224
+ return expansions
202
225
  }
203
-
package/package.json CHANGED
@@ -1,24 +1,25 @@
1
1
  {
2
2
  "name": "brace-expansion",
3
3
  "description": "Brace expansion as known from sh/bash",
4
- "version": "2.0.1",
4
+ "version": "3.0.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "git://github.com/juliangruber/brace-expansion.git"
8
8
  },
9
9
  "homepage": "https://github.com/juliangruber/brace-expansion",
10
- "main": "index.js",
10
+ "exports": "./index.js",
11
+ "type": "module",
11
12
  "scripts": {
12
- "test": "tape test/*.js",
13
+ "test": "standard --fix && node --test",
13
14
  "gentest": "bash test/generate.sh",
14
- "bench": "matcha test/perf/bench.js"
15
+ "bench": "matcha bench/bench.js"
15
16
  },
16
17
  "dependencies": {
17
- "balanced-match": "^1.0.0"
18
+ "balanced-match": "^3.0.0"
18
19
  },
19
20
  "devDependencies": {
20
21
  "@c4312/matcha": "^1.3.1",
21
- "tape": "^4.6.0"
22
+ "standard": "^17.1.0"
22
23
  },
23
24
  "keywords": [],
24
25
  "author": {
@@ -42,5 +43,8 @@
42
43
  "iphone/6.0..latest",
43
44
  "android-browser/4.2..latest"
44
45
  ]
46
+ },
47
+ "engines": {
48
+ "node": ">= 18"
45
49
  }
46
50
  }