@@ -752,12 +752,43 @@ function parseQualifiedField(value: string): { dataset?: string; field: string }
752752}
753753
754754function renderTemplate ( template : string , row : GenericSqlRow ) : string {
755- return template . replace ( / \{ ( [ ^ } ] + ) \} / g, ( _ , field : string ) => stringifyRawValue ( row [ field ] ) ) ;
755+ const rendered : string [ ] = [ ] ;
756+ let cursor = 0 ;
757+ while ( cursor < template . length ) {
758+ const open = template . indexOf ( '{' , cursor ) ;
759+ if ( open === - 1 ) {
760+ rendered . push ( template . slice ( cursor ) ) ;
761+ break ;
762+ }
763+ const close = template . indexOf ( '}' , open + 1 ) ;
764+ if ( close === - 1 ) {
765+ rendered . push ( template . slice ( cursor ) ) ;
766+ break ;
767+ }
768+
769+ rendered . push ( template . slice ( cursor , open ) ) ;
770+ const field = template . slice ( open + 1 , close ) ;
771+ rendered . push ( field ? stringifyRawValue ( row [ field ] ) : template . slice ( open , close + 1 ) ) ;
772+ cursor = close + 1 ;
773+ }
774+ return rendered . join ( '' ) ;
756775}
757776
758777function resolveTemplateArgument ( value : string , row : GenericSqlRow ) : unknown {
759- const exact = / ^ \{ ( [ ^ } ] + ) \} $ / . exec ( value ) ;
760- return exact ? row [ exact [ 1 ] ! ] : renderTemplate ( value , row ) ;
778+ const exact = exactTemplateField ( value ) ;
779+ return exact ? row [ exact ] : renderTemplate ( value , row ) ;
780+ }
781+
782+ function exactTemplateField ( value : string ) : string | null {
783+ if ( ! value . startsWith ( '{' ) || ! value . endsWith ( '}' ) || value . length <= 2 ) {
784+ return null ;
785+ }
786+ const close = value . indexOf ( '}' , 1 ) ;
787+ if ( close !== value . length - 1 ) {
788+ return null ;
789+ }
790+ const field = value . slice ( 1 , - 1 ) ;
791+ return field || null ;
761792}
762793
763794function stringifyRawValue ( value : unknown ) : string {
0 commit comments