UNPKG

graphile-build-pg

Version:

Build a GraphQL schema by reflection over a PostgreSQL schema. Easy to customize since it's built with plugins on graphile-build

95 lines (92 loc) 3.59 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getPgClientAndReleaserFromConfig = exports.default = void 0; exports.quacksLikePgPool = quacksLikePgPool; var _pg = _interopRequireDefault(require("pg")); var _debug = _interopRequireDefault(require("debug")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } const debug = (0, _debug.default)("graphile-build-pg"); function constructorName(obj) { return obj && typeof obj.constructor === "function" && obj.constructor.name; } // Some duck-typing function quacksLikePgClient(pgConfig) { // A diagnosis of exclusion if (!pgConfig || typeof pgConfig !== "object") return false; if (constructorName(pgConfig) !== "Client") return false; if (typeof pgConfig.connect !== "function") return false; if (typeof pgConfig.end !== "function") return false; if (typeof pgConfig.escapeLiteral !== "function") return false; if (typeof pgConfig.escapeIdentifier !== "function") return false; return true; } function quacksLikePgPool(pgConfig) { // A diagnosis of exclusion if (!pgConfig || typeof pgConfig !== "object") return false; if (constructorName(pgConfig) !== "Pool" && constructorName(pgConfig) !== "BoundPool") { return false; } if (!pgConfig.Client) return false; if (!pgConfig.options) return false; if (typeof pgConfig.connect !== "function") return false; if (typeof pgConfig.end !== "function") return false; if (typeof pgConfig.query !== "function") return false; return true; } const getPgClientAndReleaserFromConfig = async (pgConfig = process.env.DATABASE_URL) => { let releasePgClient = () => {}; let pgClient; if (pgConfig instanceof _pg.default.Client || quacksLikePgClient(pgConfig)) { pgClient = pgConfig; if (!pgClient.release) { throw new Error("We only support PG clients from a PG pool (because otherwise the `await` call can hang indefinitely if an error occurs and there's no error handler)"); } } else if (pgConfig instanceof _pg.default.Pool || quacksLikePgPool(pgConfig)) { const pgPool = pgConfig; pgClient = await pgPool.connect(); releasePgClient = () => pgClient.release(); } else if (pgConfig === undefined || typeof pgConfig === "string") { pgClient = new _pg.default.Client(pgConfig); pgClient.on("error", e => { debug("pgClient error occurred: %s", e); }); releasePgClient = () => new Promise((resolve, reject) => pgClient.end(err => err ? reject(err) : resolve())); await new Promise((resolve, reject) => pgClient.connect(err => err ? reject(err) : resolve())); } else { throw new Error("You must provide either a pg.Pool or pg.Client instance or a PostgreSQL connection string."); } return { pgClient, releasePgClient }; }; exports.getPgClientAndReleaserFromConfig = getPgClientAndReleaserFromConfig; const withPgClient = async (pgConfig, fn) => { if (!fn) { throw new Error("Nothing to do!"); } const { pgClient, releasePgClient } = await getPgClientAndReleaserFromConfig(pgConfig); const errorHandler = e => { // eslint-disable-next-line no-console console.error("withPgClient client error:", e.message); }; pgClient.on("error", errorHandler); try { return await fn(pgClient); } finally { pgClient.removeListener("error", errorHandler); try { await releasePgClient(); } catch (e) { // Failed to release, assuming success } } }; var _default = withPgClient; exports.default = _default; //# sourceMappingURL=withPgClient.js.map