brace-expansion 4.0.1 → 5.0.3

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.
package/LICENSE CHANGED
@@ -1,6 +1,8 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2013 Julian Gruber <julian@juliangruber.com>
3
+ Copyright Julian Gruber <julian@juliangruber.com>
4
+
5
+ TypeScript port Copyright Isaac Z. Schlueter <i@izs.me>
4
6
 
5
7
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
8
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -9,7 +9,7 @@ as known from sh/bash, in JavaScript.
9
9
  ## Example
10
10
 
11
11
  ```js
12
- import expand from 'brace-expansion'
12
+ import { expand } from 'brace-expansion'
13
13
 
14
14
  expand('file-{a,b,c}.jpg')
15
15
  // => ['file-a.jpg', 'file-b.jpg', 'file-c.jpg']
@@ -45,25 +45,36 @@ expand('ppp{,config,oe{,conf}}')
45
45
  ## API
46
46
 
47
47
  ```js
48
- import expand from 'brace-expansion'
48
+ import { expand } from '@isaacs/brace-expansion'
49
49
  ```
50
50
 
51
- ### const expanded = expand(str)
51
+ ### const expanded = expand(str, [options])
52
52
 
53
- Return an array of all possible and valid expansions of `str`. If none are
54
- found, `[str]` is returned.
53
+ Return an array of all possible and valid expansions of `str`. If
54
+ none are found, `[str]` is returned.
55
+
56
+ The `options` object can provide a `max` value to cap the number
57
+ of expansions allowed. This is limited to `100_000` by default,
58
+ to prevent DoS attacks.
59
+
60
+ ```js
61
+ const expansions = expand('{1..100}'.repeat(5), {
62
+ max: 100,
63
+ })
64
+ // expansions.length will be 100, not 100^5
65
+ ```
55
66
 
56
67
  Valid expansions are:
57
68
 
58
69
  ```js
59
- /^(.*,)+(.+)?$/
70
+ ;/^(.*,)+(.+)?$/
60
71
  // {a,b,...}
61
72
  ```
62
73
 
63
74
  A comma separated list of options, like `{a,b}` or `{a,{b,c}}` or `{,a,}`.
64
75
 
65
76
  ```js
66
- /^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
77
+ ;/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
67
78
  // {x..y[..incr]}
68
79
  ```
69
80
 
@@ -72,7 +83,7 @@ If `x` or `y` start with a leading `0`, all the numbers will be padded
72
83
  to have equal length. Negative numbers and backwards iteration work too.
73
84
 
74
85
  ```js
75
- /^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
86
+ ;/^-?\d+\.\.-?\d+(\.\.-?\d+)?$/
76
87
  // {x..y[..incr]}
