@@ -128,6 +128,53 @@ The command's technical implementation involves:
128128 return extractedLabels ;
129129 }
130130
131+ /**
132+ * Extract original custom label values from CustomLabels.labels-meta.xml
133+ */
134+ private async extractOriginalLabels ( labelNames : string [ ] , debugMode : boolean ) : Promise < Map < string , any > > {
135+ uxLog ( "log" , this , c . grey ( `Looking for original custom label definitions...` ) ) ;
136+
137+ const originalLabels = new Map < string , any > ( ) ;
138+ const customLabelsFiles = await glob ( '**/labels/CustomLabels.labels-meta.xml' , { ignore : GLOB_IGNORE_PATTERNS } ) ;
139+
140+ if ( customLabelsFiles . length === 0 ) {
141+ uxLog ( "warning" , this , c . yellow ( `No CustomLabels.labels-meta.xml found.` ) ) ;
142+ return originalLabels ;
143+ }
144+
145+ for ( const customLabelsFile of customLabelsFiles ) {
146+ const xmlContent = await fs . readFile ( customLabelsFile , 'utf8' ) ;
147+ const parsedXml = await parseStringPromise ( xmlContent , { explicitArray : false } ) ;
148+
149+ if ( ! parsedXml . CustomLabels || ! parsedXml . CustomLabels . labels ) {
150+ continue ;
151+ }
152+
153+ const labels = Array . isArray ( parsedXml . CustomLabels . labels )
154+ ? parsedXml . CustomLabels . labels
155+ : [ parsedXml . CustomLabels . labels ] ;
156+
157+ for ( const label of labels ) {
158+ const labelName = label . fullName || label . name ;
159+
160+ if ( labelNames . includes ( labelName ) ) {
161+ originalLabels . set ( labelName , {
162+ name : labelName ,
163+ label : label . value || '' ,
164+ shortDescription : label . shortDescription || '' ,
165+ } ) ;
166+
167+ if ( debugMode ) {
168+ uxLog ( "log" , this , c . grey ( `Found original: ${ labelName } = "${ label . value } "` ) ) ;
169+ }
170+ }
171+ }
172+ }
173+
174+ uxLog ( "log" , this , c . grey ( `Found ${ originalLabels . size } original label definitions.` ) ) ;
175+ return originalLabels ;
176+ }
177+
131178 public async run ( ) : Promise < AnyJson > {
132179 const { flags } = await this . parse ( CustomLabelTranslations ) ;
133180 const debugMode = flags . debug || false ;
@@ -161,6 +208,7 @@ The command's technical implementation involves:
161208 uxLog ( "log" , this , c . grey ( `Processing custom labels: ${ labelNames . join ( ', ' ) } ` ) ) ;
162209
163210 try {
211+ const originalLabels = await this . extractOriginalLabels ( labelNames , debugMode ) ;
164212 const timestamp = new Date ( ) . toISOString ( ) . replace ( / [: .] / g, '-' ) ;
165213 const outputDir = path . join ( 'extracted-translations' , `${ this . outputDirPrefix } -${ timestamp } ` ) ;
166214 await fs . ensureDir ( outputDir ) ;
@@ -245,9 +293,43 @@ The command's technical implementation involves:
245293 uxLog ( "success" , this , c . green ( `Successfully extracted custom labels to ${ outputDir } .` ) ) ;
246294 uxLog ( "log" , this , c . grey ( `Processed ${ totalFiles } translation files.` ) ) ;
247295
296+ if ( originalLabels . size > 0 ) {
297+ const originalXmlLabels : any [ ] = [ ] ;
298+
299+ for ( const labelName of labelNames ) {
300+ const original = originalLabels . get ( labelName ) ;
301+ if ( original ) {
302+ originalXmlLabels . push ( {
303+ name : original . name ,
304+ label : original . label ,
305+ shortDescription : original . shortDescription ,
306+ } ) ;
307+ }
308+ }
309+
310+ if ( originalXmlLabels . length > 0 ) {
311+ const originalXml = {
312+ Translations : {
313+ $ : { xmlns : "http://soap.sforce.com/2006/04/metadata" } ,
314+ customLabels : originalXmlLabels
315+ }
316+ } ;
317+
318+ const builder = new Builder ( {
319+ xmldec : { version : '1.0' , encoding : 'UTF-8' } ,
320+ renderOpts : { pretty : true , indent : ' ' , newline : '\n' }
321+ } ) ;
322+ const outputXml = builder . buildObject ( originalXml ) ;
323+
324+ const originalFile = path . join ( outputDir , 'original.translation-meta.xml' ) ;
325+ await fs . writeFile ( originalFile , outputXml ) ;
326+
327+ uxLog ( "log" , this , c . grey ( `Generated original labels file: original.translation-meta.xml` ) ) ;
328+ }
329+ }
330+
248331 WebSocketClient . requestOpenFile ( outputDir ) ;
249332
250- // Return an object to be displayed with --json
251333 return {
252334 success : true ,
253335 outputDirectory : outputDir ,
0 commit comments