@@ -29,24 +29,32 @@ export function unwrapPatternDefinitions(
2929
3030 // Recursively inline a single pattern
3131 function unwrapPattern ( pattern : string , seen : Set < string > = new Set ( ) ) : string {
32- // Match %{PATTERN_NAME} or %{PATTERN_NAME:field}
33- return pattern . replace ( / % { ( [ A - Z 0 - 9 _ ] + ) ( : [ ^ } ] * ) ? } / g, ( match , key , fieldName ) => {
34- if ( pattern_definitions && pattern_definitions [ key ] ) {
35- if ( seen . has ( key ) ) {
36- // Prevent infinite recursion on cyclic definitions
37- return match ;
38- }
39- seen . add ( key ) ;
40- const inlined = unwrapPattern ( pattern_definitions [ key ] , seen ) ;
41- seen . delete ( key ) ;
42- if ( fieldName ) {
43- // Named capture group
44- return `(?< ${ fieldName . substring ( 1 ) } > ${ inlined } )` ;
45- }
46- return `( ${ inlined } )` ;
32+ /**
33+ * Intentional optimization: previously a single regex /%{([A-Z0-9_]+)(:[^}]*)? }/g
34+ * with an optional capture group. We now perform two deterministic passes with two
35+ * separate regexes - one for patterns WITH a field name and one for patterns
36+ * WITHOUT - eliminating the optional branch.
37+ */
38+ const WITHOUT_FIELD = / % { ( [ A - Z 0 - 9 _ ] + ) } / g ; // %{PATTERN }
39+ const WITH_FIELD = / % { ( [ A - Z 0 - 9 _ ] + ) : ( [ ^ } ] + ) } / g ; // %{PATTERN:field}
40+
41+ const expand = ( match : string , key : string , fieldName ?: string ) : string => {
42+ if ( ! pattern_definitions || ! pattern_definitions [ key ] ) {
43+ return match ; // unknown definition - leave untouched
44+ }
45+ if ( seen . has ( key ) ) {
46+ return match ; // cyclic reference safeguard
4747 }
48- return match ; // Leave as is if not in patternDefs
49- } ) ;
48+ seen . add ( key ) ;
49+ const inlined = unwrapPattern ( pattern_definitions [ key ] , seen ) ;
50+ seen . delete ( key ) ;
51+ if ( fieldName ) {
52+ return `(?<${ fieldName } >${ inlined } )` ;
53+ }
54+ return `(${ inlined } )` ;
55+ } ;
56+
57+ return pattern . replace ( WITHOUT_FIELD , expand ) . replace ( WITH_FIELD , expand ) ;
5058 }
5159
5260 return patterns . map ( ( pattern ) => unwrapPattern ( pattern ) ) ;
0 commit comments