| 40 | } |
| 41 | |
| 42 | function parseConn(connStr: string): ParsedConn | null { |
| 43 | if (connStr.startsWith('sqlite://')) { |
| 44 | const filepath = connStr.replace(/^sqlite:\/\/+/, ''); |
| 45 | return { dialect: 'sqlite', filepath: filepath.startsWith('/') ? filepath : filepath }; |
| 46 | } |
| 47 | try { |
| 48 | const u = new URL(connStr); |
| 49 | const dialect: Dialect = u.protocol === 'mysql:' ? 'mysql' |
| 50 | : u.protocol === 'postgres:' || u.protocol === 'postgresql:' ? 'postgres' |
| 51 | : (() => { throw new Error('Unknown dialect'); })(); |
| 52 | return { |
| 53 | dialect, |
| 54 | host: u.hostname || 'localhost', |
| 55 | port: u.port ? parseInt(u.port, 10) : (dialect === 'mysql' ? 3306 : 5432), |
| 56 | user: decodeURIComponent(u.username || ''), |
| 57 | password: decodeURIComponent(u.password || ''), |
| 58 | database: u.pathname ? u.pathname.replace(/^\//, '') : undefined, |
| 59 | }; |
| 60 | } catch { |
| 61 | return null; |
| 62 | } |
| 63 | } |
| 64 | |
| 65 | async function getConnection(parsed: ParsedConn): Promise<{ kind: Dialect; conn: any } | { kind: 'error'; message: string }> { |
| 66 | if (parsed.dialect === 'mysql') { |