@@ -28,16 +28,21 @@ export default function createYamlLoader(): ILoader<
2828 try {
2929 // Parse source and extract quoting metadata
3030 const sourceDoc = YAML . parseDocument ( originalInput ) ;
31- const metadata = extractQuotingMetadata ( sourceDoc ) ;
3231
33- // Create output document and apply source quoting
32+ // Create output document - let the library handle smart quoting
3433 const outputDoc = YAML . parseDocument (
3534 YAML . stringify ( payload , {
3635 lineWidth : - 1 ,
3736 defaultKeyType : "PLAIN" ,
3837 } ) ,
3938 ) ;
40- applyQuotingMetadata ( outputDoc , metadata ) ;
39+
40+ // Detect if this is yaml-root-key format by comparing structures
41+ const isRootKeyFormat = detectRootKeyFormat ( sourceDoc , outputDoc ) ;
42+
43+ // Extract and apply metadata with root-key awareness
44+ const metadata = extractQuotingMetadata ( sourceDoc , isRootKeyFormat ) ;
45+ applyQuotingMetadata ( outputDoc , metadata , isRootKeyFormat ) ;
4146
4247 return outputDoc . toString ( { lineWidth : - 1 } ) ;
4348 } catch ( error ) {
@@ -53,16 +58,70 @@ export default function createYamlLoader(): ILoader<
5358 } ) ;
5459}
5560
61+ // Detect if this is yaml-root-key format by comparing source and output structures
62+ function detectRootKeyFormat (
63+ sourceDoc : YAML . Document ,
64+ outputDoc : YAML . Document ,
65+ ) : boolean {
66+ const sourceRoot = sourceDoc . contents ;
67+ const outputRoot = outputDoc . contents ;
68+
69+ // Both must be maps with single root key
70+ if ( ! isYAMLMap ( sourceRoot ) || ! isYAMLMap ( outputRoot ) ) {
71+ return false ;
72+ }
73+
74+ const sourceMap = sourceRoot as any ;
75+ const outputMap = outputRoot as any ;
76+
77+ if (
78+ ! sourceMap . items ||
79+ sourceMap . items . length !== 1 ||
80+ ! outputMap . items ||
81+ outputMap . items . length !== 1
82+ ) {
83+ return false ;
84+ }
85+
86+ const sourceRootKey = getKeyValue ( sourceMap . items [ 0 ] . key ) ;
87+ const outputRootKey = getKeyValue ( outputMap . items [ 0 ] . key ) ;
88+
89+ // If both have single root keys that are DIFFERENT strings, it's yaml-root-key format
90+ // (e.g., source has "en:", output has "es:")
91+ if (
92+ sourceRootKey !== outputRootKey &&
93+ typeof sourceRootKey === "string" &&
94+ typeof outputRootKey === "string"
95+ ) {
96+ return true ;
97+ }
98+
99+ return false ;
100+ }
101+
56102// Extract quoting metadata from source document
57- function extractQuotingMetadata ( doc : YAML . Document ) : QuotingMetadata {
103+ function extractQuotingMetadata (
104+ doc : YAML . Document ,
105+ skipRootKey : boolean ,
106+ ) : QuotingMetadata {
58107 const metadata : QuotingMetadata = {
59108 keys : new Map < string , string > ( ) ,
60109 values : new Map < string , string > ( ) ,
61110 } ;
62111 const root = doc . contents ;
63112 if ( ! root ) return metadata ;
64113
65- walkAndExtract ( root , [ ] , metadata ) ;
114+ let startNode : any = root ;
115+
116+ // If yaml-root-key format, skip the locale root key
117+ if ( skipRootKey && isYAMLMap ( root ) ) {
118+ const rootMap = root as any ;
119+ if ( rootMap . items && rootMap . items . length === 1 ) {
120+ startNode = rootMap . items [ 0 ] . value ;
121+ }
122+ }
123+
124+ walkAndExtract ( startNode , [ ] , metadata ) ;
66125 return metadata ;
67126}
68127
@@ -113,11 +172,22 @@ function walkAndExtract(
113172function applyQuotingMetadata (
114173 doc : YAML . Document ,
115174 metadata : QuotingMetadata ,
175+ skipRootKey : boolean ,
116176) : void {
117177 const root = doc . contents ;
118178 if ( ! root ) return ;
119179
120- walkAndApply ( root , [ ] , metadata ) ;
180+ let startNode : any = root ;
181+
182+ // If yaml-root-key format, skip the locale root key
183+ if ( skipRootKey && isYAMLMap ( root ) ) {
184+ const rootMap = root as any ;
185+ if ( rootMap . items && rootMap . items . length === 1 ) {
186+ startNode = rootMap . items [ 0 ] . value ;
187+ }
188+ }
189+
190+ walkAndApply ( startNode , [ ] , metadata ) ;
121191}
122192
123193// Walk AST and apply quoting information
0 commit comments