import { parseDsn } from "./utils.ts";
export type ConnectionString = string;
function getPgEnv(): ConnectionOptions { return { database: Deno.env.get("PGDATABASE"), hostname: Deno.env.get("PGHOST"), port: Deno.env.get("PGPORT"), user: Deno.env.get("PGUSER"), password: Deno.env.get("PGPASSWORD"), applicationName: Deno.env.get("PGAPPNAME"), };}
export class ConnectionParamsError extends Error { constructor(message: string) { super(message); this.name = "ConnectionParamsError"; }}
export interface ConnectionOptions { applicationName?: string; database?: string; hostname?: string; password?: string; port?: string | number; user?: string;}
export interface ConnectionParams { applicationName: string; database: string; hostname: string; password?: string; port: number; user: string;}
function formatMissingParams(missingParams: string[]) { return `Missing connection parameters: ${ missingParams.join( ", ", ) }`;}
function assertRequiredOptions( options: ConnectionOptions, requiredKeys: (keyof ConnectionOptions)[], has_env_access: boolean,) { const missingParams: (keyof ConnectionOptions)[] = []; for (const key of requiredKeys) { if ( options[key] === "" || options[key] === null || options[key] === undefined ) { missingParams.push(key); } }
if (missingParams.length) { let missing_params_message = formatMissingParams(missingParams); if (!has_env_access) { missing_params_message += "\nConnection parameters can be read from environment variables only if Deno is run with env permission"; }
throw new ConnectionParamsError(missing_params_message); }}
function parseOptionsFromDsn(connString: string): ConnectionOptions { const dsn = parseDsn(connString);
if (dsn.driver !== "postgres") { throw new ConnectionParamsError( `Supplied DSN has invalid driver: ${dsn.driver}.`, ); }
return { ...dsn, applicationName: dsn.params.application_name, };}
const DEFAULT_OPTIONS = { hostname: "127.0.0.1", port: "5432", applicationName: "deno_postgres",};
export function createParams( params: string | ConnectionOptions = {},): ConnectionParams { if (typeof params === "string") { params = parseOptionsFromDsn(params); }
let pgEnv: ConnectionOptions = {}; let has_env_access = true; try { pgEnv = getPgEnv(); } catch (e) { if (e instanceof Deno.errors.PermissionDenied) { has_env_access = false; } else { throw e; } }
let port: string; if (params.port) { port = String(params.port); } else if (pgEnv.port) { port = String(pgEnv.port); } else { port = DEFAULT_OPTIONS.port; }
const connection_options = { applicationName: params.applicationName ?? pgEnv.applicationName ?? DEFAULT_OPTIONS.applicationName, database: params.database ?? pgEnv.database, hostname: params.hostname ?? pgEnv.hostname ?? DEFAULT_OPTIONS.hostname, password: params.password ?? pgEnv.password, port, user: params.user ?? pgEnv.user, };
assertRequiredOptions( connection_options, ["database", "hostname", "port", "user", "applicationName"], has_env_access, );
const connection_parameters: ConnectionParams = { ...connection_options, database: connection_options.database as string, port: parseInt(connection_options.port, 10), user: connection_options.user as string, };
if (isNaN(connection_parameters.port)) { throw new ConnectionParamsError( `Invalid port ${connection_parameters.port}`, ); }
return connection_parameters;}