Skip to content

Commit 451f790

Browse files
committed
fix: restore db prompts in init, fix chmod imports, include db in generated config
1 parent dcbdcba commit 451f790

1 file changed

Lines changed: 57 additions & 3 deletions

File tree

src/cli/commands/init.ts

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { writeFile, readFile as readFileNode } from 'node:fs/promises';
1+
import { writeFile, readFile as readFileNode, chmod } from 'node:fs/promises';
22
import { ensureDir, pathExists } from 'fs-extra';
33
import { resolve } from 'path';
44
import { createInterface } from 'readline';
55
import { detectFramework, detectPkgManager } from '../../domain/framework/detector.js';
66
import { isValidIpOrHostname, isValidPort } from '../../domain/validation/ip.js';
77
import { ORM_PATTERNS } from '../../shared/constants.js';
88
import { ui } from '../ui.js';
9+
import type { DatabaseType } from '../../shared/types.js';
910

1011
const rl = createInterface({ input: process.stdin, output: process.stdout });
1112

@@ -83,6 +84,12 @@ export async function cmdInit(cwd: string, options: { nonInteractive?: boolean;
8384
let domain = '';
8485
let zeroDowntime = true;
8586
let healthCheckPath = '/health';
87+
let dbType: DatabaseType | undefined;
88+
let dbHost: string | undefined;
89+
let dbPort: number | undefined;
90+
let dbName: string | undefined;
91+
let dbUser: string | undefined;
92+
let dbPassword: string | undefined;
8693

8794
if (appType === 'backend') {
8895
pm2Name = await ask('PM2 app name', appName);
@@ -93,6 +100,25 @@ export async function cmdInit(cwd: string, options: { nonInteractive?: boolean;
93100
if (zeroDowntime) {
94101
healthCheckPath = await ask('Health check path', '/health');
95102
}
103+
104+
const hasDb = (await ask('Configure a database?', 'no')).toLowerCase().startsWith('y');
105+
if (hasDb) {
106+
const dbTypeRaw = await ask('Database type (postgres/mysql/sqlite/mongodb)', 'postgres');
107+
dbType = (['postgres', 'mysql', 'sqlite', 'mongodb'].includes(dbTypeRaw)
108+
? dbTypeRaw
109+
: 'postgres') as DatabaseType;
110+
111+
if (dbType !== 'sqlite') {
112+
dbHost = await ask('Database host', 'localhost');
113+
const defaultDbPort = dbType === 'postgres' ? '5432' : dbType === 'mysql' ? '3306' : '27017';
114+
dbPort = parseInt(await ask('Database port', defaultDbPort), 10);
115+
dbName = await ask('Database name', appName);
116+
dbUser = await ask('Database user', appName);
117+
dbPassword = await ask('Database password (optional)', '');
118+
} else {
119+
dbName = await ask('SQLite file path', './data.db');
120+
}
121+
}
96122
} else {
97123
domain = await ask('Domain (optional)', '');
98124
}
@@ -112,6 +138,12 @@ export async function cmdInit(cwd: string, options: { nonInteractive?: boolean;
112138
zeroDowntime,
113139
healthCheckPath,
114140
pkgManager: pkgManager ?? undefined,
141+
dbType,
142+
dbHost,
143+
dbPort,
144+
dbName,
145+
dbUser,
146+
dbPassword: dbPassword || undefined,
115147
});
116148

117149
const configPath = resolve(cwd, 'shipnode.config.ts');
@@ -154,6 +186,12 @@ interface ConfigOptions {
154186
zeroDowntime?: boolean;
155187
healthCheckPath?: string;
156188
pkgManager?: string;
189+
dbType?: DatabaseType;
190+
dbHost?: string;
191+
dbPort?: number;
192+
dbName?: string;
193+
dbUser?: string;
194+
dbPassword?: string;
157195
}
158196

159197
async function generateShipnodeDir(cwd: string, detectedOrm?: string): Promise<void> {
@@ -166,12 +204,12 @@ async function generateShipnodeDir(cwd: string, detectedOrm?: string): Promise<v
166204

167205
if (!(await pathExists(preDeployPath))) {
168206
await writeFile(preDeployPath, generatePreDeployHook(detectedOrm), 'utf-8');
169-
await import('fs/promises').then((fs) => fs.chmod(preDeployPath, 0o755));
207+
await chmod(preDeployPath, 0o755);
170208
}
171209

172210
if (!(await pathExists(postDeployPath))) {
173211
await writeFile(postDeployPath, generatePostDeployHook(), 'utf-8');
174-
await import('fs/promises').then((fs) => fs.chmod(postDeployPath, 0o755));
212+
await chmod(postDeployPath, 0o755);
175213
}
176214

177215
if (!(await pathExists(ignorePath))) {
@@ -293,6 +331,22 @@ function generateConfig(opts: ConfigOptions): string {
293331
lines.push(` .pkgManager('${opts.pkgManager}')`);
294332
}
295333

334+
if (opts.dbType) {
335+
if (opts.dbType === 'sqlite') {
336+
lines.push(` .database({ type: 'sqlite', host: 'localhost', port: 0, name: '${opts.dbName ?? './data.db'}', user: '' })`);
337+
} else {
338+
const dbOpts = [
339+
`type: '${opts.dbType}'`,
340+
`host: '${opts.dbHost ?? 'localhost'}'`,
341+
`port: ${opts.dbPort ?? 5432}`,
342+
`name: '${opts.dbName ?? ''}'`,
343+
`user: '${opts.dbUser ?? ''}'`,
344+
...(opts.dbPassword ? [`password: process.env.DB_PASSWORD ?? '${opts.dbPassword}'`] : [`// password: process.env.DB_PASSWORD`]),
345+
];
346+
lines.push(` .database({ ${dbOpts.join(', ')} })`);
347+
}
348+
}
349+
296350
lines.push(' .build();');
297351
lines.push('');
298352
return lines.join('\n');

0 commit comments

Comments
 (0)