@@ -5,7 +5,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
55Object . defineProperty ( exports , "__esModule" , { value : true } ) ;
66const utils_1 = require ( "../utils" ) ;
77const infuser_1 = __importDefault ( require ( "../infuser" ) ) ;
8+ const squeezer_1 = __importDefault ( require ( "../squeezer" ) ) ;
89const fs_1 = __importDefault ( require ( "fs" ) ) ;
10+ const path_1 = __importDefault ( require ( "path" ) ) ;
11+ const deep_diff_1 = require ( "deep-diff" ) ;
12+ const glob_1 = __importDefault ( require ( "glob" ) ) ;
13+ const debug_1 = require ( "debug" ) ;
14+ const debug = debug_1 . debug ( 'vue-i18n-locale-message:commands:infuse' ) ;
915exports . command = 'infuse' ;
1016exports . aliases = 'inf' ;
1117exports . describe = 'infuse locale messages to single-file components' ;
@@ -17,23 +23,140 @@ exports.builder = (args) => {
1723 describe : 'target path that single-file components is stored' ,
1824 demandOption : true
1925 } )
20- . option ( 'messages ' , {
26+ . option ( 'locales ' , {
2127 type : 'string' ,
22- alias : 'm ' ,
28+ alias : 'l ' ,
2329 describe : 'locale messages path to be infused' ,
2430 demandOption : true
31+ } )
32+ . option ( 'match' , {
33+ type : 'string' ,
34+ alias : 'm' ,
35+ describe : 'option should be accepted a regex filenames, must be specified together --messages'
2536 } ) ;
2637} ;
2738exports . handler = ( args ) => {
2839 const targetPath = utils_1 . resolve ( args . target ) ;
29- const messagesPath = utils_1 . resolve ( args . messages ) ;
30- const newSources = infuser_1 . default ( targetPath , utils_1 . readSFC ( targetPath ) , readLocaleMessages ( messagesPath ) ) ;
40+ const messagesPath = utils_1 . resolve ( args . locales ) ;
41+ const sources = utils_1 . readSFC ( targetPath ) ;
42+ const messages = readLocaleMessages ( messagesPath , args . match ) ;
43+ const meta = squeezer_1 . default ( targetPath , sources ) ;
44+ apply ( messages , meta ) ;
45+ const newSources = infuser_1 . default ( targetPath , sources , meta ) ;
3146 writeSFC ( newSources ) ;
3247} ;
33- function readLocaleMessages ( path ) {
34- // TODO: async implementation
35- const data = fs_1 . default . readFileSync ( path , { encoding : 'utf8' } ) ;
36- return JSON . parse ( data ) ;
48+ function readLocaleMessages ( targetPath , matchRegex ) {
49+ debug ( 'readLocaleMessages' , targetPath , matchRegex ) ;
50+ if ( ! matchRegex ) {
51+ const data = fs_1 . default . readFileSync ( targetPath , { encoding : 'utf8' } ) ;
52+ return JSON . parse ( data ) ;
53+ }
54+ else {
55+ const globPath = path_1 . default . normalize ( `${ targetPath } /*.json` ) ;
56+ const paths = glob_1 . default . sync ( globPath ) ;
57+ return paths . reduce ( ( messages , p ) => {
58+ const re = new RegExp ( matchRegex , 'ig' ) ;
59+ const filename = path_1 . default . basename ( p ) ;
60+ const match = re . exec ( filename ) ;
61+ debug ( 'regex match' , match ) ;
62+ if ( match ) {
63+ const data = fs_1 . default . readFileSync ( p , { encoding : 'utf8' } ) ;
64+ Object . assign ( messages , { [ match [ 1 ] ] : JSON . parse ( data ) } ) ;
65+ }
66+ return messages ;
67+ } , { } ) ;
68+ }
69+ }
70+ function removeItem ( item , items ) {
71+ const index = items . indexOf ( item ) ;
72+ if ( index === - 1 ) {
73+ return false ;
74+ }
75+ items . splice ( index , 1 ) ;
76+ return true ;
77+ }
78+ function apply ( messages , meta ) {
79+ const { target, components } = meta ;
80+ for ( const [ component , blocks ] of Object . entries ( components ) ) {
81+ debug ( `apply component = ${ component } , blocks = ${ JSON . stringify ( blocks ) } ` ) ;
82+ const { hierarchy } = utils_1 . parsePath ( target , component ) ;
83+ const collectMessages = getTargetLocaleMessages ( messages , hierarchy ) ;
84+ debug ( 'collect messages' , JSON . stringify ( collectMessages , null , 2 ) ) ;
85+ const sourceLocales = Object . keys ( collectMessages ) ;
86+ const targetLocales = blocks . reduce ( ( locales , block ) => {
87+ if ( block . locale ) {
88+ locales . push ( block . locale ) ;
89+ }
90+ else {
91+ locales = Object . keys ( block . messages ) . reduce ( ( locales , locale ) => {
92+ locales . push ( locale ) ;
93+ return locales ;
94+ } , locales ) ;
95+ }
96+ return locales ;
97+ } , [ ] ) ;
98+ debug ( `locales: source = ${ sourceLocales } , target = ${ targetLocales } ` ) ;
99+ blocks . forEach ( block => {
100+ const { locale } = block ;
101+ if ( locale ) {
102+ deep_diff_1 . applyDiff ( block . messages [ locale ] , collectMessages [ locale ] ) ;
103+ removeItem ( locale , sourceLocales ) ;
104+ removeItem ( locale , targetLocales ) ;
105+ }
106+ else {
107+ const locales = Object . keys ( block . messages ) ;
108+ locales . forEach ( locale => {
109+ deep_diff_1 . applyDiff ( block . messages [ locale ] , collectMessages [ locale ] ) ;
110+ removeItem ( locale , sourceLocales ) ;
111+ removeItem ( locale , targetLocales ) ;
112+ } ) ;
113+ }
114+ } ) ;
115+ debug ( `locales remain: source = ${ sourceLocales } , target = ${ targetLocales } ` ) ;
116+ if ( sourceLocales . length ) {
117+ sourceLocales . forEach ( locale => {
118+ blocks . push ( {
119+ lang : 'json' ,
120+ locale,
121+ messages : Object . assign ( { } , { [ locale ] : collectMessages [ locale ] } )
122+ } ) ;
123+ } ) ;
124+ }
125+ if ( targetLocales . length ) {
126+ debug ( 'invalid target remain locales ...' , targetLocales . length ) ;
127+ }
128+ }
129+ return meta ;
130+ }
131+ function getTargetLocaleMessages ( messages , hierarchy ) {
132+ return Object . keys ( messages ) . reduce ( ( target , locale ) => {
133+ debug ( `processing curernt: locale=${ locale } , target=${ JSON . stringify ( target ) } ` ) ;
134+ const obj = messages [ locale ] ;
135+ if ( obj ) {
136+ let o = obj ;
137+ let prev = null ;
138+ const h = hierarchy . concat ( ) ;
139+ while ( h . length > 0 ) {
140+ const key = h . shift ( ) ;
141+ debug ( 'processing hierarchy key: ' , key ) ;
142+ if ( ! key || ! o ) {
143+ break ;
144+ }
145+ o = o [ key ] ;
146+ prev = o ;
147+ debug ( `processing o = ${ JSON . stringify ( o ) } , prev = ${ JSON . stringify ( prev ) } ` ) ;
148+ }
149+ if ( ! o && ! prev ) {
150+ return target ;
151+ }
152+ else {
153+ return Object . assign ( target , { [ locale ] : ( ( ! o && prev ) ? prev : o ) } ) ;
154+ }
155+ }
156+ else {
157+ return target ;
158+ }
159+ } , { } ) ;
37160}
38161function writeSFC ( sources ) {
39162 // TODO: async implementation
0 commit comments