77
88
  ```
78
89
 
@@ -81,53 +92,3 @@ An alphabetic sequence from `x` to `y` inclusive, with optional increment.
81
92
  number.
82
93
 
83
94
  For compatibility reasons, the string `${` is not eligible for brace expansion.
84
-
85
- ## Installation
86
-
87
- With [npm](https://npmjs.org) do:
88
-
89
- ```bash
90
- npm install brace-expansion
91
- ```
92
-
93
- ## Contributors
94
-
95
- - [Julian Gruber](https://github.com/juliangruber)
96
- - [Isaac Z. Schlueter](https://github.com/isaacs)
97
- - [Haelwenn Monnier](https://github.com/lanodan)
98
-
99
- ## Sponsors
100
-
101
- This module is proudly supported by my [Sponsors](https://github.com/juliangruber/sponsors)!
102
-
103
- Do you want to support modules like this to improve their quality, stability and weigh in on new features? Then please consider donating to my [Patreon](https://www.patreon.com/juliangruber). Not sure how much of my modules you're using? Try [feross/thanks](https://github.com/feross/thanks)!
104
-
105
- ## Security contact information
106
-
107
- To report a security vulnerability, please use the
108
- [Tidelift security contact](https://tidelift.com/security).
109
- Tidelift will coordinate the fix and disclosure.
110
-
111
- ## License
112
-
113
- (MIT)
114
-
115
- Copyright (c) 2013 Julian Gruber &lt;julian@juliangruber.com&gt;
116
-
117
- Permission is hereby granted, free of charge, to any person obtaining a copy of
118
- this software and associated documentation files (the "Software"), to deal in
119
- the Software without restriction, including without limitation the rights to
120
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
121
- of the Software, and to permit persons to whom the Software is furnished to do
122
- so, subject to the following conditions:
123
-
124
- The above copyright notice and this permission notice shall be included in all
125
- copies or substantial portions of the Software.
126
-
127
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
128
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
129
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
130
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
131
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
132
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
133
- SOFTWARE.
@@ -0,0 +1,6 @@
1
+ export declare const EXPANSION_MAX = 100000;
2
+ export type BraceExpansionOptions = {
3
+ max?: number;
4
+ };
5
+ export declare function expand(str: string, options?: BraceExpansionOptions): string[];
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,aAAa,SAAU,CAAA;AAwDpC,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,YAkBtE"}
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EXPANSION_MAX = void 0;
4
+ exports.expand = expand;
5
+ const balanced_match_1 = require("balanced-match");
6
+ const escSlash = '\0SLASH' + Math.random() + '\0';
7
+ const escOpen = '\0OPEN' + Math.random() + '\0';
8
+ const escClose = '\0CLOSE' + Math.random() + '\0';
9
+ const escComma = '\0COMMA' + Math.random() + '\0';
10
+ const escPeriod = '\0PERIOD' + Math.random() + '\0';
11
+ const escSlashPattern = new RegExp(escSlash, 'g');
12
+ const escOpenPattern = new RegExp(escOpen, 'g');
13
+ const escClosePattern = new RegExp(escClose, 'g');
14
+ const escCommaPattern = new RegExp(escComma, 'g');
15
+ const escPeriodPattern = new RegExp(escPeriod, 'g');
16
+ const slashPattern = /\\\\/g;
17
+ const openPattern = /\\{/g;
18
+ const closePattern = /\\}/g;
19
+ const commaPattern = /\\,/g;
20
+ const periodPattern = /\\./g;
21
+ exports.EXPANSION_MAX = 100_000;
22
+ function numeric(str) {
23
+ return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
24
+ }
25
+ function escapeBraces(str) {
26
+ return str
27
+ .replace(slashPattern, escSlash)
28
+ .replace(openPattern, escOpen)
29
+ .replace(closePattern, escClose)
30
+ .replace(commaPattern, escComma)
31
+ .replace(periodPattern, escPeriod);
32
+ }
33
+ function unescapeBraces(str) {
34
+ return str
35
+ .replace(escSlashPattern, '\\')
36
+ .replace(escOpenPattern, '{')
37
+ .replace(escClosePattern, '}')
38
+ .replace(escCommaPattern, ',')
39
+ .replace(escPeriodPattern, '.');
40
+ }
41
+ /**
42
+ * Basically just str.split(","), but handling cases
43
+ * where we have nested braced sections, which should be
44
+ * treated as individual members, like {a,{b,c},d}
45
+ */
46
+ function parseCommaParts(str) {
47
+ if (!str) {
48
+ return [''];
49
+ }
50
+ const parts = [];
51
+ const m = (0, balanced_match_1.balanced)('{', '}', str);
52
+ if (!m) {
53
+ return str.split(',');
54
+ }
55
+ const { pre, body, post } = m;
56
+ const p = pre.split(',');
57
+ p[p.length - 1] += '{' + body + '}';
58
+ const postParts = parseCommaParts(post);
59
+ if (post.length) {
60
+ ;
61
+ p[p.length - 1] += postParts.shift();
62
+ p.push.apply(p, postParts);
63
+ }
64
+ parts.push.apply(parts, p);
65
+ return parts;
66
+ }
67
+ function expand(str, options = {}) {
68
+ if (!str) {
69
+ return [];
70
+ }
71
+ const { max = exports.EXPANSION_MAX } = options;
72
+ // I don't know why Bash 4.3 does this, but it does.
73
+ // Anything starting with {} will have the first two bytes preserved
74
+ // but *only* at the top level, so {},a}b will not expand to anything,
75
+ // but a{},b}c will be expanded to [a}c,abc].
76
+ // One could argue that this is a bug in Bash, but since the goal of
77
+ // this module is to match Bash's rules, we escape a leading {}
78
+ if (str.slice(0, 2) === '{}') {
79
+ str = '\\{\\}' + str.slice(2);
80
+ }
81
+ return expand_(escapeBraces(str), max, true).map(unescapeBraces);
82
+ }
83
+ function embrace(str) {
84
+ return '{' + str + '}';
85
+ }
86
+ function isPadded(el) {
87
+ return /^-?0\d/.test(el);
88
+ }
89
+ function lte(i, y) {
90
+ return i <= y;
91
+ }
92
+ function gte(i, y) {
93
+ return i >= y;
94
+ }
95
+ function expand_(str, max, isTop) {
96
+ /** @type {string[]} */
97
+ const expansions = [];
98
+ const m = (0, balanced_match_1.balanced)('{', '}', str);
99
+ if (!m)
100
+ return [str];
101
+ // no need to expand pre, since it is guaranteed to be free of brace-sets
102
+ const pre = m.pre;
103
+ const post = m.post.length ? expand_(m.post, max, false) : [''];
104
+ if (/\$$/.test(m.pre)) {
105
+ for (let k = 0; k < post.length && k < max; k++) {
106
+ const expansion = pre + '{' + m.body + '}' + post[k];
107
+ expansions.push(expansion);
108
+ }
109
+ }
110
+ else {
111
+ const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
112
+ const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
113
+ const isSequence = isNumericSequence || isAlphaSequence;
114
+ const isOptions = m.body.indexOf(',') >= 0;
115
+ if (!isSequence && !isOptions) {
116
+ // {a},b}
117
+ if (m.post.match(/,(?!,).*\}/)) {
118
+ str = m.pre + '{' + m.body + escClose + m.post;
119
+ return expand_(str, max, true);
120
+ }
121
+ return [str];
122
+ }
123
+ let n;
124
+ if (isSequence) {
125
+ n = m.body.split(/\.\./);
126
+ }
127
+ else {
128
+ n = parseCommaParts(m.body);
129
+ if (n.length === 1 && n[0] !== undefined) {
130
+ // x{{a,b}}y ==> x{a}y x{b}y
131
+ n = expand_(n[0], max, false).map(embrace);
132
+ //XXX is this necessary? Can't seem to hit it in tests.
133
+ /* c8 ignore start */
134
+ if (n.length === 1) {
135
+ return post.map(p => m.pre + n[0] + p);
136
+ }
137
+ /* c8 ignore stop */
138
+ }
139
+ }
140
+ // at this point, n is the parts, and we know it's not a comma set
141
+ // with a single entry.
142
+ let N;
143
+ if (isSequence && n[0] !== undefined && n[1] !== undefined) {
144
+ const x = numeric(n[0]);
145
+ const y = numeric(n[1]);
146
+ const width = Math.max(n[0].length, n[1].length);
147
+ let incr = n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1;
148
+ let test = lte;
149
+ const reverse = y < x;
150
+ if (reverse) {
151
+ incr *= -1;
152
+ test = gte;
153
+ }
154
+ const pad = n.some(isPadded);
155
+ N = [];
156
+ for (let i = x; test(i, y); i += incr) {
157
+ let c;
158
+ if (isAlphaSequence) {
159
+ c = String.fromCharCode(i);
160
+ if (c === '\\') {
161
+ c = '';
162
+ }
163
+ }
164
+ else {
165
+ c = String(i);
166
+ if (pad) {
167
+ const need = width - c.length;
168
+ if (need > 0) {
169
+ const z = new Array(need + 1).join('0');
170
+ if (i < 0) {
171
+ c = '-' + z + c.slice(1);
172
+ }
173
+ else {
174
+ c = z + c;
175
+ }
176
+ }
177
+ }
178
+ }
179
+ N.push(c);
180
+ }
181
+ }
182
+ else {
183
+ N = [];
184
+ for (let j = 0; j < n.length; j++) {
185
+ N.push.apply(N, expand_(n[j], max, false));
186
+ }
187
+ }
188
+ for (let j = 0; j < N.length; j++) {
189
+ for (let k = 0; k < post.length && expansions.length < max; k++) {
190
+ const expansion = pre + N[j] + post[k];
191
+ if (!isTop || isSequence || expansion) {
192
+ expansions.push(expansion);
193
+ }
194
+ }
195
+ }
196
+ }
197
+ return expansions;
198
+ }
199
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { balanced } from 'balanced-match'\n\nconst escSlash = '\\0SLASH' + Math.random() + '\\0'\nconst escOpen = '\\0OPEN' + Math.random() + '\\0'\nconst escClose = '\\0CLOSE' + Math.random() + '\\0'\nconst escComma = '\\0COMMA' + Math.random() + '\\0'\nconst escPeriod = '\\0PERIOD' + Math.random() + '\\0'\nconst escSlashPattern = new RegExp(escSlash, 'g')\nconst escOpenPattern = new RegExp(escOpen, 'g')\nconst escClosePattern = new RegExp(escClose, 'g')\nconst escCommaPattern = new RegExp(escComma, 'g')\nconst escPeriodPattern = new RegExp(escPeriod, 'g')\nconst slashPattern = /\\\\\\\\/g\nconst openPattern = /\\\\{/g\nconst closePattern = /\\\\}/g\nconst commaPattern = /\\\\,/g\nconst periodPattern = /\\\\./g\n\nexport const EXPANSION_MAX = 100_000\n\nfunction numeric(str: string) {\n return !isNaN(str as any) ? parseInt(str, 10) : str.charCodeAt(0)\n}\n\nfunction escapeBraces(str: string) {\n return str\n .replace(slashPattern, escSlash)\n .replace(openPattern, escOpen)\n .replace(closePattern, escClose)\n .replace(commaPattern, escComma)\n .replace(periodPattern, escPeriod)\n}\n\nfunction unescapeBraces(str: string) {\n return str\n .replace(escSlashPattern, '\\\\')\n .replace(escOpenPattern, '{')\n .replace(escClosePattern, '}')\n .replace(escCommaPattern, ',')\n .replace(escPeriodPattern, '.')\n}\n\n/**\n * Basically just str.split(\",\"), but handling cases\n * where we have nested braced sections, which should be\n * treated as individual members, like {a,{b,c},d}\n */\nfunction parseCommaParts(str: string) {\n if (!str) {\n return ['']\n }\n\n const parts: string[] = []\n const m = balanced('{', '}', str)\n\n if (!m) {\n return str.split(',')\n }\n\n const { pre, body, post } = m\n const p = pre.split(',')\n\n p[p.length - 1] += '{' + body + '}'\n const postParts = parseCommaParts(post)\n if (post.length) {\n ;(p[p.length - 1] as string) += postParts.shift()\n p.push.apply(p, postParts)\n }\n\n parts.push.apply(parts, p)\n\n return parts\n}\n\nexport type BraceExpansionOptions = {\n max?: number\n}\n\nexport function expand(str: string, options: BraceExpansionOptions = {}) {\n if (!str) {\n return []\n }\n\n const { max = EXPANSION_MAX } = options\n\n // I don't know why Bash 4.3 does this, but it does.\n // Anything starting with {} will have the first two bytes preserved\n // but *only* at the top level, so {},a}b will not expand to anything,\n // but a{},b}c will be expanded to [a}c,abc].\n // One could argue that this is a bug in Bash, but since the goal of\n // this module is to match Bash's rules, we escape a leading {}\n if (str.slice(0, 2) === '{}') {\n str = '\\\\{\\\\}' + str.slice(2)\n }\n\n return expand_(escapeBraces(str), max, true).map(unescapeBraces)\n}\n\nfunction embrace(str: string) {\n return '{' + str + '}'\n}\n\nfunction isPadded(el: string) {\n return /^-?0\\d/.test(el)\n}\n\nfunction lte(i: number, y: number) {\n return i <= y\n}\n\nfunction gte(i: number, y: number) {\n return i >= y\n}\n\nfunction expand_(str: string, max: number, isTop: boolean): string[] {\n /** @type {string[]} */\n const expansions: string[] = []\n\n const m = balanced('{', '}', str)\n if (!m) return [str]\n\n // no need to expand pre, since it is guaranteed to be free of brace-sets\n const pre = m.pre\n const post: string[] = m.post.length ? expand_(m.post, max, false) : ['']\n\n if (/\\$$/.test(m.pre)) {\n for (let k = 0; k < post.length && k < max; k++) {\n const expansion = pre + '{' + m.body + '}' + post[k]\n expansions.push(expansion)\n }\n } else {\n const isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body)\n const isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(\n m.body,\n )\n const isSequence = isNumericSequence || isAlphaSequence\n const isOptions = m.body.indexOf(',') >= 0\n if (!isSequence && !isOptions) {\n // {a},b}\n if (m.post.match(/,(?!,).*\\}/)) {\n str = m.pre + '{' + m.body + escClose + m.post\n return expand_(str, max, true)\n }\n return [str]\n }\n\n let n: string[]\n if (isSequence) {\n n = m.body.split(/\\.\\./)\n } else {\n n = parseCommaParts(m.body)\n if (n.length === 1 && n[0] !== undefined) {\n // x{{a,b}}y ==> x{a}y x{b}y\n n = expand_(n[0], max, false).map(embrace)\n //XXX is this necessary? Can't seem to hit it in tests.\n /* c8 ignore start */\n if (n.length === 1) {\n return post.map(p => m.pre + n[0] + p)\n }\n /* c8 ignore stop */\n }\n }\n\n // at this point, n is the parts, and we know it's not a comma set\n // with a single entry.\n let N: string[]\n\n if (isSequence && n[0] !== undefined && n[1] !== undefined) {\n const x = numeric(n[0])\n const y = numeric(n[1])\n const width = Math.max(n[0].length, n[1].length)\n let incr =\n n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1\n let test = lte\n const reverse = y < x\n if (reverse) {\n incr *= -1\n test = gte\n }\n const pad = n.some(isPadded)\n\n N = []\n\n for (let i = x; test(i, y); i += incr) {\n let c\n if (isAlphaSequence) {\n c = String.fromCharCode(i)\n if (c === '\\\\') {\n c = ''\n }\n } else {\n c = String(i)\n if (pad) {\n const need = width - c.length\n if (need > 0) {\n const z = new Array(need + 1).join('0')\n if (i < 0) {\n c = '-' + z + c.slice(1)\n } else {\n c = z + c\n }\n }\n }\n }\n N.push(c)\n }\n } else {\n N = []\n\n for (let j = 0; j < n.length; j++) {\n N.push.apply(N, expand_(n[j] as string, max, false))\n }\n }\n\n for (let j = 0; j < N.length; j++) {\n for (let k = 0; k < post.length && expansions.length < max; k++) {\n const expansion = pre + N[j] + post[k]\n if (!isTop || isSequence || expansion) {\n expansions.push(expansion)\n }\n }\n }\n }\n\n return expansions\n}\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,6 @@
1
+ export declare const EXPANSION_MAX = 100000;
2
+ export type BraceExpansionOptions = {
3
+ max?: number;
4
+ };
5
+ export declare function expand(str: string, options?: BraceExpansionOptions): string[];
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAkBA,eAAO,MAAM,aAAa,SAAU,CAAA;AAwDpC,MAAM,MAAM,qBAAqB,GAAG;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,YAkBtE"}
@@ -0,0 +1,195 @@
1
+ import { balanced } from 'balanced-match';
2
+ const escSlash = '\0SLASH' + Math.random() + '\0';
3
+ const escOpen = '\0OPEN' + Math.random() + '\0';
4
+ const escClose = '\0CLOSE' + Math.random() + '\0';
5
+ const escComma = '\0COMMA' + Math.random() + '\0';
6
+ const escPeriod = '\0PERIOD' + Math.random() + '\0';
7
+ const escSlashPattern = new RegExp(escSlash, 'g');
8
+ const escOpenPattern = new RegExp(escOpen, 'g');
9
+ const escClosePattern = new RegExp(escClose, 'g');
10
+ const escCommaPattern = new RegExp(escComma, 'g');
11
+ const escPeriodPattern = new RegExp(escPeriod, 'g');
12
+ const slashPattern = /\\\\/g;
13
+ const openPattern = /\\{/g;
14
+ const closePattern = /\\}/g;
15
+ const commaPattern = /\\,/g;
16
+ const periodPattern = /\\./g;
17
+ export const EXPANSION_MAX = 100_000;
18
+ function numeric(str) {
19
+ return !isNaN(str) ? parseInt(str, 10) : str.charCodeAt(0);
20
+ }
21
+ function escapeBraces(str) {
22
+ return str
23
+ .replace(slashPattern, escSlash)
24
+ .replace(openPattern, escOpen)
25
+ .replace(closePattern, escClose)
26
+ .replace(commaPattern, escComma)
27
+ .replace(periodPattern, escPeriod);
28
+ }
29
+ function unescapeBraces(str) {
30
+ return str
31
+ .replace(escSlashPattern, '\\')
32
+ .replace(escOpenPattern, '{')
33
+ .replace(escClosePattern, '}')
34
+ .replace(escCommaPattern, ',')
35
+ .replace(escPeriodPattern, '.');
36
+ }
37
+ /**
38
+ * Basically just str.split(","), but handling cases
39
+ * where we have nested braced sections, which should be
40
+ * treated as individual members, like {a,{b,c},d}
41
+ */
42
+ function parseCommaParts(str) {
43
+ if (!str) {
44
+ return [''];
45
+ }
46
+ const parts = [];
47
+ const m = balanced('{', '}', str);
48
+ if (!m) {
49
+ return str.split(',');
50
+ }
51
+ const { pre, body, post } = m;
52
+ const p = pre.split(',');
53
+ p[p.length - 1] += '{' + body + '}';
54
+ const postParts = parseCommaParts(post);
55
+ if (post.length) {
56
+ ;
57
+ p[p.length - 1] += postParts.shift();
58
+ p.push.apply(p, postParts);
59
+ }
60
+ parts.push.apply(parts, p);
61
+ return parts;
62
+ }
63
+ export function expand(str, options = {}) {
64
+ if (!str) {
65
+ return [];
66
+ }
67
+ const { max = EXPANSION_MAX } = options;
68
+ // I don't know why Bash 4.3 does this, but it does.
69
+ // Anything starting with {} will have the first two bytes preserved
70
+ // but *only* at the top level, so {},a}b will not expand to anything,
71
+ // but a{},b}c will be expanded to [a}c,abc].
72
+ // One could argue that this is a bug in Bash, but since the goal of
73
+ // this module is to match Bash's rules, we escape a leading {}
74
+ if (str.slice(0, 2) === '{}') {
75
+ str = '\\{\\}' + str.slice(2);
76
+ }
77
+ return expand_(escapeBraces(str), max, true).map(unescapeBraces);
78
+ }
79
+ function embrace(str) {
80
+ return '{' + str + '}';
81
+ }
82
+ function isPadded(el) {
83
+ return /^-?0\d/.test(el);
84
+ }
85
+ function lte(i, y) {
86
+ return i <= y;
87
+ }
88
+ function gte(i, y) {
89
+ return i >= y;
90
+ }
91
+ function expand_(str, max, isTop) {
92
+ /** @type {string[]} */
93
+ const expansions = [];
94
+ const m = balanced('{', '}', str);
95
+ if (!m)
96
+ return [str];
97
+ // no need to expand pre, since it is guaranteed to be free of brace-sets
98
+ const pre = m.pre;
99
+ const post = m.post.length ? expand_(m.post, max, false) : [''];
100
+ if (/\$$/.test(m.pre)) {
101
+ for (let k = 0; k < post.length && k < max; k++) {
102
+ const expansion = pre + '{' + m.body + '}' + post[k];
103
+ expansions.push(expansion);
104
+ }
105
+ }
106
+ else {
107
+ const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
108
+ const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
109
+ const isSequence = isNumericSequence || isAlphaSequence;
110
+ const isOptions = m.body.indexOf(',') >= 0;
111
+ if (!isSequence && !isOptions) {
112
+ // {a},b}
113
+ if (m.post.match(/,(?!,).*\}/)) {
114
+ str = m.pre + '{' + m.body + escClose + m.post;
115
+ return expand_(str, max, true);
116
+ }
117
+ return [str];
118
+ }
119
+ let n;
120
+ if (isSequence) {
121
+ n = m.body.split(/\.\./);
122
+ }
123
+ else {
124
+ n = parseCommaParts(m.body);
125
+ if (n.length === 1 && n[0] !== undefined) {
126
+ // x{{a,b}}y ==> x{a}y x{b}y
127
+ n = expand_(n[0], max, false).map(embrace);
128
+ //XXX is this necessary? Can't seem to hit it in tests.
129
+ /* c8 ignore start */
130
+ if (n.length === 1) {
131
+ return post.map(p => m.pre + n[0] + p);
132
+ }
133
+ /* c8 ignore stop */
134
+ }
135
+ }
136
+ // at this point, n is the parts, and we know it's not a comma set
137
+ // with a single entry.
138
+ let N;
139
+ if (isSequence && n[0] !== undefined && n[1] !== undefined) {
140
+ const x = numeric(n[0]);
141
+ const y = numeric(n[1]);
142
+ const width = Math.max(n[0].length, n[1].length);
143
+ let incr = n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1;
144
+ let test = lte;
145
+ const reverse = y < x;
146
+ if (reverse) {
147
+ incr *= -1;
148
+ test = gte;
149
+ }
150
+ const pad = n.some(isPadded);
151
+ N = [];
152
+ for (let i = x; test(i, y); i += incr) {
153
+ let c;
154
+ if (isAlphaSequence) {
155
+ c = String.fromCharCode(i);
156
+ if (c === '\\') {
157
+ c = '';
158
+ }
159
+ }
160
+ else {
161
+ c = String(i);
162
+ if (pad) {
163
+ const need = width - c.length;
164
+ if (need > 0) {
165
+ const z = new Array(need + 1).join('0');
166
+ if (i < 0) {
167
+ c = '-' + z + c.slice(1);
168
+ }
169
+ else {
170
+ c = z + c;
171
+ }
172
+ }
173
+ }
174
+ }
175
+ N.push(c);
176
+ }
177
+ }
178
+ else {
179
+ N = [];
180
+ for (let j = 0; j < n.length; j++) {
181
+ N.push.apply(N, expand_(n[j], max, false));
182
+ }
183
+ }
184
+ for (let j = 0; j < N.length; j++) {
185
+ for (let k = 0; k < post.length && expansions.length < max; k++) {
186
+ const expansion = pre + N[j] + post[k];
187
+ if (!isTop || isSequence || expansion) {
188
+ expansions.push(expansion);
189
+ }
190
+ }
191
+ }
192
+ }
193
+ return expansions;
194
+ }
195
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { balanced } from 'balanced-match'\n\nconst escSlash = '\\0SLASH' + Math.random() + '\\0'\nconst escOpen = '\\0OPEN' + Math.random() + '\\0'\nconst escClose = '\\0CLOSE' + Math.random() + '\\0'\nconst escComma = '\\0COMMA' + Math.random() + '\\0'\nconst escPeriod = '\\0PERIOD' + Math.random() + '\\0'\nconst escSlashPattern = new RegExp(escSlash, 'g')\nconst escOpenPattern = new RegExp(escOpen, 'g')\nconst escClosePattern = new RegExp(escClose, 'g')\nconst escCommaPattern = new RegExp(escComma, 'g')\nconst escPeriodPattern = new RegExp(escPeriod, 'g')\nconst slashPattern = /\\\\\\\\/g\nconst openPattern = /\\\\{/g\nconst closePattern = /\\\\}/g\nconst commaPattern = /\\\\,/g\nconst periodPattern = /\\\\./g\n\nexport const EXPANSION_MAX = 100_000\n\nfunction numeric(str: string) {\n return !isNaN(str as any) ? parseInt(str, 10) : str.charCodeAt(0)\n}\n\nfunction escapeBraces(str: string) {\n return str\n .replace(slashPattern, escSlash)\n .replace(openPattern, escOpen)\n .replace(closePattern, escClose)\n .replace(commaPattern, escComma)\n .replace(periodPattern, escPeriod)\n}\n\nfunction unescapeBraces(str: string) {\n return str\n .replace(escSlashPattern, '\\\\')\n .replace(escOpenPattern, '{')\n .replace(escClosePattern, '}')\n .replace(escCommaPattern, ',')\n .replace(escPeriodPattern, '.')\n}\n\n/**\n * Basically just str.split(\",\"), but handling cases\n * where we have nested braced sections, which should be\n * treated as individual members, like {a,{b,c},d}\n */\nfunction parseCommaParts(str: string) {\n if (!str) {\n return ['']\n }\n\n const parts: string[] = []\n const m = balanced('{', '}', str)\n\n if (!m) {\n return str.split(',')\n }\n\n const { pre, body, post } = m\n const p = pre.split(',')\n\n p[p.length - 1] += '{' + body + '}'\n const postParts = parseCommaParts(post)\n if (post.length) {\n ;(p[p.length - 1] as string) += postParts.shift()\n p.push.apply(p, postParts)\n }\n\n parts.push.apply(parts, p)\n\n return parts\n}\n\nexport type BraceExpansionOptions = {\n max?: number\n}\n\nexport function expand(str: string, options: BraceExpansionOptions = {}) {\n if (!str) {\n return []\n }\n\n const { max = EXPANSION_MAX } = options\n\n // I don't know why Bash 4.3 does this, but it does.\n // Anything starting with {} will have the first two bytes preserved\n // but *only* at the top level, so {},a}b will not expand to anything,\n // but a{},b}c will be expanded to [a}c,abc].\n // One could argue that this is a bug in Bash, but since the goal of\n // this module is to match Bash's rules, we escape a leading {}\n if (str.slice(0, 2) === '{}') {\n str = '\\\\{\\\\}' + str.slice(2)\n }\n\n return expand_(escapeBraces(str), max, true).map(unescapeBraces)\n}\n\nfunction embrace(str: string) {\n return '{' + str + '}'\n}\n\nfunction isPadded(el: string) {\n return /^-?0\\d/.test(el)\n}\n\nfunction lte(i: number, y: number) {\n return i <= y\n}\n\nfunction gte(i: number, y: number) {\n return i >= y\n}\n\nfunction expand_(str: string, max: number, isTop: boolean): string[] {\n /** @type {string[]} */\n const expansions: string[] = []\n\n const m = balanced('{', '}', str)\n if (!m) return [str]\n\n // no need to expand pre, since it is guaranteed to be free of brace-sets\n const pre = m.pre\n const post: string[] = m.post.length ? expand_(m.post, max, false) : ['']\n\n if (/\\$$/.test(m.pre)) {\n for (let k = 0; k < post.length && k < max; k++) {\n const expansion = pre + '{' + m.body + '}' + post[k]\n expansions.push(expansion)\n }\n } else {\n const isNumericSequence = /^-?\\d+\\.\\.-?\\d+(?:\\.\\.-?\\d+)?$/.test(m.body)\n const isAlphaSequence = /^[a-zA-Z]\\.\\.[a-zA-Z](?:\\.\\.-?\\d+)?$/.test(\n m.body,\n )\n const isSequence = isNumericSequence || isAlphaSequence\n const isOptions = m.body.indexOf(',') >= 0\n if (!isSequence && !isOptions) {\n // {a},b}\n if (m.post.match(/,(?!,).*\\}/)) {\n str = m.pre + '{' + m.body + escClose + m.post\n return expand_(str, max, true)\n }\n return [str]\n }\n\n let n: string[]\n if (isSequence) {\n n = m.body.split(/\\.\\./)\n } else {\n n = parseCommaParts(m.body)\n if (n.length === 1 && n[0] !== undefined) {\n // x{{a,b}}y ==> x{a}y x{b}y\n n = expand_(n[0], max, false).map(embrace)\n //XXX is this necessary? Can't seem to hit it in tests.\n /* c8 ignore start */\n if (n.length === 1) {\n return post.map(p => m.pre + n[0] + p)\n }\n /* c8 ignore stop */\n }\n }\n\n // at this point, n is the parts, and we know it's not a comma set\n // with a single entry.\n let N: string[]\n\n if (isSequence && n[0] !== undefined && n[1] !== undefined) {\n const x = numeric(n[0])\n const y = numeric(n[1])\n const width = Math.max(n[0].length, n[1].length)\n let incr =\n n.length === 3 && n[2] !== undefined ? Math.abs(numeric(n[2])) : 1\n let test = lte\n const reverse = y < x\n if (reverse) {\n incr *= -1\n test = gte\n }\n const pad = n.some(isPadded)\n\n N = []\n\n for (let i = x; test(i, y); i += incr) {\n let c\n if (isAlphaSequence) {\n c = String.fromCharCode(i)\n if (c === '\\\\') {\n c = ''\n }\n } else {\n c = String(i)\n if (pad) {\n const need = width - c.length\n if (need > 0) {\n const z = new Array(need + 1).join('0')\n if (i < 0) {\n c = '-' + z + c.slice(1)\n } else {\n c = z + c\n }\n }\n }\n }\n N.push(c)\n }\n } else {\n N = []\n\n for (let j = 0; j < n.length; j++) {\n N.push.apply(N, expand_(n[j] as string, max, false))\n }\n }\n\n for (let j = 0; j < N.length; j++) {\n for (let k = 0; k < post.length && expansions.length < max; k++) {\n const expansion = pre + N[j] + post[k]\n if (!isTop || isSequence || expansion) {\n expansions.push(expansion)\n }\n }\n }\n }\n\n return expansions\n}\n"]}
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
package/package.json CHANGED
@@ -1,50 +1,64 @@
1
1
  {
2
2
  "name": "brace-expansion",
3
3
  "description": "Brace expansion as known from sh/bash",
4
- "version": "4.0.1",
5
- "repository": {
6
- "type": "git",
7
- "url": "git://github.com/juliangruber/brace-expansion.git"
4
+ "version": "5.0.3",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "exports": {
9
+ "./package.json": "./package.json",
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/esm/index.d.ts",
13
+ "default": "./dist/esm/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/commonjs/index.d.ts",
17
+ "default": "./dist/commonjs/index.js"
18
+ }
19
+ }
8
20
  },
9
- "homepage": "https://github.com/juliangruber/brace-expansion",
10
- "exports": "./index.js",
11
21
  "type": "module",
12
22
  "scripts": {
13
- "test": "standard --fix && node --test",
14
- "gentest": "bash test/generate.sh",
15
- "bench": "matcha bench/bench.js"
16
- },
17
- "dependencies": {
18
- "balanced-match": "^3.0.0"
23
+ "preversion": "npm test",
24
+ "postversion": "npm publish",
25
+ "prepublishOnly": "git push origin --follow-tags",
26
+ "prepare": "tshy",
27
+ "pretest": "npm run prepare",
28
+ "presnap": "npm run prepare",
29
+ "test": "tap",
30
+ "snap": "tap",
31
+ "format": "prettier --write .",
32
+ "benchmark": "node benchmark/index.js",
33
+ "typedoc": "typedoc --tsconfig .tshy/esm.json ./src/*.ts"
19
34
  },
20
35
  "devDependencies": {
21
- "@c4312/matcha": "^1.3.1",
22
- "standard": "^17.1.0"
36
+ "@types/brace-expansion": "^1.1.2",
37
+ "@types/node": "^25.2.1",
38
+ "mkdirp": "^3.0.1",
39
+ "prettier": "^3.3.2",
40
+ "tap": "^21.6.2",
41
+ "tshy": "^3.0.2",
42
+ "typedoc": "^0.28.5"
23
43
  },
24
- "keywords": [],
25
- "author": {
26
- "name": "Julian Gruber",
27
- "email": "mail@juliangruber.com",
28
- "url": "http://juliangruber.com"
44
+ "dependencies": {
45
+ "balanced-match": "^4.0.2"
29
46
  },
30
47
  "license": "MIT",
31
- "testling": {
32
- "files": "test/*.js",
33
- "browsers": [
34
- "ie/8..latest",
35
- "firefox/20..latest",
36
- "firefox/nightly",
37
- "chrome/25..latest",
38
- "chrome/canary",
39
- "opera/12..latest",
40
- "opera/next",
41
- "safari/5.1..latest",
42
- "ipad/6.0..latest",
43
- "iphone/6.0..latest",
44
- "android-browser/4.2..latest"
45
- ]
46
- },
47
48
  "engines": {
48
- "node": ">= 18"
49
+ "node": "18 || 20 || >=22"
50
+ },
51
+ "tshy": {
52
+ "exports": {
53
+ "./package.json": "./package.json",
54
+ ".": "./src/index.ts"
55
+ }
56
+ },
57
+ "main": "./dist/commonjs/index.js",
58
+ "types": "./dist/commonjs/index.d.ts",
59
+ "module": "./dist/esm/index.js",
60
+ "repository": {
61
+ "type": "git",
62
+ "url": "git+ssh://git@github.com/juliangruber/brace-expansion.git"
49
63
  }
50
64
  }
@@ -1,2 +0,0 @@
1
- tidelift: "npm/brace-expansion"
2
- patreon: juliangruber
@@ -1,15 +0,0 @@
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/bench/bench.js DELETED
@@ -1,13 +0,0 @@
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 DELETED
@@ -1,235 +0,0 @@
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
- const escSlashPattern = new RegExp(escSlash, 'g')
9
- const escOpenPattern = new RegExp(escOpen, 'g')
10
- const escClosePattern = new RegExp(escClose, 'g')
11
- const escCommaPattern = new RegExp(escComma, 'g')
12
- const escPeriodPattern = new RegExp(escPeriod, 'g')
13
- const slashPattern = /\\\\/g
14
- const openPattern = /\\{/g
15
- const closePattern = /\\}/g
16
- const commaPattern = /\\,/g
17
- const periodPattern = /\\./g
18
-
19
- /**
20
- * @return {number}
21
- */
22
- function numeric (str) {
23
- return !isNaN(str)
24
- ? parseInt(str, 10)
25
- : str.charCodeAt(0)
26
- }
27
-
28
- /**
29
- * @param {string} str
30
- */
31
- function escapeBraces (str) {
32
- return str.replace(slashPattern, escSlash)
33
- .replace(openPattern, escOpen)
34
- .replace(closePattern, escClose)
35
- .replace(commaPattern, escComma)
36
- .replace(periodPattern, escPeriod)
37
- }
38
-
39
- /**
40
- * @param {string} str
41
- */
42
- function unescapeBraces (str) {
43
- return str.replace(escSlashPattern, '\\')
44
- .replace(escOpenPattern, '{')
45
- .replace(escClosePattern, '}')
46
- .replace(escCommaPattern, ',')
47
- .replace(escPeriodPattern, '.')
48
- }
49
-
50
- /**
51
- * Basically just str.split(","), but handling cases
52
- * where we have nested braced sections, which should be
53
- * treated as individual members, like {a,{b,c},d}
54
- * @param {string} str
55
- */
56
- function parseCommaParts (str) {
57
- if (!str) { return [''] }
58
-
59
- const parts = []
60
- const m = balanced('{', '}', str)
61
-
62
- if (!m) { return str.split(',') }
63
-
64
- const { pre, body, post } = m
65
- const p = pre.split(',')
66
-
67
- p[p.length - 1] += '{' + body + '}'
68
- const postParts = parseCommaParts(post)
69
- if (post.length) {
70
- p[p.length - 1] += postParts.shift()
71
- p.push.apply(p, postParts)
72
- }
73
-
74
- parts.push.apply(parts, p)
75
-
76
- return parts
77
- }
78
-
79
- /**
80
- * @param {string} str
81
- */
82
- export default function expandTop (str) {
83
- if (!str) { return [] }
84
-
85
- // I don't know why Bash 4.3 does this, but it does.
86
- // Anything starting with {} will have the first two bytes preserved
87
- // but *only* at the top level, so {},a}b will not expand to anything,
88
- // but a{},b}c will be expanded to [a}c,abc].
89
- // One could argue that this is a bug in Bash, but since the goal of
90
- // this module is to match Bash's rules, we escape a leading {}
91
- if (str.slice(0, 2) === '{}') {
92
- str = '\\{\\}' + str.slice(2)
93
- }
94
-
95
- return expand(escapeBraces(str), true).map(unescapeBraces)
96
- }
97
-
98
- /**
99
- * @param {string} str
100
- */
101
- function embrace (str) {
102
- return '{' + str + '}'
103
- }
104
-
105
- /**
106
- * @param {string} el
107
- */
108
- function isPadded (el) {
109
- return /^-?0\d/.test(el)
110
- }
111
-
112
- /**
113
- * @param {number} i
114
- * @param {number} y
115
- */
116
- function lte (i, y) {
117
- return i <= y
118
- }
119
-
120
- /**
121
- * @param {number} i
122
- * @param {number} y
123
- */
124
- function gte (i, y) {
125
- return i >= y
126
- }
127
-
128
- /**
129
- * @param {string} str
130
- * @param {boolean} [isTop]
131
- */
132
- function expand (str, isTop) {
133
- /** @type {string[]} */
134
- const expansions = []
135
-
136
- const m = balanced('{', '}', str)
137
- if (!m) return [str]
138
-
139
- // no need to expand pre, since it is guaranteed to be free of brace-sets
140
- const pre = m.pre
141
- const post = m.post.length
142
- ? expand(m.post, false)
143
- : ['']
144
-
145
- if (/\$$/.test(m.pre)) {
146
- for (let k = 0; k < post.length; k++) {
147
- const expansion = pre + '{' + m.body + '}' + post[k]
148
- expansions.push(expansion)
149
- }
150
- } else {
151
- const isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body)
152
- const isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body)
153
- const isSequence = isNumericSequence || isAlphaSequence
154
- const isOptions = m.body.indexOf(',') >= 0
155
- if (!isSequence && !isOptions) {
156
- // {a},b}
157
- if (m.post.match(/,(?!,).*\}/)) {
158
- str = m.pre + '{' + m.body + escClose + m.post
159
- return expand(str)
160
- }
161
- return [str]
162
- }
163
-
164
- let n
165
- if (isSequence) {
166
- n = m.body.split(/\.\./)
167
- } else {
168
- n = parseCommaParts(m.body)
169
- if (n.length === 1) {
170
- // x{{a,b}}y ==> x{a}y x{b}y
171
- n = expand(n[0], false).map(embrace)
172
- if (n.length === 1) {
173
- return post.map(function (p) {
174
- return m.pre + n[0] + p
175
- })
176
- }
177
- }
178
- }
179
-
180
- // at this point, n is the parts, and we know it's not a comma set
181
- // with a single entry.
182
- let N
183
-
184
- if (isSequence) {
185
- const x = numeric(n[0])
186
- const y = numeric(n[1])
187
- const width = Math.max(n[0].length, n[1].length)
188
- let incr = n.length === 3
189
- ? Math.abs(numeric(n[2]))
190
- : 1
191
- let test = lte
192
- const reverse = y < x
193
- if (reverse) {
194
- incr *= -1
195
- test = gte
196
- }
197
- const pad = n.some(isPadded)
198
-
199
- N = []
200
-
201
- for (let i = x; test(i, y); i += incr) {
202
- let c
203
- if (isAlphaSequence) {
204
- c = String.fromCharCode(i)
205
- if (c === '\\') { c = '' }
206
- } else {
207
- c = String(i)
208
- if (pad) {
209
- const need = width - c.length
210
- if (need > 0) {
211
- const z = new Array(need + 1).join('0')
212
- if (i < 0) { c = '-' + z + c.slice(1) } else { c = z + c }
213
- }
214
- }
215
- }
216
- N.push(c)
217
- }
218
- } else {
219
- N = []
220
-
221
- for (let j = 0; j < n.length; j++) {
222
- N.push.apply(N, expand(n[j], false))
223
- }
224
- }
225
-
226
- for (let j = 0; j < N.length; j++) {
227
- for (let k = 0; k < post.length; k++) {
228
- const expansion = pre + N[j] + post[k]
229
- if (!isTop || isSequence || expansion) { expansions.push(expansion) }
230
- }
231
- }
232
- }
233
-
234
- return expansions
235
- }
package/tea.yaml DELETED
@@ -1,6 +0,0 @@
1
- # https://tea.xyz/what-is-this-file
2
- ---
3
- version: 1.0.0
4
- codeOwners:
5
- - '0xE7DEE1B8Bb97C3065850Cf582D6DED57C6009587'
6
- quorum: 1