@@ -2,25 +2,10 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
22import os from 'node:os'
33import path from 'node:path'
44
5- import { Spinner } from '@socketsecurity/registry/lib/spinner'
5+ import { logger } from './logger'
6+ import constants from '../constants'
67
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'
249
2510interface Settings {
2611 apiKey ?: string | null
@@ -29,40 +14,85 @@ interface Settings {
2914 apiProxy ?: string | null
3015}
3116
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+ }
3340
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
4068 }
41- } else {
42- mkdirSync ( path . dirname ( settingsPath ) , { recursive : true } )
69+ return _settingsPath
4370}
4471
4572export function getSetting < Key extends keyof Settings > (
4673 key : Key
4774) : Settings [ Key ] {
48- return settings [ key ]
75+ return getSettings ( ) [ key ]
4976}
5077
5178let pendingSave = false
52-
5379export function updateSetting < Key extends keyof Settings > (
5480 key : Key ,
5581 value : Settings [ Key ]
5682) : void {
83+ const settings = getSettings ( )
5784 settings [ key ] = value
5885 if ( ! pendingSave ) {
5986 pendingSave = true
6087 process . nextTick ( ( ) => {
6188 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+ }
6696 } )
6797 }
6898}
0 commit comments