import * as Hapi from "@hapi/hapi"; import pgPromise from "pg-promise"; import 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.js"; import { Plugin } from "@hapi/hapi/lib/types/plugin"; export * from "./types.js"; 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; }; export function makePlugin(): Plugin, void> { return { version: "1.0.0", name: "pg-promise", async register( server: Hapi.Server, userOpts?: IPGPPluginOptions ): Promise { if (userOpts.logSql === undefined) userOpts.logSql = false; if (!userOpts.decorateAs) userOpts.decorateAs = { pgp: "pgp", db: "db" }; const options = userOpts; 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(); }); }, }; }