@pattern-algebra/core 0.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.
- package/README.md +571 -0
- package/dist/automaton/complement.d.ts +20 -0
- package/dist/automaton/complement.d.ts.map +1 -0
- package/dist/automaton/complement.js +36 -0
- package/dist/automaton/complement.js.map +1 -0
- package/dist/automaton/complement.test.d.ts +2 -0
- package/dist/automaton/complement.test.d.ts.map +1 -0
- package/dist/automaton/complement.test.js +114 -0
- package/dist/automaton/complement.test.js.map +1 -0
- package/dist/automaton/determinize.d.ts +41 -0
- package/dist/automaton/determinize.d.ts.map +1 -0
- package/dist/automaton/determinize.js +310 -0
- package/dist/automaton/determinize.js.map +1 -0
- package/dist/automaton/determinize.test.d.ts +2 -0
- package/dist/automaton/determinize.test.d.ts.map +1 -0
- package/dist/automaton/determinize.test.js +134 -0
- package/dist/automaton/determinize.test.js.map +1 -0
- package/dist/automaton/emptiness.d.ts +41 -0
- package/dist/automaton/emptiness.d.ts.map +1 -0
- package/dist/automaton/emptiness.js +262 -0
- package/dist/automaton/emptiness.js.map +1 -0
- package/dist/automaton/emptiness.test.d.ts +2 -0
- package/dist/automaton/emptiness.test.d.ts.map +1 -0
- package/dist/automaton/emptiness.test.js +154 -0
- package/dist/automaton/emptiness.test.js.map +1 -0
- package/dist/automaton/index.d.ts +10 -0
- package/dist/automaton/index.d.ts.map +1 -0
- package/dist/automaton/index.js +11 -0
- package/dist/automaton/index.js.map +1 -0
- package/dist/automaton/intersect.d.ts +35 -0
- package/dist/automaton/intersect.d.ts.map +1 -0
- package/dist/automaton/intersect.js +302 -0
- package/dist/automaton/intersect.js.map +1 -0
- package/dist/automaton/pattern-algebra.d.ts +62 -0
- package/dist/automaton/pattern-algebra.d.ts.map +1 -0
- package/dist/automaton/pattern-algebra.js +309 -0
- package/dist/automaton/pattern-algebra.js.map +1 -0
- package/dist/automaton/pattern-algebra.test.d.ts +2 -0
- package/dist/automaton/pattern-algebra.test.d.ts.map +1 -0
- package/dist/automaton/pattern-algebra.test.js +223 -0
- package/dist/automaton/pattern-algebra.test.js.map +1 -0
- package/dist/compile/automaton-builder.d.ts +47 -0
- package/dist/compile/automaton-builder.d.ts.map +1 -0
- package/dist/compile/automaton-builder.js +211 -0
- package/dist/compile/automaton-builder.js.map +1 -0
- package/dist/compile/compiler.d.ts +32 -0
- package/dist/compile/compiler.d.ts.map +1 -0
- package/dist/compile/compiler.js +47 -0
- package/dist/compile/compiler.js.map +1 -0
- package/dist/compile/index.d.ts +8 -0
- package/dist/compile/index.d.ts.map +1 -0
- package/dist/compile/index.js +8 -0
- package/dist/compile/index.js.map +1 -0
- package/dist/compile/quick-reject.d.ts +28 -0
- package/dist/compile/quick-reject.d.ts.map +1 -0
- package/dist/compile/quick-reject.js +147 -0
- package/dist/compile/quick-reject.js.map +1 -0
- package/dist/containment/analysis.d.ts +60 -0
- package/dist/containment/analysis.d.ts.map +1 -0
- package/dist/containment/analysis.js +378 -0
- package/dist/containment/analysis.js.map +1 -0
- package/dist/containment/containment.d.ts +23 -0
- package/dist/containment/containment.d.ts.map +1 -0
- package/dist/containment/containment.js +681 -0
- package/dist/containment/containment.js.map +1 -0
- package/dist/containment/containment.test.d.ts +2 -0
- package/dist/containment/containment.test.d.ts.map +1 -0
- package/dist/containment/containment.test.js +209 -0
- package/dist/containment/containment.test.js.map +1 -0
- package/dist/containment/index.d.ts +7 -0
- package/dist/containment/index.d.ts.map +1 -0
- package/dist/containment/index.js +7 -0
- package/dist/containment/index.js.map +1 -0
- package/dist/core-alpha.d.ts +1253 -0
- package/dist/core-beta.d.ts +1253 -0
- package/dist/core-public.d.ts +1253 -0
- package/dist/core-unstripped.d.ts +1253 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/match/index.d.ts +8 -0
- package/dist/match/index.d.ts.map +1 -0
- package/dist/match/index.js +8 -0
- package/dist/match/index.js.map +1 -0
- package/dist/match/matcher.d.ts +40 -0
- package/dist/match/matcher.d.ts.map +1 -0
- package/dist/match/matcher.js +256 -0
- package/dist/match/matcher.js.map +1 -0
- package/dist/match/matcher.test.d.ts +2 -0
- package/dist/match/matcher.test.d.ts.map +1 -0
- package/dist/match/matcher.test.js +185 -0
- package/dist/match/matcher.test.js.map +1 -0
- package/dist/match/path-utils.d.ts +132 -0
- package/dist/match/path-utils.d.ts.map +1 -0
- package/dist/match/path-utils.js +223 -0
- package/dist/match/path-utils.js.map +1 -0
- package/dist/match/path-utils.test.d.ts +2 -0
- package/dist/match/path-utils.test.d.ts.map +1 -0
- package/dist/match/path-utils.test.js +193 -0
- package/dist/match/path-utils.test.js.map +1 -0
- package/dist/match/segment-matcher.d.ts +25 -0
- package/dist/match/segment-matcher.d.ts.map +1 -0
- package/dist/match/segment-matcher.js +267 -0
- package/dist/match/segment-matcher.js.map +1 -0
- package/dist/parse/brace-expansion.d.ts +34 -0
- package/dist/parse/brace-expansion.d.ts.map +1 -0
- package/dist/parse/brace-expansion.js +294 -0
- package/dist/parse/brace-expansion.js.map +1 -0
- package/dist/parse/brace-expansion.test.d.ts +2 -0
- package/dist/parse/brace-expansion.test.d.ts.map +1 -0
- package/dist/parse/brace-expansion.test.js +105 -0
- package/dist/parse/brace-expansion.test.js.map +1 -0
- package/dist/parse/index.d.ts +8 -0
- package/dist/parse/index.d.ts.map +1 -0
- package/dist/parse/index.js +8 -0
- package/dist/parse/index.js.map +1 -0
- package/dist/parse/parser.d.ts +15 -0
- package/dist/parse/parser.d.ts.map +1 -0
- package/dist/parse/parser.js +526 -0
- package/dist/parse/parser.js.map +1 -0
- package/dist/parse/parser.test.d.ts +2 -0
- package/dist/parse/parser.test.d.ts.map +1 -0
- package/dist/parse/parser.test.js +266 -0
- package/dist/parse/parser.test.js.map +1 -0
- package/dist/parse/validator.d.ts +30 -0
- package/dist/parse/validator.d.ts.map +1 -0
- package/dist/parse/validator.js +115 -0
- package/dist/parse/validator.js.map +1 -0
- package/dist/parse/validator.test.d.ts +2 -0
- package/dist/parse/validator.test.d.ts.map +1 -0
- package/dist/parse/validator.test.js +45 -0
- package/dist/parse/validator.test.js.map +1 -0
- package/dist/types/ast.d.ts +158 -0
- package/dist/types/ast.d.ts.map +1 -0
- package/dist/types/ast.js +2 -0
- package/dist/types/ast.js.map +1 -0
- package/dist/types/automaton.d.ts +150 -0
- package/dist/types/automaton.d.ts.map +1 -0
- package/dist/types/automaton.js +2 -0
- package/dist/types/automaton.js.map +1 -0
- package/dist/types/containment.d.ts +257 -0
- package/dist/types/containment.d.ts.map +1 -0
- package/dist/types/containment.js +5 -0
- package/dist/types/containment.js.map +1 -0
- package/dist/types/errors.d.ts +37 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +24 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +6 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Segment-level matching utilities.
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Check if a path segment matches a segment pattern.
|
|
7
|
+
*
|
|
8
|
+
* @param segment - The actual path segment (e.g., "file.ts")
|
|
9
|
+
* @param pattern - The pattern segment from AST
|
|
10
|
+
* @returns true if the segment matches
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export function matchSegment(segment, pattern) {
|
|
15
|
+
switch (pattern.type) {
|
|
16
|
+
case 'literal':
|
|
17
|
+
return segment === pattern.value;
|
|
18
|
+
case 'globstar':
|
|
19
|
+
// Globstar matches any single segment (when used as transition)
|
|
20
|
+
return true;
|
|
21
|
+
case 'wildcard':
|
|
22
|
+
return matchWildcard(segment, pattern);
|
|
23
|
+
case 'charclass':
|
|
24
|
+
// Single charclass matches a single character segment
|
|
25
|
+
return segment.length === 1 && matchCharClass(segment[0], pattern);
|
|
26
|
+
case 'composite':
|
|
27
|
+
return matchComposite(segment, pattern);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Match a segment against a wildcard pattern.
|
|
32
|
+
*/
|
|
33
|
+
function matchWildcard(segment, pattern) {
|
|
34
|
+
return matchWildcardParts(segment, 0, pattern.parts, 0);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Recursive wildcard matching with backtracking.
|
|
38
|
+
*/
|
|
39
|
+
function matchWildcardParts(segment, segPos, parts, partIndex) {
|
|
40
|
+
// Base case: consumed all parts
|
|
41
|
+
if (partIndex >= parts.length) {
|
|
42
|
+
return segPos === segment.length;
|
|
43
|
+
}
|
|
44
|
+
const part = parts[partIndex];
|
|
45
|
+
switch (part.type) {
|
|
46
|
+
case 'literal': {
|
|
47
|
+
const literal = part.value;
|
|
48
|
+
if (!segment.startsWith(literal, segPos)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return matchWildcardParts(segment, segPos + literal.length, parts, partIndex + 1);
|
|
52
|
+
}
|
|
53
|
+
case 'question': {
|
|
54
|
+
// Must match exactly one character
|
|
55
|
+
if (segPos >= segment.length) {
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
return matchWildcardParts(segment, segPos + 1, parts, partIndex + 1);
|
|
59
|
+
}
|
|
60
|
+
case 'star': {
|
|
61
|
+
// Star matches zero or more characters - try all possibilities
|
|
62
|
+
// Optimization: if this is the last part, consume everything
|
|
63
|
+
if (partIndex === parts.length - 1) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
// Try matching 0, 1, 2, ... characters
|
|
67
|
+
for (let i = segPos; i <= segment.length; i++) {
|
|
68
|
+
if (matchWildcardParts(segment, i, parts, partIndex + 1)) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Match a character against a character class.
|
|
78
|
+
*/
|
|
79
|
+
function matchCharClass(char, spec) {
|
|
80
|
+
let matches = false;
|
|
81
|
+
// Check individual characters
|
|
82
|
+
if (spec.chars.includes(char)) {
|
|
83
|
+
matches = true;
|
|
84
|
+
}
|
|
85
|
+
// Check ranges
|
|
86
|
+
if (!matches) {
|
|
87
|
+
const code = char.charCodeAt(0);
|
|
88
|
+
for (const range of spec.ranges) {
|
|
89
|
+
if (code >= range.start.charCodeAt(0) && code <= range.end.charCodeAt(0)) {
|
|
90
|
+
matches = true;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Apply negation
|
|
96
|
+
return spec.negated ? !matches : matches;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Match a segment against a composite pattern.
|
|
100
|
+
*/
|
|
101
|
+
function matchComposite(segment, pattern) {
|
|
102
|
+
return matchCompositeParts(segment, 0, pattern.parts, 0);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Recursive composite matching.
|
|
106
|
+
*/
|
|
107
|
+
function matchCompositeParts(segment, segPos, parts, partIndex) {
|
|
108
|
+
// Base case: consumed all parts
|
|
109
|
+
if (partIndex >= parts.length) {
|
|
110
|
+
return segPos === segment.length;
|
|
111
|
+
}
|
|
112
|
+
const part = parts[partIndex];
|
|
113
|
+
switch (part.type) {
|
|
114
|
+
case 'literal': {
|
|
115
|
+
const literal = part.value;
|
|
116
|
+
if (!segment.startsWith(literal, segPos)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return matchCompositeParts(segment, segPos + literal.length, parts, partIndex + 1);
|
|
120
|
+
}
|
|
121
|
+
case 'question': {
|
|
122
|
+
if (segPos >= segment.length) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
return matchCompositeParts(segment, segPos + 1, parts, partIndex + 1);
|
|
126
|
+
}
|
|
127
|
+
case 'star': {
|
|
128
|
+
// If last part, consume everything
|
|
129
|
+
if (partIndex === parts.length - 1) {
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
// Try matching 0, 1, 2, ... characters
|
|
133
|
+
for (let i = segPos; i <= segment.length; i++) {
|
|
134
|
+
if (matchCompositeParts(segment, i, parts, partIndex + 1)) {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
case 'charclass': {
|
|
141
|
+
if (segPos >= segment.length) {
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
if (!matchCharClass(segment[segPos], part.spec)) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
return matchCompositeParts(segment, segPos + 1, parts, partIndex + 1);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Build a RegExp from a segment pattern for automaton transitions.
|
|
153
|
+
*
|
|
154
|
+
* @param pattern - Segment pattern
|
|
155
|
+
* @returns RegExp that matches the segment, or null for globstar/literal
|
|
156
|
+
*
|
|
157
|
+
* @public
|
|
158
|
+
*/
|
|
159
|
+
export function segmentToRegex(pattern) {
|
|
160
|
+
switch (pattern.type) {
|
|
161
|
+
case 'literal':
|
|
162
|
+
// Literal doesn't need regex - use exact comparison
|
|
163
|
+
return null;
|
|
164
|
+
case 'globstar':
|
|
165
|
+
// Globstar matches any segment
|
|
166
|
+
return /^.+$/;
|
|
167
|
+
case 'wildcard':
|
|
168
|
+
return wildcardToRegex(pattern);
|
|
169
|
+
case 'charclass':
|
|
170
|
+
return charClassToRegex(pattern);
|
|
171
|
+
case 'composite':
|
|
172
|
+
return compositeToRegex(pattern);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Convert wildcard pattern to regex.
|
|
177
|
+
*/
|
|
178
|
+
function wildcardToRegex(pattern) {
|
|
179
|
+
let regexStr = '^';
|
|
180
|
+
for (const part of pattern.parts) {
|
|
181
|
+
switch (part.type) {
|
|
182
|
+
case 'literal':
|
|
183
|
+
regexStr += escapeRegex(part.value);
|
|
184
|
+
break;
|
|
185
|
+
case 'star':
|
|
186
|
+
regexStr += '.*';
|
|
187
|
+
break;
|
|
188
|
+
case 'question':
|
|
189
|
+
regexStr += '.';
|
|
190
|
+
break;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
regexStr += '$';
|
|
194
|
+
return new RegExp(regexStr);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Convert char class to regex.
|
|
198
|
+
*/
|
|
199
|
+
function charClassToRegex(spec) {
|
|
200
|
+
let charClass = '[';
|
|
201
|
+
if (spec.negated) {
|
|
202
|
+
charClass += '^';
|
|
203
|
+
}
|
|
204
|
+
// Add individual chars (escaped)
|
|
205
|
+
for (const char of spec.chars) {
|
|
206
|
+
charClass += escapeRegexChar(char);
|
|
207
|
+
}
|
|
208
|
+
// Add ranges
|
|
209
|
+
for (const range of spec.ranges) {
|
|
210
|
+
charClass += escapeRegexChar(range.start) + '-' + escapeRegexChar(range.end);
|
|
211
|
+
}
|
|
212
|
+
charClass += ']';
|
|
213
|
+
return new RegExp(`^${charClass}$`);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Convert composite pattern to regex.
|
|
217
|
+
*/
|
|
218
|
+
function compositeToRegex(pattern) {
|
|
219
|
+
let regexStr = '^';
|
|
220
|
+
for (const part of pattern.parts) {
|
|
221
|
+
switch (part.type) {
|
|
222
|
+
case 'literal':
|
|
223
|
+
regexStr += escapeRegex(part.value);
|
|
224
|
+
break;
|
|
225
|
+
case 'star':
|
|
226
|
+
regexStr += '.*';
|
|
227
|
+
break;
|
|
228
|
+
case 'question':
|
|
229
|
+
regexStr += '.';
|
|
230
|
+
break;
|
|
231
|
+
case 'charclass': {
|
|
232
|
+
const spec = part.spec;
|
|
233
|
+
let charClass = '[';
|
|
234
|
+
if (spec.negated) {
|
|
235
|
+
charClass += '^';
|
|
236
|
+
}
|
|
237
|
+
for (const char of spec.chars) {
|
|
238
|
+
charClass += escapeRegexChar(char);
|
|
239
|
+
}
|
|
240
|
+
for (const range of spec.ranges) {
|
|
241
|
+
charClass += escapeRegexChar(range.start) + '-' + escapeRegexChar(range.end);
|
|
242
|
+
}
|
|
243
|
+
charClass += ']';
|
|
244
|
+
regexStr += charClass;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
regexStr += '$';
|
|
250
|
+
return new RegExp(regexStr);
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Escape special regex characters in a string.
|
|
254
|
+
*/
|
|
255
|
+
function escapeRegex(str) {
|
|
256
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Escape a single character for use in a regex character class.
|
|
260
|
+
*/
|
|
261
|
+
function escapeRegexChar(char) {
|
|
262
|
+
if ('^-]\\'.includes(char)) {
|
|
263
|
+
return '\\' + char;
|
|
264
|
+
}
|
|
265
|
+
return char;
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=segment-matcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment-matcher.js","sourceRoot":"","sources":["../../src/match/segment-matcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brace expansion utilities.
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
import type { PathPattern } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Expand brace expressions in a pattern, creating multiple patterns.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* expandBraces(parsePattern('{src,lib}/*.ts'))
|
|
11
|
+
* // => [parsePattern('src/*.ts'), parsePattern('lib/*.ts')]
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* expandBraces(parsePattern('file{1..3}.txt'))
|
|
15
|
+
* // => [parsePattern('file1.txt'), parsePattern('file2.txt'), parsePattern('file3.txt')]
|
|
16
|
+
*
|
|
17
|
+
* @param pattern - The pattern to expand
|
|
18
|
+
* @param maxExpansion - Maximum number of expanded patterns (default: 100)
|
|
19
|
+
* @returns Array of expanded patterns
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export declare function expandBraces(pattern: PathPattern, maxExpansion?: number): readonly PathPattern[];
|
|
24
|
+
/**
|
|
25
|
+
* Count the number of patterns that would result from expansion.
|
|
26
|
+
* Does not actually expand - useful for limit checking.
|
|
27
|
+
*
|
|
28
|
+
* @param source - Pattern source string
|
|
29
|
+
* @returns Estimated expansion count, or Infinity if it would exceed reasonable limits
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export declare function countBraceExpansions(source: string): number;
|
|
34
|
+
//# sourceMappingURL=brace-expansion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brace-expansion.d.ts","sourceRoot":"","sources":["../../src/parse/brace-expansion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,UAAU,CAAA;AAMzD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,WAAW,EACpB,YAAY,GAAE,MAA8B,GAC3C,SAAS,WAAW,EAAE,CAyBxB;AAuOD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAyC3D"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Brace expansion utilities.
|
|
3
|
+
* @packageDocumentation
|
|
4
|
+
*/
|
|
5
|
+
import { parsePattern } from './parser';
|
|
6
|
+
/** Default maximum expansion factor */
|
|
7
|
+
const DEFAULT_MAX_EXPANSION = 100;
|
|
8
|
+
/**
|
|
9
|
+
* Expand brace expressions in a pattern, creating multiple patterns.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* expandBraces(parsePattern('{src,lib}/*.ts'))
|
|
13
|
+
* // => [parsePattern('src/*.ts'), parsePattern('lib/*.ts')]
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* expandBraces(parsePattern('file{1..3}.txt'))
|
|
17
|
+
* // => [parsePattern('file1.txt'), parsePattern('file2.txt'), parsePattern('file3.txt')]
|
|
18
|
+
*
|
|
19
|
+
* @param pattern - The pattern to expand
|
|
20
|
+
* @param maxExpansion - Maximum number of expanded patterns (default: 100)
|
|
21
|
+
* @returns Array of expanded patterns
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
export function expandBraces(pattern, maxExpansion = DEFAULT_MAX_EXPANSION) {
|
|
26
|
+
// If already has errors, return as-is
|
|
27
|
+
if (pattern.errors && pattern.errors.length > 0) {
|
|
28
|
+
return [pattern];
|
|
29
|
+
}
|
|
30
|
+
// Check if pattern contains braces at all
|
|
31
|
+
if (!pattern.source.includes('{')) {
|
|
32
|
+
return [pattern];
|
|
33
|
+
}
|
|
34
|
+
// Expand the source string
|
|
35
|
+
const expanded = expandBraceString(pattern.source, maxExpansion);
|
|
36
|
+
if (expanded.error) {
|
|
37
|
+
// Add error to pattern and return
|
|
38
|
+
const errorPattern = {
|
|
39
|
+
...pattern,
|
|
40
|
+
errors: [...(pattern.errors ?? []), expanded.error],
|
|
41
|
+
};
|
|
42
|
+
return [errorPattern];
|
|
43
|
+
}
|
|
44
|
+
// Parse each expanded pattern
|
|
45
|
+
return expanded.patterns.map((src) => parsePattern(src));
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Expand braces in a pattern string.
|
|
49
|
+
*/
|
|
50
|
+
function expandBraceString(source, maxExpansion) {
|
|
51
|
+
// Handle negation prefix
|
|
52
|
+
let prefix = '';
|
|
53
|
+
let toExpand = source;
|
|
54
|
+
if (source.startsWith('!')) {
|
|
55
|
+
prefix = '!';
|
|
56
|
+
toExpand = source.slice(1);
|
|
57
|
+
}
|
|
58
|
+
const expanded = doExpandBraces(toExpand, maxExpansion);
|
|
59
|
+
if (expanded.error) {
|
|
60
|
+
return expanded;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
patterns: expanded.patterns.map((p) => prefix + p),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Core brace expansion logic.
|
|
68
|
+
*/
|
|
69
|
+
function doExpandBraces(pattern, maxExpansion) {
|
|
70
|
+
// Find first top-level brace
|
|
71
|
+
const braceInfo = findTopLevelBrace(pattern);
|
|
72
|
+
if (!braceInfo) {
|
|
73
|
+
return { patterns: [pattern] };
|
|
74
|
+
}
|
|
75
|
+
const { start, end, content } = braceInfo;
|
|
76
|
+
// Check for nested braces
|
|
77
|
+
if (content.includes('{')) {
|
|
78
|
+
return {
|
|
79
|
+
patterns: [pattern],
|
|
80
|
+
error: {
|
|
81
|
+
code: 'NESTED_BRACES',
|
|
82
|
+
message: 'Nested braces are not allowed',
|
|
83
|
+
position: start,
|
|
84
|
+
length: end - start + 1,
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
const prefix = pattern.slice(0, start);
|
|
89
|
+
const suffix = pattern.slice(end + 1);
|
|
90
|
+
// Parse brace content
|
|
91
|
+
const alternatives = parseBraceContent(content);
|
|
92
|
+
if (alternatives.error) {
|
|
93
|
+
return {
|
|
94
|
+
patterns: [pattern],
|
|
95
|
+
error: alternatives.error,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
// Check expansion limit before expanding
|
|
99
|
+
if (alternatives.items.length > maxExpansion) {
|
|
100
|
+
return {
|
|
101
|
+
patterns: [pattern],
|
|
102
|
+
error: {
|
|
103
|
+
code: 'EXPANSION_LIMIT',
|
|
104
|
+
message: `Brace expansion exceeds limit of ${maxExpansion}`,
|
|
105
|
+
position: start,
|
|
106
|
+
length: end - start + 1,
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// Expand
|
|
111
|
+
const expanded = alternatives.items.map((item) => prefix + item + suffix);
|
|
112
|
+
// Check total expansion
|
|
113
|
+
if (expanded.length > maxExpansion) {
|
|
114
|
+
return {
|
|
115
|
+
patterns: expanded.slice(0, maxExpansion),
|
|
116
|
+
error: {
|
|
117
|
+
code: 'EXPANSION_LIMIT',
|
|
118
|
+
message: `Brace expansion exceeds limit of ${maxExpansion}`,
|
|
119
|
+
position: start,
|
|
120
|
+
length: end - start + 1,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
// Recursively expand remaining braces
|
|
125
|
+
const allExpanded = [];
|
|
126
|
+
for (const exp of expanded) {
|
|
127
|
+
const recursive = doExpandBraces(exp, maxExpansion - allExpanded.length);
|
|
128
|
+
if (recursive.error) {
|
|
129
|
+
return recursive;
|
|
130
|
+
}
|
|
131
|
+
allExpanded.push(...recursive.patterns);
|
|
132
|
+
if (allExpanded.length > maxExpansion) {
|
|
133
|
+
return {
|
|
134
|
+
patterns: allExpanded.slice(0, maxExpansion),
|
|
135
|
+
error: {
|
|
136
|
+
code: 'EXPANSION_LIMIT',
|
|
137
|
+
message: `Total brace expansion exceeds limit of ${maxExpansion}`,
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return { patterns: allExpanded };
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Find the first top-level brace pair.
|
|
146
|
+
*/
|
|
147
|
+
function findTopLevelBrace(pattern) {
|
|
148
|
+
let inBracket = false;
|
|
149
|
+
let braceStart = -1;
|
|
150
|
+
let depth = 0;
|
|
151
|
+
for (let i = 0; i < pattern.length; i++) {
|
|
152
|
+
const char = pattern[i];
|
|
153
|
+
const prevChar = i > 0 ? pattern[i - 1] : '';
|
|
154
|
+
if (prevChar === '\\')
|
|
155
|
+
continue;
|
|
156
|
+
if (char === '[' && !inBracket) {
|
|
157
|
+
inBracket = true;
|
|
158
|
+
}
|
|
159
|
+
else if (char === ']' && inBracket) {
|
|
160
|
+
inBracket = false;
|
|
161
|
+
}
|
|
162
|
+
else if (char === '{' && !inBracket) {
|
|
163
|
+
if (depth === 0) {
|
|
164
|
+
braceStart = i;
|
|
165
|
+
}
|
|
166
|
+
depth++;
|
|
167
|
+
}
|
|
168
|
+
else if (char === '}' && !inBracket && depth > 0) {
|
|
169
|
+
depth--;
|
|
170
|
+
if (depth === 0) {
|
|
171
|
+
return {
|
|
172
|
+
start: braceStart,
|
|
173
|
+
end: i,
|
|
174
|
+
content: pattern.slice(braceStart + 1, i),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Parse the content inside braces.
|
|
183
|
+
*/
|
|
184
|
+
function parseBraceContent(content) {
|
|
185
|
+
// Check for numeric range
|
|
186
|
+
const rangeMatch = /^(-?\d+)\.\.(-?\d+)$/.exec(content);
|
|
187
|
+
if (rangeMatch) {
|
|
188
|
+
const start = parseInt(rangeMatch[1], 10);
|
|
189
|
+
const end = parseInt(rangeMatch[2], 10);
|
|
190
|
+
const step = start <= end ? 1 : -1;
|
|
191
|
+
const count = Math.abs(end - start) + 1;
|
|
192
|
+
if (count > 50) {
|
|
193
|
+
return {
|
|
194
|
+
items: [],
|
|
195
|
+
error: {
|
|
196
|
+
code: 'EXPANSION_LIMIT',
|
|
197
|
+
message: `Numeric range {${start}..${end}} exceeds limit of 50 elements`,
|
|
198
|
+
},
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const items = [];
|
|
202
|
+
for (let n = start; step > 0 ? n <= end : n >= end; n += step) {
|
|
203
|
+
items.push(String(n));
|
|
204
|
+
}
|
|
205
|
+
return { items };
|
|
206
|
+
}
|
|
207
|
+
// Split by commas
|
|
208
|
+
const items = splitByComma(content);
|
|
209
|
+
return { items };
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Split content by commas (not inside brackets).
|
|
213
|
+
*/
|
|
214
|
+
function splitByComma(content) {
|
|
215
|
+
const parts = [];
|
|
216
|
+
let current = '';
|
|
217
|
+
let inBracket = false;
|
|
218
|
+
for (let i = 0; i < content.length; i++) {
|
|
219
|
+
const char = content[i];
|
|
220
|
+
const prevChar = i > 0 ? content[i - 1] : '';
|
|
221
|
+
if (prevChar === '\\') {
|
|
222
|
+
current += char;
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
if (char === '[' && !inBracket) {
|
|
226
|
+
inBracket = true;
|
|
227
|
+
current += char;
|
|
228
|
+
}
|
|
229
|
+
else if (char === ']' && inBracket) {
|
|
230
|
+
inBracket = false;
|
|
231
|
+
current += char;
|
|
232
|
+
}
|
|
233
|
+
else if (char === ',' && !inBracket) {
|
|
234
|
+
parts.push(current);
|
|
235
|
+
current = '';
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
current += char;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
parts.push(current);
|
|
242
|
+
return parts;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Count the number of patterns that would result from expansion.
|
|
246
|
+
* Does not actually expand - useful for limit checking.
|
|
247
|
+
*
|
|
248
|
+
* @param source - Pattern source string
|
|
249
|
+
* @returns Estimated expansion count, or Infinity if it would exceed reasonable limits
|
|
250
|
+
*
|
|
251
|
+
* @public
|
|
252
|
+
*/
|
|
253
|
+
export function countBraceExpansions(source) {
|
|
254
|
+
let count = 1;
|
|
255
|
+
let i = 0;
|
|
256
|
+
let inBracket = false;
|
|
257
|
+
let braceDepth = 0;
|
|
258
|
+
let currentAlternatives = 0;
|
|
259
|
+
while (i < source.length) {
|
|
260
|
+
const char = source[i];
|
|
261
|
+
const prevChar = i > 0 ? source[i - 1] : '';
|
|
262
|
+
if (prevChar === '\\') {
|
|
263
|
+
i++;
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
if (char === '[' && !inBracket) {
|
|
267
|
+
inBracket = true;
|
|
268
|
+
}
|
|
269
|
+
else if (char === ']' && inBracket) {
|
|
270
|
+
inBracket = false;
|
|
271
|
+
}
|
|
272
|
+
else if (char === '{' && !inBracket) {
|
|
273
|
+
braceDepth++;
|
|
274
|
+
if (braceDepth === 1) {
|
|
275
|
+
currentAlternatives = 1;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
else if (char === ',' && braceDepth === 1 && !inBracket) {
|
|
279
|
+
currentAlternatives++;
|
|
280
|
+
}
|
|
281
|
+
else if (char === '}' && !inBracket && braceDepth > 0) {
|
|
282
|
+
braceDepth--;
|
|
283
|
+
if (braceDepth === 0) {
|
|
284
|
+
count *= currentAlternatives;
|
|
285
|
+
if (count > 10000) {
|
|
286
|
+
return Infinity;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
i++;
|
|
291
|
+
}
|
|
292
|
+
return count;
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=brace-expansion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brace-expansion.js","sourceRoot":"","sources":["../../src/parse/brace-expansion.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAEvC,uCAAuC;AACvC,MAAM,qBAAqB,GAAG,GAAG,CAAA;AAEjC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,YAAY,CAC1B,OAAoB,EACpB,eAAuB,qBAAqB;IAE5C,sCAAsC;IACtC,IAAI,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO,CAAC,OAAO,CAAC,CAAA;IAClB,CAAC;IAED,0CAA0C;IAC1C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,OAAO,CAAC,CAAA;IAClB,CAAC;IAED,2BAA2B;IAC3B,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,CAAA;IAEhE,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,kCAAkC;QAClC,MAAM,YAAY,GAAgB;YAChC,GAAG,OAAO;YACV,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC;SACpD,CAAA;QACD,OAAO,CAAC,YAAY,CAAC,CAAA;IACvB,CAAC;IAED,8BAA8B;IAC9B,OAAO,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAA;AAC1D,CAAC;AAUD;;GAEG;AACH,SAAS,iBAAiB,CAAC,MAAc,EAAE,YAAoB;IAC7D,yBAAyB;IACzB,IAAI,MAAM,GAAG,EAAE,CAAA;IACf,IAAI,QAAQ,GAAG,MAAM,CAAA;IAErB,IAAI,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC3B,MAAM,GAAG,GAAG,CAAA;QACZ,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;IAC5B,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAA;IAEvD,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;KACnD,CAAA;AACH,CAAC;AAED;;GAEG;AACH,SAAS,cAAc,CAAC,OAAe,EAAE,YAAoB;IAC3D,6BAA6B;IAC7B,MAAM,SAAS,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAE5C,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO,EAAE,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE,CAAA;IAChC,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,SAAS,CAAA;IAEzC,0BAA0B;IAC1B,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1B,OAAO;YACL,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,KAAK,EAAE;gBACL,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,+BAA+B;gBACxC,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,GAAG,GAAG,KAAK,GAAG,CAAC;aACxB;SACF,CAAA;IACH,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAA;IACtC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAA;IAErC,sBAAsB;IACtB,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAE/C,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;QACvB,OAAO;YACL,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,KAAK,EAAE,YAAY,CAAC,KAAK;SAC1B,CAAA;IACH,CAAC;IAED,yCAAyC;IACzC,IAAI,YAAY,CAAC,KAAK,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;QAC7C,OAAO;YACL,QAAQ,EAAE,CAAC,OAAO,CAAC;YACnB,KAAK,EAAE;gBACL,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,oCAAoC,YAAY,EAAE;gBAC3D,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,GAAG,GAAG,KAAK,GAAG,CAAC;aACxB;SACF,CAAA;IACH,CAAC;IAED,SAAS;IACT,MAAM,QAAQ,GAAG,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC,CAAA;IAEzE,wBAAwB;IACxB,IAAI,QAAQ,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;QACnC,OAAO;YACL,QAAQ,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC;YACzC,KAAK,EAAE;gBACL,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,oCAAoC,YAAY,EAAE;gBAC3D,QAAQ,EAAE,KAAK;gBACf,MAAM,EAAE,GAAG,GAAG,KAAK,GAAG,CAAC;aACxB;SACF,CAAA;IACH,CAAC;IAED,sCAAsC;IACtC,MAAM,WAAW,GAAa,EAAE,CAAA;IAChC,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,EAAE,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAAA;QACxE,IAAI,SAAS,CAAC,KAAK,EAAE,CAAC;YACpB,OAAO,SAAS,CAAA;QAClB,CAAC;QACD,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;QACvC,IAAI,WAAW,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;YACtC,OAAO;gBACL,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC;gBAC5C,KAAK,EAAE;oBACL,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,0CAA0C,YAAY,EAAE;iBAClE;aACF,CAAA;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAA;AAClC,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACxC,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,IAAI,UAAU,GAAG,CAAC,CAAC,CAAA;IACnB,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACvB,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAE5C,IAAI,QAAQ,KAAK,IAAI;YAAE,SAAQ;QAE/B,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/B,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;YACrC,SAAS,GAAG,KAAK,CAAA;QACnB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,UAAU,GAAG,CAAC,CAAA;YAChB,CAAC;YACD,KAAK,EAAE,CAAA;QACT,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YACnD,KAAK,EAAE,CAAA;YACP,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;gBAChB,OAAO;oBACL,KAAK,EAAE,UAAU;oBACjB,GAAG,EAAE,CAAC;oBACN,OAAO,EAAE,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,EAAE,CAAC,CAAC;iBAC1C,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,OAAe;IACxC,0BAA0B;IAC1B,MAAM,UAAU,GAAG,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACvD,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACzC,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,KAAK,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;QAClC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAA;QAEvC,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;YACf,OAAO;gBACL,KAAK,EAAE,EAAE;gBACT,KAAK,EAAE;oBACL,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,kBAAkB,KAAK,KAAK,GAAG,gCAAgC;iBACzE;aACF,CAAA;QACH,CAAC;QAED,MAAM,KAAK,GAAa,EAAE,CAAA;QAC1B,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC;YAC9D,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QACvB,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,CAAA;IAClB,CAAC;IAED,kBAAkB;IAClB,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,CAAC,CAAA;IACnC,OAAO,EAAE,KAAK,EAAE,CAAA;AAClB,CAAC;AAED;;GAEG;AACH,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,SAAS,GAAG,KAAK,CAAA;IAErB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;QACvB,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAE5C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,OAAO,IAAI,IAAI,CAAA;YACf,SAAQ;QACV,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/B,SAAS,GAAG,IAAI,CAAA;YAChB,OAAO,IAAI,IAAI,CAAA;QACjB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;YACrC,SAAS,GAAG,KAAK,CAAA;YACjB,OAAO,IAAI,IAAI,CAAA;QACjB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YACnB,OAAO,GAAG,EAAE,CAAA;QACd,CAAC;aAAM,CAAC;YACN,OAAO,IAAI,IAAI,CAAA;QACjB,CAAC;IACH,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACnB,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAc;IACjD,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,IAAI,UAAU,GAAG,CAAC,CAAA;IAClB,IAAI,mBAAmB,GAAG,CAAC,CAAA;IAE3B,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAA;QACtB,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;QAE3C,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;YACtB,CAAC,EAAE,CAAA;YACH,SAAQ;QACV,CAAC;QAED,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YAC/B,SAAS,GAAG,IAAI,CAAA;QAClB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,SAAS,EAAE,CAAC;YACrC,SAAS,GAAG,KAAK,CAAA;QACnB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,UAAU,EAAE,CAAA;YACZ,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;gBACrB,mBAAmB,GAAG,CAAC,CAAA;YACzB,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,UAAU,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1D,mBAAmB,EAAE,CAAA;QACvB,CAAC;aAAM,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC,SAAS,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACxD,UAAU,EAAE,CAAA;YACZ,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;gBACrB,KAAK,IAAI,mBAAmB,CAAA;gBAC5B,IAAI,KAAK,GAAG,KAAK,EAAE,CAAC;oBAClB,OAAO,QAAQ,CAAA;gBACjB,CAAC;YACH,CAAC;QACH,CAAC;QAED,CAAC,EAAE,CAAA;IACL,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"brace-expansion.test.d.ts","sourceRoot":"","sources":["../../src/parse/brace-expansion.test.ts"],"names":[],"mappings":""}
|