@@ -4,12 +4,12 @@ const yaml = require('js-yaml');
4
4
const { app } = require ( '@electron/remote' ) ;
5
5
const path = require ( 'path' ) ;
6
6
7
- class config {
7
+ class Config {
8
8
static instance = null ;
9
9
10
10
constructor ( ) {
11
- if ( config . instance ) {
12
- return config . instance ;
11
+ if ( Config . instance ) {
12
+ return Config . instance ;
13
13
}
14
14
15
15
this . default_config = { } ;
@@ -23,15 +23,15 @@ class config {
23
23
this . readConfigYaml ( ) ;
24
24
this . checkConfigVersion ( ) ;
25
25
26
- config . instance = this ;
26
+ Config . instance = this ;
27
27
}
28
28
29
29
static getInstance ( ) {
30
- if ( ! config . instance ) {
31
- new config ( ) ;
30
+ if ( ! Config . instance ) {
31
+ new Config ( ) ;
32
32
}
33
33
34
- return config . instance ;
34
+ return Config . instance ;
35
35
}
36
36
37
37
checkConfigExists ( ) {
@@ -50,47 +50,116 @@ class config {
50
50
this . config = yaml . load ( raw ) ;
51
51
}
52
52
53
+ writeConfig ( config = this . config ) {
54
+ logger . debug ( 'Writing config:' , JSON . stringify ( config , null , 2 ) ) ;
55
+
56
+ const lines = [ ] ;
57
+ let configContent = fs . readFileSync ( this . defaultDir , 'utf8' ) ;
58
+ const templateLines = configContent . split ( '\n' ) ;
59
+ let currentKey = '' ;
60
+
61
+ for ( const line of templateLines ) {
62
+ const keyMatch = line . match ( / ^ ( \w + ) : | ^ ( [ \w - ] + ) : / ) ;
63
+ const indentedKeyMatch = line . match ( / ^ \s + ( \w + ) : | ^ \s + ( [ \w - ] + ) : / ) ;
64
+
65
+ if ( keyMatch ) {
66
+ currentKey = keyMatch [ 1 ] || keyMatch [ 2 ] ;
67
+ const value = config [ currentKey ] ;
68
+ logger . debug ( `Processing key: ${ currentKey } , value:` , value ) ;
69
+
70
+ if ( typeof value === 'object' && value !== null && ! Array . isArray ( value ) ) {
71
+ lines . push ( `${ currentKey } :` ) ;
72
+ }
73
+ else {
74
+ lines . push ( `${ currentKey } : ${ value } ` ) ;
75
+ }
76
+ }
77
+ else if ( indentedKeyMatch && currentKey ) {
78
+ const subKey = indentedKeyMatch [ 1 ] || indentedKeyMatch [ 2 ] ;
79
+ if (
80
+ config [ currentKey ]
81
+ && typeof config [ currentKey ] [ subKey ] !== 'undefined'
82
+ ) {
83
+ const value = config [ currentKey ] [ subKey ] ;
84
+ const comment = line . includes ( '#' ) ? ' #' + line . split ( '#' ) [ 1 ] : '' ;
85
+ lines . push ( ` ${ subKey } : ${ value } ${ comment } ` ) ;
86
+ logger . debug ( `Processing subkey: ${ currentKey } .${ subKey } , value:` , value ) ;
87
+ }
88
+ }
89
+ else {
90
+ lines . push ( line ) ;
91
+ }
92
+ }
93
+
94
+ configContent = lines . join ( '\n' ) ;
95
+ logger . debug ( 'New content to write:' , configContent ) ;
96
+
97
+ try {
98
+ const dir = path . dirname ( this . configDir ) ;
99
+ if ( ! fs . existsSync ( dir ) ) {
100
+ fs . mkdirSync ( dir , { recursive : true } ) ;
101
+ }
102
+
103
+ fs . writeFileSync ( this . configDir , configContent , 'utf8' ) ;
104
+ logger . info ( 'Config has been saved to file' ) ;
105
+ }
106
+ catch ( error ) {
107
+ logger . error ( 'Failed to write config:' , error ) ;
108
+ }
109
+
110
+ this . config = config ;
111
+ }
112
+
53
113
checkConfigVersion ( ) {
54
114
if ( this . default_config . ver > ( this . config ?. ver ?? 0 ) ) {
55
115
logger . warn ( `Updating config from version ${ this . config ?. ver ?? 0 } to ${ this . default_config . ver } ` ) ;
56
116
57
- const existingValues = { ...this . config } ;
58
-
59
117
let configContent = fs . readFileSync ( this . defaultDir , 'utf8' ) ;
60
118
const lines = configContent . split ( '\n' ) ;
61
119
const newLines = [ ] ;
62
120
let currentKey = '' ;
63
121
122
+ const newConfig = JSON . parse ( JSON . stringify ( this . default_config ) ) ;
123
+ for ( const key in this . config ) {
124
+ if ( this . config [ key ] !== null && this . config [ key ] !== undefined ) {
125
+ if ( typeof this . config [ key ] === 'object' && ! Array . isArray ( this . config [ key ] ) ) {
126
+ newConfig [ key ] = {
127
+ ...newConfig [ key ] ,
128
+ ...this . config [ key ] ,
129
+ } ;
130
+ }
131
+ else {
132
+ newConfig [ key ] = this . config [ key ] ;
133
+ }
134
+ }
135
+ }
136
+
137
+ newConfig . ver = this . default_config . ver ;
138
+
64
139
for ( const line of lines ) {
65
140
const keyMatch = line . match ( / ^ ( \w + ) : | ^ ( [ \w - ] + ) : / ) ;
66
- const indentedKeyMatch = line . match ( / ^ \s + ( \w + ) : / ) ;
141
+ const indentedKeyMatch = line . match ( / ^ \s + ( \w + ) : | ^ \s + ( [ \w - ] + ) : / ) ;
67
142
68
143
if ( keyMatch ) {
69
144
currentKey = keyMatch [ 1 ] || keyMatch [ 2 ] ;
145
+ const value = newConfig [ currentKey ] ;
70
146
71
- if ( currentKey === 'ver' ) {
72
- newLines . push ( `ver: ${ this . default_config . ver } ` ) ;
73
- }
74
- else if ( existingValues [ currentKey ] !== undefined ) {
75
- const value = existingValues [ currentKey ] ;
76
- if ( typeof value === 'object' && value !== null && ! Array . isArray ( value ) ) {
77
- newLines . push ( `${ currentKey } :` ) ;
78
- }
79
- else {
80
- newLines . push ( `${ currentKey } : ${ value } ` ) ;
81
- }
147
+ if ( typeof value === 'object' && value !== null && ! Array . isArray ( value ) ) {
148
+ newLines . push ( `${ currentKey } :` ) ;
82
149
}
83
150
else {
84
- newLines . push ( line ) ;
151
+ newLines . push ( ` ${ currentKey } : ${ value } ` ) ;
85
152
}
86
153
}
87
154
else if ( indentedKeyMatch && currentKey ) {
88
- const subKey = indentedKeyMatch [ 1 ] ;
89
- if ( existingValues [ currentKey ] ?. [ subKey ] !== undefined ) {
90
- newLines . push ( ` ${ subKey } : ${ existingValues [ currentKey ] [ subKey ] } ` ) ;
91
- }
92
- else {
93
- newLines . push ( line ) ;
155
+ const subKey = indentedKeyMatch [ 1 ] || indentedKeyMatch [ 2 ] ;
156
+ if (
157
+ newConfig [ currentKey ]
158
+ && typeof newConfig [ currentKey ] [ subKey ] !== 'undefined'
159
+ ) {
160
+ const value = newConfig [ currentKey ] [ subKey ] ;
161
+ const comment = line . includes ( '#' ) ? ' #' + line . split ( '#' ) [ 1 ] : '' ;
162
+ newLines . push ( ` ${ subKey } : ${ value } ${ comment } ` ) ;
94
163
}
95
164
}
96
165
else {
@@ -107,15 +176,18 @@ class config {
107
176
fs . writeFileSync ( this . configDir , configContent ) ;
108
177
logger . info ( 'Config file updated successfully' ) ;
109
178
110
- this . config = yaml . load ( configContent ) ;
179
+ this . config = newConfig ;
111
180
}
112
181
}
113
182
114
- getConfig ( ) {
183
+ getConfig ( refresh = false ) {
184
+ if ( refresh ) {
185
+ this . readConfigYaml ( ) ;
186
+ }
115
187
return this . config ;
116
188
}
117
189
}
118
190
119
- new config ( ) ;
191
+ new Config ( ) ;
120
192
121
- module . exports = config ;
193
+ module . exports = Config ;
0 commit comments