@@ -79,6 +79,99 @@ async function installDependencies(targetDir: string) {
79
79
}
80
80
}
81
81
82
+ /**
83
+ * Stores Postgres URL in the global .env file
84
+ * @param url The Postgres URL to store
85
+ */
86
+ async function storePostgresUrl ( url : string ) : Promise < void > {
87
+ if ( ! url ) return ;
88
+
89
+ try {
90
+ const homeDir = os . homedir ( ) ;
91
+ const globalEnvPath = path . join ( homeDir , '.eliza' , '.env' ) ;
92
+
93
+ await fs . writeFile ( globalEnvPath , `POSTGRES_URL=${ url } \n` , { flag : 'a' } ) ;
94
+ logger . success ( 'Postgres URL saved to configuration' ) ;
95
+ } catch ( error ) {
96
+ logger . warn ( 'Error saving database configuration:' , error ) ;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Validates a Postgres URL format
102
+ * @param url The URL to validate
103
+ * @returns True if the URL appears valid
104
+ */
105
+ function isValidPostgresUrl ( url : string ) : boolean {
106
+ if ( ! url ) return false ;
107
+
108
+ // Basic pattern: postgresql://user:password@host :port/dbname
109
+ const basicPattern = / ^ p o s t g r e s q l : \/ \/ [ ^ : ] + : [ ^ @ ] + @ [ ^ : ] + : \d + \/ \w + $ / ;
110
+
111
+ // More permissive pattern (allows missing password, different formats)
112
+ const permissivePattern = / ^ p o s t g r e s q l : \/ \/ .* @ .* : \d + \/ .* $ / ;
113
+
114
+ return basicPattern . test ( url ) || permissivePattern . test ( url ) ;
115
+ }
116
+
117
+ /**
118
+ * Prompts the user for a Postgres URL, validates it, and stores it
119
+ * @returns The configured Postgres URL or null if user skips
120
+ */
121
+ async function promptAndStorePostgresUrl ( ) : Promise < string | null > {
122
+ let isValidUrl = false ;
123
+ let userUrl = '' ;
124
+
125
+ while ( ! isValidUrl ) {
126
+ // Prompt for postgres url with simpler message
127
+ const reply = await prompts ( {
128
+ type : 'text' ,
129
+ name : 'postgresUrl' ,
130
+ message : 'Enter your Postgres URL:' ,
131
+ validate : ( value ) => value . trim ( ) !== '' || 'Postgres URL cannot be empty' ,
132
+ } ) ;
133
+
134
+ // Handle cancellation
135
+ if ( ! reply . postgresUrl ) {
136
+ const { continueAnyway } = await prompts ( {
137
+ type : 'confirm' ,
138
+ name : 'continueAnyway' ,
139
+ message : 'Continue without configuring Postgres?' ,
140
+ initial : false ,
141
+ } ) ;
142
+
143
+ if ( continueAnyway ) return null ;
144
+ continue ;
145
+ }
146
+
147
+ userUrl = reply . postgresUrl ;
148
+
149
+ // Validate URL format
150
+ if ( ! isValidPostgresUrl ( userUrl ) ) {
151
+ logger . warn ( "The URL format doesn't appear to be valid." ) ;
152
+ logger . info ( 'Expected format: postgresql://user:password@host:port/dbname' ) ;
153
+
154
+ const { useAnyway } = await prompts ( {
155
+ type : 'confirm' ,
156
+ name : 'useAnyway' ,
157
+ message : 'Use this URL anyway? (Choose Yes if you have a custom setup)' ,
158
+ initial : false ,
159
+ } ) ;
160
+
161
+ if ( ! useAnyway ) continue ;
162
+ }
163
+
164
+ isValidUrl = true ;
165
+ }
166
+
167
+ if ( userUrl ) {
168
+ await storePostgresUrl ( userUrl ) ;
169
+ return userUrl ;
170
+ }
171
+
172
+ return null ;
173
+ }
174
+
82
175
/**
83
176
* Initialize a new project or plugin.
84
177
*
@@ -288,13 +381,7 @@ export const create = new Command()
288
381
}
289
382
290
383
if ( database === 'postgres' && ! postgresUrl ) {
291
- // prompt for postgres url
292
- const reply = await prompts ( {
293
- type : 'text' ,
294
- name : 'postgresUrl' ,
295
- message : 'Enter your postgres url' ,
296
- } ) ;
297
- postgresUrl = reply . postgresUrl ;
384
+ postgresUrl = await promptAndStorePostgresUrl ( ) ;
298
385
}
299
386
300
387
// Set up src directory
0 commit comments