Skip to content

Commit fd37e0d

Browse files
authored
Merge pull request #3977 from 0xbbjoker/0xbbjoker/fix-postgres-url-persistence
fix: store postgres connection URL properly in global config
2 parents 56d96f7 + 5b37c6b commit fd37e0d

File tree

1 file changed

+94
-7
lines changed

1 file changed

+94
-7
lines changed

packages/cli/src/commands/create.ts

+94-7
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,99 @@ async function installDependencies(targetDir: string) {
7979
}
8080
}
8181

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 = /^postgresql:\/\/[^:]+:[^@]+@[^:]+:\d+\/\w+$/;
110+
111+
// More permissive pattern (allows missing password, different formats)
112+
const permissivePattern = /^postgresql:\/\/.*@.*:\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+
82175
/**
83176
* Initialize a new project or plugin.
84177
*
@@ -288,13 +381,7 @@ export const create = new Command()
288381
}
289382

290383
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();
298385
}
299386

300387
// Set up src directory

0 commit comments

Comments
 (0)