import type { DriverId } from "./catalog"; import { driverById } from "./catalog"; const PROTO: Record = { mysql: "mysql", mariadb: "mariadb", postgres: "postgresql", postgresql: "postgresql", redis: "redis", sqlite: "sqlite", file: "sqlite", sqlserver: "sqlserver", mssql: "sqlserver", oracle: "oracle", tidb: "tidb", mongodb: "mongodb", mongo: "mongodb", oceanbase: "oceanbase", gaussdb: "gaussdb", opengauss: "gaussdb", polardb: "polardb", tdsql: "tdsql", kingbase: "kingbase", dameng: "dameng", }; export type ParsedDSN = { driver: DriverId; host?: string; port?: number; user?: string; password?: string; database?: string; ssl?: boolean; }; /** 粘贴 mysql:// / postgres:// / redis:// / sqlite: 路径即可拆字段 */ export function parseDSN(raw: string): ParsedDSN | null { const s = raw.trim(); if (!s) return null; if (/^[a-zA-Z]:[\\/]/.test(s) || s.startsWith("/") || s.endsWith(".db") || s.endsWith(".sqlite")) { return { driver: "sqlite", database: s }; } try { const u = new URL(s.includes("://") ? s : `mysql://${s}`); const proto = u.protocol.replace(":", "").toLowerCase(); const driver = PROTO[proto]; if (!driver) return null; const database = decodeURIComponent(u.pathname.replace(/^\/+/, "")); const port = u.port ? Number(u.port) : driverById(driver)?.defaultPort; const ssl = u.searchParams.get("sslmode") === "require" || u.searchParams.get("ssl") === "true"; return { driver, host: u.hostname || undefined, port: port || undefined, user: decodeURIComponent(u.username || "") || undefined, password: decodeURIComponent(u.password || "") || undefined, database: database || undefined, ssl, }; } catch { return null; } }