@@ -30,6 +30,26 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
3030 let sourceIndex = 0 ;
3131 let generatedIndex = 0 ;
3232
33+ // Map to track capitalized names: original name -> capitalized name
34+ /** @type {Map<string, string> } */
35+ const capitalizedNames = new Map ( ) ;
36+ // Reverse map: capitalized name -> original name
37+ /** @type {Map<string, string> } */
38+ const reverseCapitalizedNames = new Map ( ) ;
39+
40+ // Pre-walk to collect capitalized names from JSXElement nodes (transformed AST)
41+ // These are identifiers that are used as dynamic components/elements
42+ walk ( ast , null , {
43+ _ ( node , { next } ) {
44+ // Check JSXElement nodes with metadata (preserved from Element nodes)
45+ if ( node . type === 'JSXElement' && node . metadata ?. ts_name && node . metadata ?. original_name ) {
46+ capitalizedNames . set ( node . metadata . original_name , node . metadata . ts_name ) ;
47+ reverseCapitalizedNames . set ( node . metadata . ts_name , node . metadata . original_name ) ;
48+ }
49+ next ( ) ;
50+ }
51+ } ) ;
52+
3353 /**
3454 * Check if character is a word boundary (not alphanumeric or underscore)
3555 * @param {string } char
@@ -132,7 +152,8 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
132152 } ;
133153
134154 // Collect text tokens from AST nodes
135- /** @type {string[] } */
155+ // Tokens can be either strings or objects with source/generated properties
156+ /** @type {Array<string | {source: string, generated: string}> } */
136157 const tokens = [ ] ;
137158
138159 // We have to visit everything in generated order to maintain correct indices
@@ -142,12 +163,37 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
142163 // Only collect tokens from nodes with .loc (skip synthesized nodes like children attribute)
143164 if ( node . type === 'Identifier' && node . name ) {
144165 if ( node . loc ) {
145- tokens . push ( node . name ) ;
166+ // Check if this identifier was capitalized (reverse lookup)
167+ const originalName = reverseCapitalizedNames . get ( node . name ) ;
168+ if ( originalName ) {
169+ // This is a capitalized name in generated code, map to lowercase in source
170+ tokens . push ( { source : originalName , generated : node . name } ) ;
171+ } else {
172+ // Check if this identifier should be capitalized (forward lookup)
173+ const capitalizedName = capitalizedNames . get ( node . name ) ;
174+ if ( capitalizedName ) {
175+ tokens . push ( { source : node . name , generated : capitalizedName } ) ;
176+ } else {
177+ tokens . push ( node . name ) ;
178+ }
179+ }
146180 }
147181 return ; // Leaf node, don't traverse further
148182 } else if ( node . type === 'JSXIdentifier' && node . name ) {
149183 if ( node . loc ) {
150- tokens . push ( node . name ) ;
184+ // Check if this was capitalized (reverse lookup)
185+ const originalName = reverseCapitalizedNames . get ( node . name ) ;
186+ if ( originalName ) {
187+ tokens . push ( { source : originalName , generated : node . name } ) ;
188+ } else {
189+ // Check if this should be capitalized (forward lookup)
190+ const capitalizedName = capitalizedNames . get ( node . name ) ;
191+ if ( capitalizedName ) {
192+ tokens . push ( { source : node . name , generated : capitalizedName } ) ;
193+ } else {
194+ tokens . push ( node . name ) ;
195+ }
196+ }
151197 }
152198 return ; // Leaf node, don't traverse further
153199 } else if ( node . type === 'Literal' && node . raw ) {
@@ -252,7 +298,20 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
252298
253299 // 3. Push closing tag name (not visited by AST walker)
254300 if ( ! node . openingElement ?. selfClosing && node . closingElement ?. name ?. type === 'JSXIdentifier' ) {
255- tokens . push ( node . closingElement . name . name ) ;
301+ const closingName = node . closingElement . name . name ;
302+ // Check if this was capitalized (reverse lookup)
303+ const originalName = reverseCapitalizedNames . get ( closingName ) ;
304+ if ( originalName ) {
305+ tokens . push ( { source : originalName , generated : closingName } ) ;
306+ } else {
307+ // Check if this should be capitalized (forward lookup)
308+ const capitalizedName = capitalizedNames . get ( closingName ) ;
309+ if ( capitalizedName ) {
310+ tokens . push ( { source : closingName , generated : capitalizedName } ) ;
311+ } else {
312+ tokens . push ( closingName ) ;
313+ }
314+ }
256315 }
257316
258317 return ;
@@ -1031,15 +1090,26 @@ export function convert_source_map_to_mappings(ast, source, generated_code) {
10311090 } ) ;
10321091
10331092 // Process each token in order
1034- for ( const text of tokens ) {
1035- const sourcePos = findInSource ( text ) ;
1036- const genPos = findInGenerated ( text ) ;
1093+ for ( const token of tokens ) {
1094+ let sourceText , generatedText ;
1095+
1096+ if ( typeof token === 'string' ) {
1097+ sourceText = token ;
1098+ generatedText = token ;
1099+ } else {
1100+ // Token with different source and generated names
1101+ sourceText = token . source ;
1102+ generatedText = token . generated ;
1103+ }
1104+
1105+ const sourcePos = findInSource ( sourceText ) ;
1106+ const genPos = findInGenerated ( generatedText ) ;
10371107
10381108 if ( sourcePos !== null && genPos !== null ) {
10391109 mappings . push ( {
10401110 sourceOffsets : [ sourcePos ] ,
10411111 generatedOffsets : [ genPos ] ,
1042- lengths : [ text . length ] ,
1112+ lengths : [ sourceText . length ] ,
10431113 data : mapping_data ,
10441114 } ) ;
10451115 }
0 commit comments