import * as Hapi from "@hapi/hapi"; import * as Hoek from "@hapi/hoek"; import pgPromise from "pg-promise"; import * as pgMonitor from "pg-monitor"; import type { IConnectionParameters } from "pg-promise/typescript/pg-subset"; import type { IMain, IInitOptions } from "pg-promise"; import { IPGPPluginOptions, ExtendedProtocol } from "./types"; export * from "./types"; const defaultOptions: IPGPPluginOptions = { connection: undefined, pgpInit: {}, logSql: false, decorateAs: { pgp: "pgp", db: "db", }, }; export const startDiagnostics = ( logSql: boolean, initOpts: IInitOptions ): void => { if (logSql) { pgMonitor.attach(initOpts); } else { pgMonitor.attach(initOpts, ["error"]); } }; export const stopDiagnostics = (): void => pgMonitor.detach(); const startPgp = async (initOptions: IInitOptions): Promise => { const pgp: IMain = pgPromise(initOptions); return pgp; }; const startDb = async ( pgp, connection: string | IConnectionParameters ): Promise> => { const db: ExtendedProtocol = pgp(connection); return db; }; const register = async ( server: Hapi.Server, userOpts?: IPGPPluginOptions ): Promise => { const options: IPGPPluginOptions = Hoek.applyToDefaults( defaultOptions, userOpts ) as IPGPPluginOptions; if (!options.connection) { throw new Error( "hapi-pg-promise: connection details are not defined. You must specify a valid connection for the plugin to boot." ); } if ("pgp" in options && "pgpInit" in options) { throw new Error( "hapi-pg-promise: options pgp and pgpInit are mutually exclusive" ); } let pgp: IMain; if ("pgp" in options) { pgp = options.pgp; } else { pgp = await startPgp(options.pgpInit); startDiagnostics(options.logSql, options.pgpInit); } const db = await startDb(pgp, options.connection); if (options.decorateAs) { if (options.decorateAs) { server.decorate("request", options.decorateAs.pgp, pgp); server.decorate("server", options.decorateAs.pgp, pgp); } if (options.decorateAs.db) { server.decorate("server", options.decorateAs.db, () => db); server.decorate("request", options.decorateAs.db, () => db); } } server.ext("onPostStop", async () => { stopDiagnostics(); await db.$pool.end(); }); }; const pgPromisePlugin = { register, name: "pg-promise", version: "0.0.1", }; export default pgPromisePlugin;