65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
import type { DriverId } from "./catalog";
|
|
import { driverById } from "./catalog";
|
|
|
|
const PROTO: Record<string, DriverId> = {
|
|
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;
|
|
}
|
|
}
|