@@ -2,12 +2,58 @@ import { existsSync, readFileSync } from 'node:fs'
22import { join } from 'node:path'
33import { homedir } from 'node:os'
44
5+ // Settings interface supporting both nested (v2) and flat (legacy) formats
56interface Settings {
7+ _schemaVersion ?: number
8+ // Nested format (v2)
9+ server ?: { port ?: number }
10+ authentication ?: { username ?: string | null ; password ?: string | null }
11+ // Legacy flat format
612 port ?: number
713 basicAuthUsername ?: string
814 basicAuthPassword ?: string
915}
1016
17+ const DEFAULT_PORT = 7777
18+
19+ /**
20+ * Get port from settings (supports nested and flat formats)
21+ */
22+ function getPortFromSettings ( settings : Settings | null ) : number | null {
23+ if ( ! settings ) return null
24+ // Try nested format first (v2)
25+ if ( settings . server ?. port ) {
26+ return settings . server . port
27+ }
28+ // Fall back to flat format (legacy)
29+ if ( settings . port ) {
30+ return settings . port
31+ }
32+ return null
33+ }
34+
35+ /**
36+ * Get auth credentials from settings (supports nested and flat formats)
37+ */
38+ function getAuthFromSettings ( settings : Settings | null ) : { username : string ; password : string } | null {
39+ if ( ! settings ) return null
40+ // Try nested format first (v2)
41+ if ( settings . authentication ?. username && settings . authentication ?. password ) {
42+ return {
43+ username : settings . authentication . username ,
44+ password : settings . authentication . password ,
45+ }
46+ }
47+ // Fall back to flat format (legacy)
48+ if ( settings . basicAuthUsername && settings . basicAuthPassword ) {
49+ return {
50+ username : settings . basicAuthUsername ,
51+ password : settings . basicAuthPassword ,
52+ }
53+ }
54+ return null
55+ }
56+
1157function expandPath ( p : string ) : string {
1258 if ( p . startsWith ( '~/' ) ) {
1359 return join ( homedir ( ) , p . slice ( 2 ) )
@@ -36,7 +82,7 @@ function readSettingsFile(path: string): Settings | null {
3682 * 4. VIBORA_DIR settings.json (read port)
3783 * 5. .vibora/settings.json in CWD (read port)
3884 * 6. ~/.vibora/settings.json (read port)
39- * 7. Default: http://localhost:3333
85+ * 7. Default: http://localhost:7777
4086 */
4187export function discoverServerUrl ( urlOverride ?: string , portOverride ?: string ) : string {
4288 // 1. Explicit URL override
@@ -58,27 +104,30 @@ export function discoverServerUrl(urlOverride?: string, portOverride?: string):
58104 if ( process . env . VIBORA_DIR ) {
59105 const viboraDirSettings = join ( expandPath ( process . env . VIBORA_DIR ) , 'settings.json' )
60106 const settings = readSettingsFile ( viboraDirSettings )
61- if ( settings ?. port ) {
62- return `http://localhost:${ settings . port } `
107+ const port = getPortFromSettings ( settings )
108+ if ( port ) {
109+ return `http://localhost:${ port } `
63110 }
64111 }
65112
66113 // 5. Local .vibora/settings.json
67114 const cwdSettings = join ( process . cwd ( ) , '.vibora' , 'settings.json' )
68115 const localSettings = readSettingsFile ( cwdSettings )
69- if ( localSettings ?. port ) {
70- return `http://localhost:${ localSettings . port } `
116+ const localPort = getPortFromSettings ( localSettings )
117+ if ( localPort ) {
118+ return `http://localhost:${ localPort } `
71119 }
72120
73121 // 6. Global ~/.vibora/settings.json
74122 const globalSettings = join ( homedir ( ) , '.vibora' , 'settings.json' )
75123 const homeSettings = readSettingsFile ( globalSettings )
76- if ( homeSettings ?. port ) {
77- return `http://localhost:${ homeSettings . port } `
124+ const homePort = getPortFromSettings ( homeSettings )
125+ if ( homePort ) {
126+ return `http://localhost:${ homePort } `
78127 }
79128
80129 // 7. Default
81- return ' http://localhost:3333'
130+ return ` http://localhost:${ DEFAULT_PORT } `
82131}
83132
84133/**
@@ -101,6 +150,7 @@ export function getViboraDir(): string {
101150
102151/**
103152 * Gets auth credentials from settings.json.
153+ * Supports both nested (v2) and flat (legacy) formats.
104154 * Priority: VIBORA_DIR → CWD .vibora → ~/.vibora
105155 * Returns null if no credentials are configured.
106156 */
@@ -113,11 +163,9 @@ export function getAuthCredentials(): { username: string; password: string } | n
113163
114164 for ( const path of settingsPaths ) {
115165 const settings = readSettingsFile ( path )
116- if ( settings ?. basicAuthUsername && settings ?. basicAuthPassword ) {
117- return {
118- username : settings . basicAuthUsername ,
119- password : settings . basicAuthPassword ,
120- }
166+ const auth = getAuthFromSettings ( settings )
167+ if ( auth ) {
168+ return auth
121169 }
122170 }
123171
0 commit comments