1- import { Disposable } from 'vscode'
1+ import { Disposable , EventEmitter } from 'vscode'
2+ import _ from 'lodash'
23import { Log } from '../../utils'
3- import { LocaleTree , LocaleNode , LocaleRecord } from '../types'
4+ import { LocaleTree , LocaleNode , LocaleRecord , FlattenLocaleTree , Coverage } from '../types'
45import { Config , Global } from '..'
56
7+ export interface NodeOptions {
8+ locale : string
9+ readonly ?: boolean
10+ filepath : string
11+ sfc ?: boolean
12+ }
13+
614export abstract class Loader extends Disposable {
715 protected _disposables : Disposable [ ] = [ ]
16+ protected _onDidChange = new EventEmitter < undefined > ( )
17+ readonly onDidChange = this . _onDidChange . event
18+
19+ protected _flattenLocaleTree : FlattenLocaleTree = { }
20+ protected _localeTree : LocaleTree = new LocaleTree ( { keypath : '' } )
821
922 constructor (
1023 public readonly name : string
1124 ) {
1225 super ( ( ) => this . onDispose ( ) )
1326 }
1427
15- protected onDispose ( ) {
16- Log . info ( `🗑 Disposing loader "${ this . name } "` )
17- this . _disposables . forEach ( d => d . dispose ( ) )
18- this . _disposables = [ ]
19- }
20-
21- abstract get root ( ) : LocaleTree
2228 abstract get locales ( ) : string [ ]
2329
2430 abstract getShadowFilePath ( keypath : string , locale : string ) : string | undefined
2531
32+ get root ( ) {
33+ return this . _localeTree
34+ }
35+
36+ get flattenLocaleTree ( ) {
37+ return this . _flattenLocaleTree
38+ }
39+
2640 splitKeypath ( keypath : string ) : string [ ] {
2741 return keypath . replace ( / \[ ( .* ?) \] / g, '.$1' ) . split ( '.' )
2842 }
2943
44+ getCoverage ( locale : string , keys ?: string [ ] ) : Coverage | undefined {
45+ keys = keys || Object . keys ( this . _flattenLocaleTree )
46+ const total = keys . length
47+ const translated = keys . filter ( ( key ) => {
48+ return this . _flattenLocaleTree [ key ] && this . _flattenLocaleTree [ key ] . getValue ( locale )
49+ } )
50+ return {
51+ locale,
52+ total,
53+ translated : translated . length ,
54+ keys,
55+ }
56+ }
57+
58+ protected updateTree ( tree : LocaleTree | undefined , data : any , keypath : string , keyname : string , options : NodeOptions , isCollection = false ) {
59+ tree = tree || new LocaleTree ( {
60+ keypath,
61+ keyname,
62+ isCollection,
63+ sfc : options . sfc ,
64+ } )
65+ tree . values [ options . locale ] = data
66+ for ( const [ key , value ] of Object . entries ( data ) ) {
67+ const newKeyPath = keypath
68+ ? ( isCollection
69+ ? `${ keypath } [${ key } ]`
70+ : `${ keypath } .${ key } ` )
71+ : ( isCollection
72+ ? `[${ key } ]`
73+ : key )
74+
75+ // should go nested
76+ if ( _ . isArray ( value ) ) {
77+ let subtree : LocaleTree | undefined
78+ if ( tree . getChild ( key ) && tree . getChild ( key ) . type === 'tree' )
79+ subtree = tree . getChild ( key ) as LocaleTree
80+
81+ tree . setChild ( key , this . updateTree ( subtree , value , newKeyPath , key , options , true ) )
82+ continue
83+ }
84+
85+ if ( _ . isObject ( value ) ) {
86+ let subtree : LocaleTree | undefined
87+ if ( tree . getChild ( key ) && tree . getChild ( key ) . type === 'tree' )
88+ subtree = tree . getChild ( key ) as LocaleTree
89+
90+ tree . setChild ( key , this . updateTree ( subtree , value , newKeyPath , key , options ) )
91+ continue
92+ }
93+
94+ // init node
95+ if ( ! tree . getChild ( key ) ) {
96+ const node = new LocaleNode ( {
97+ keypath : newKeyPath ,
98+ keyname : key ,
99+ readonly : options . readonly ,
100+ sfc : options . sfc ,
101+ } )
102+ tree . setChild ( key , node )
103+ this . _flattenLocaleTree [ node . keypath ] = node
104+ }
105+
106+ // add locales to exitsing node
107+ const node = tree . getChild ( key )
108+ if ( node . type === 'node' ) {
109+ node . locales [ options . locale ] = new LocaleRecord ( {
110+ keypath : newKeyPath ,
111+ keyname : key ,
112+ value : `${ value } ` ,
113+ locale : options . locale ,
114+ filepath : options . filepath ,
115+ sfc : options . sfc ,
116+ readonly : options . readonly ,
117+ } )
118+ }
119+ }
120+ return tree
121+ }
122+
30123 getTreeNodeByKey ( keypath : string , tree ?: LocaleTree ) : LocaleNode | LocaleTree | undefined {
31124 const root = ! tree
32125 tree = tree || this . root
@@ -50,6 +143,14 @@ export abstract class Loader extends Disposable {
50143 return undefined
51144 }
52145
146+ getFilepathByKey ( key : string , locale ?: string ) {
147+ locale = locale || Config . displayLanguage
148+ const record = this . getRecordByKey ( key , locale )
149+ if ( record && record . filepath )
150+ return record . filepath
151+ return undefined
152+ }
153+
53154 getValueByKey ( keypath : string , locale ?: string , clamp : boolean = true , stringifySpace ?: number ) {
54155 locale = locale || Config . displayLanguage
55156
@@ -135,4 +236,10 @@ export abstract class Loader extends Disposable {
135236 } )
136237 return locales
137238 }
239+
240+ protected onDispose ( ) {
241+ Log . info ( `🗑 Disposing loader "${ this . name } "` )
242+ this . _disposables . forEach ( d => d . dispose ( ) )
243+ this . _disposables = [ ]
244+ }
138245}
0 commit comments