UNPKG

@devotis/bouquet

Version:

A bouquet of little functions, wrappers and libraries that I use across projects and clients 💐

111 lines (97 loc) 3.43 kB
require('dotenv').config(); const sql = require('pg-sql2'); const url = require('url'); const valueSafeForSet = (value) => value == null // of undefined dus ? '' : typeof value === 'object' ? JSON.stringify(value) : value; const getPgSettingsFromReq = ( req, reqParts = ['headers', 'user', 'query', 'session'], getRole, defaultSettings = {} ) => { const settings = { role: typeof getRole === 'string' ? getRole : getRole(req), ...defaultSettings, }; reqParts.forEach((part) => { const value = part === 'fullUrl' ? url.format({ protocol: req.protocol, host: req.get('host'), pathname: req.originalUrl, }) : req[part]; const valueType = typeof value; if (valueType === 'string' || valueType === 'boolean') { settings[`request.${part}`] = value; return; } if (part === 'session') { // because session.id is not found via Object.entries settings[`request.session.id`] = valueSafeForSet(req.sessionID); } Object.entries(value || {}).forEach(([key, value]) => { settings[ `request.${part.replace('headers', 'header')}.${key}` ] = valueSafeForSet(value); }); }); return settings; }; const getSettingsForPgClientTransaction = ({ pgSettings }) => { let role, localSettings = []; if (pgSettings && typeof pgSettings === 'object') { for (const key in pgSettings) { if ( Object.prototype.hasOwnProperty.call(pgSettings, key) // && isPgSettingValid(pgSettings[key]) ) { if (key === 'role') { role = pgSettings[key]; } else { localSettings.push([key, pgSettings[key]]); } } } } return { role, localSettings }; }; // compiled from https://github.com/graphile/postgraphile/blob/51bd1dc96de194f75fdb1759e0ce9f555b2cf82b/src/postgraphile/withPostGraphileContext.ts const getSqlSettingsQuery = (localSettings) => { const sqlSettings = []; if (!localSettings.length) return null; // Later settings should win, so we're going to loop backwards and not // add settings for keys we've already seen. const seenKeys = []; // TODO:perf: looping backwards is slow for (let i = localSettings.length - 1; i >= 0; i--) { const [key, value] = localSettings[i]; if (!seenKeys.includes(key)) { seenKeys.push(key); // Make sure that the third config is always `true` so that we are only // ever setting variables on the transaction. // Also, we're using `unshift` to undo the reverse-looping we're doing sqlSettings.unshift( sql.fragment`set_config(${sql.value(key)}, ${sql.value( value )}, true)` ); } } const sqlSettingsQuery = sqlSettings.length > 0 ? sql.compile(sql.query`select ${sql.join(sqlSettings, ', ')}`) : null; return sqlSettingsQuery; }; module.exports = { getSqlSettingsQuery, getPgSettingsFromReq, getSettingsForPgClientTransaction, };