@@ -36,36 +36,79 @@ export abstract class ConverterCommon extends EventEmitter {
3636 protected abstract createLanguageResourcesFiles (
3737 language : string ,
3838 isDefaultLanguage : boolean ,
39- i18nContentIterator : Iterable < I18nEntry >
39+ i18nEntries : I18nEntries
4040 ) : this;
4141
4242 public abstract livesyncExclusionPatterns ( ) : string [ ] ;
4343
44+ public loadLangage ( filePath : string ) : I18nEntries {
45+ delete ( < any > require ) . cache [ ( < any > require ) . resolve ( filePath ) ] ;
46+
47+ const fileContent = require ( filePath ) ;
48+ const i18nEntries : I18nEntries = new Map ( ) ;
49+ const stack = [ { prefix : "" , element : fileContent } ] ;
50+
51+ while ( stack . length > 0 ) {
52+ const { prefix, element } = stack . pop ( ) ;
53+ if ( Array . isArray ( element ) ) {
54+ i18nEntries . set ( prefix , element . join ( "" ) ) ;
55+ } else if ( typeof element === "object" ) {
56+ for ( const key of Object . keys ( element ) ) {
57+ stack . push ( { prefix : prefix === "" ? key : `${ prefix } .${ key } ` , element : element [ key ] } ) ;
58+ }
59+ } else {
60+ i18nEntries . set ( prefix , new String ( element ) . valueOf ( ) ) ;
61+ }
62+ }
63+
64+ return i18nEntries ;
65+ }
66+
4467 public run ( ) : this {
4568 if ( ! fs . existsSync ( this . i18nDirectoryPath ) ) {
46- this . logger . info ( `'${ this . i18nDirectoryPath } ' doesn't exists: nothing to localize` ) ;
69+ this . logger . warn ( `'${ this . i18nDirectoryPath } ' doesn't exists: nothing to localize` ) ;
4770 return this ;
4871 }
4972
73+ let defaultLanguage = undefined ;
5074 const supportedLanguages : SupportedLanguages = new Map ( ) ;
5175
5276 fs . readdirSync ( this . i18nDirectoryPath ) . map ( fileName => {
5377 return path . join ( this . i18nDirectoryPath , fileName ) ;
5478 } ) . filter ( filePath => {
5579 return fs . statSync ( filePath ) . isFile ( ) ;
56- } ) . map ( filePath => {
57- delete ( < any > require ) . cache [ ( < any > require ) . resolve ( filePath ) ] ;
58- return filePath ;
59- } ) . map ( filePath => {
80+ } ) . forEach ( filePath => {
6081 let language = path . basename ( filePath , path . extname ( filePath ) ) ;
61- const isDefaultLanguage = path . extname ( language ) === ".default" ;
62- if ( isDefaultLanguage ) { language = path . basename ( language , ".default" ) ; }
63- supportedLanguages . set ( language , isDefaultLanguage ) ;
64- this . createLanguageResourcesFiles (
65- language ,
66- isDefaultLanguage ,
67- this . i18nContentGenerator ( require ( filePath ) )
68- ) ;
82+ if ( path . extname ( language ) === ".default" ) {
83+ language = path . basename ( language , ".default" ) ;
84+ defaultLanguage = language ;
85+ }
86+ supportedLanguages . set ( language , filePath ) ;
87+ } ) ;
88+
89+ if ( supportedLanguages . size === 0 ) {
90+ this . logger . warn ( `'${ this . i18nDirectoryPath } ' is empty: nothing to localize` ) ;
91+ return this ;
92+ }
93+
94+ if ( ! defaultLanguage ) {
95+ defaultLanguage = supportedLanguages . keys ( ) . next ( ) . value ;
96+ this . logger . warn ( `No file found with the .default extension: default langage set to '${ defaultLanguage } '` ) ;
97+ }
98+
99+ const defaultLanguageI18nEntries = this . loadLangage ( supportedLanguages . get ( defaultLanguage ) ) ;
100+ this . createLanguageResourcesFiles ( defaultLanguage , true , defaultLanguageI18nEntries ) ;
101+
102+ supportedLanguages . forEach ( ( filePath , language ) => {
103+ if ( language !== defaultLanguage ) {
104+ const languageI18nEntries = this . loadLangage ( filePath ) ;
105+ defaultLanguageI18nEntries . forEach ( ( value , key ) => {
106+ if ( ! languageI18nEntries . has ( key ) ) {
107+ languageI18nEntries . set ( key , value ) ;
108+ }
109+ } ) ;
110+ this . createLanguageResourcesFiles ( language , false , languageI18nEntries ) ;
111+ }
69112 } ) ;
70113
71114 [ this . appResourcesDirectoryPath , this . appResourcesDestinationDirectoryPath ] . forEach ( resourcesDirectoryPath => {
@@ -77,22 +120,6 @@ export abstract class ConverterCommon extends EventEmitter {
77120 return this ;
78121 }
79122
80- public * i18nContentGenerator ( i18nContent : any ) : Iterable < I18nEntry > {
81- const stack = [ { prefix : "" , element : i18nContent } ] ;
82- while ( stack . length > 0 ) {
83- const { prefix, element } = stack . pop ( ) ;
84- if ( Array . isArray ( element ) ) {
85- yield { key : prefix , value : element . join ( "" ) } ;
86- } else if ( typeof element === "object" ) {
87- for ( const key of Object . keys ( element ) ) {
88- stack . push ( { prefix : prefix === "" ? key : `${ prefix } .${ key } ` , element : element [ key ] } ) ;
89- }
90- } else {
91- yield { key : < string > prefix , value : new String ( element ) . valueOf ( ) } ;
92- }
93- }
94- }
95-
96123 protected createDirectoryIfNeeded ( directoryPath : string ) : this {
97124 if ( ! fs . existsSync ( directoryPath ) || ! fs . statSync ( directoryPath ) . isDirectory ( ) ) { mkdirp . sync ( directoryPath ) ; }
98125 return this ;
@@ -118,5 +145,5 @@ export abstract class ConverterCommon extends EventEmitter {
118145 }
119146}
120147
121- export type I18nEntry = { key : string ; value : string ; } ;
122- export type SupportedLanguages = Map < string , boolean > ;
148+ export type I18nEntries = Map < string , string > ;
149+ export type SupportedLanguages = Map < string , string > ;
0 commit comments