@@ -2,25 +2,10 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
2
2
import os from 'node:os'
3
3
import path from 'node:path'
4
4
5
- import { Spinner } from '@socketsecurity/registry/lib/spinner'
5
+ import { logger } from './logger'
6
+ import constants from '../constants'
6
7
7
- let dataHome : string | undefined =
8
- process . platform === 'win32'
9
- ? process . env [ 'LOCALAPPDATA' ]
10
- : process . env [ 'XDG_DATA_HOME' ]
11
-
12
- if ( ! dataHome ) {
13
- if ( process . platform === 'win32' ) throw new Error ( 'missing %LOCALAPPDATA%' )
14
- const home = os . homedir ( )
15
- dataHome = path . join (
16
- home ,
17
- ...( process . platform === 'darwin'
18
- ? [ 'Library' , 'Application Support' ]
19
- : [ '.local' , 'share' ] )
20
- )
21
- }
22
-
23
- const settingsPath = path . join ( dataHome , 'socket' , 'settings' )
8
+ const LOCALAPPDATA = 'LOCALAPPDATA'
24
9
25
10
interface Settings {
26
11
apiKey ?: string | null
@@ -29,40 +14,85 @@ interface Settings {
29
14
apiProxy ?: string | null
30
15
}
31
16
32
- let settings : Settings = { }
17
+ let _settings : Settings | undefined
18
+ function getSettings ( ) : Settings {
19
+ if ( _settings === undefined ) {
20
+ _settings = < Settings > { }
21
+ const settingsPath = getSettingsPath ( )
22
+ if ( settingsPath ) {
23
+ if ( existsSync ( settingsPath ) ) {
24
+ const raw = readFileSync ( settingsPath , 'utf8' )
25
+ try {
26
+ Object . assign (
27
+ _settings ,
28
+ JSON . parse ( Buffer . from ( raw , 'base64' ) . toString ( ) )
29
+ )
30
+ } catch {
31
+ logger . warn ( `Failed to parse settings at ${ settingsPath } ` )
32
+ }
33
+ } else {
34
+ mkdirSync ( path . dirname ( settingsPath ) , { recursive : true } )
35
+ }
36
+ }
37
+ }
38
+ return _settings
39
+ }
33
40
34
- if ( existsSync ( settingsPath ) ) {
35
- const raw = readFileSync ( settingsPath , 'utf8' )
36
- try {
37
- settings = JSON . parse ( Buffer . from ( raw , 'base64' ) . toString ( ) )
38
- } catch {
39
- new Spinner ( ) . warning ( `Failed to parse settings at ${ settingsPath } ` )
41
+ let _settingsPath : string | undefined
42
+ let _warnedSettingPathWin32Missing = false
43
+ function getSettingsPath ( ) : string | undefined {
44
+ if ( _settingsPath === undefined ) {
45
+ // Lazily access constants.WIN32.
46
+ const { WIN32 } = constants
47
+ let dataHome : string | undefined = WIN32
48
+ ? process . env [ LOCALAPPDATA ]
49
+ : process . env [ 'XDG_DATA_HOME' ]
50
+ if ( ! dataHome ) {
51
+ if ( WIN32 ) {
52
+ if ( ! _warnedSettingPathWin32Missing ) {
53
+ _warnedSettingPathWin32Missing = true
54
+ logger . warn ( `Missing %${ LOCALAPPDATA } %` )
55
+ }
56
+ } else {
57
+ dataHome = path . join (
58
+ os . homedir ( ) ,
59
+ ...( process . platform === 'darwin'
60
+ ? [ 'Library' , 'Application Support' ]
61
+ : [ '.local' , 'share' ] )
62
+ )
63
+ }
64
+ }
65
+ _settingsPath = dataHome
66
+ ? path . join ( dataHome , 'socket' , 'settings' )
67
+ : undefined
40
68
}
41
- } else {
42
- mkdirSync ( path . dirname ( settingsPath ) , { recursive : true } )
69
+ return _settingsPath
43
70
}
44
71
45
72
export function getSetting < Key extends keyof Settings > (
46
73
key : Key
47
74
) : Settings [ Key ] {
48
- return settings [ key ]
75
+ return getSettings ( ) [ key ]
49
76
}
50
77
51
78
let pendingSave = false
52
-
53
79
export function updateSetting < Key extends keyof Settings > (
54
80
key : Key ,
55
81
value : Settings [ Key ]
56
82
) : void {
83
+ const settings = getSettings ( )
57
84
settings [ key ] = value
58
85
if ( ! pendingSave ) {
59
86
pendingSave = true
60
87
process . nextTick ( ( ) => {
61
88
pendingSave = false
62
- writeFileSync (
63
- settingsPath ,
64
- Buffer . from ( JSON . stringify ( settings ) ) . toString ( 'base64' )
65
- )
89
+ const settingsPath = getSettingsPath ( )
90
+ if ( settingsPath ) {
91
+ writeFileSync (
92
+ settingsPath ,
93
+ Buffer . from ( JSON . stringify ( settings ) ) . toString ( 'base64' )
94
+ )
95
+ }
66
96
} )
67
97
}
68
98
}
0 commit comments