mirror of
https://github.com/brianc/node-postgres.git
synced 2025-12-08 20:16:25 +00:00
I am running this package using electron, what i noticed was that due to the fact that the lines between node and browser environments become a bit blurred, the URL class that was being used was the one defined by the browser and not node. By making an explicit require it ensures the correct Class is used. While creating a test for this would be difficuilt i think adding an eslint rule to stop using globally defined objects and require imports instead would resolve issues like this in the future
113 lines
3.0 KiB
JavaScript
113 lines
3.0 KiB
JavaScript
'use strict'
|
|
//Parse method copied from https://github.com/brianc/node-postgres
|
|
//Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com)
|
|
//MIT License
|
|
|
|
const { URL } = require('url')
|
|
//parses a connection string
|
|
function parse(str) {
|
|
//unix socket
|
|
if (str.charAt(0) === '/') {
|
|
const config = str.split(' ')
|
|
return { host: config[0], database: config[1] }
|
|
}
|
|
|
|
// Check for empty host in URL
|
|
|
|
const config = {}
|
|
let result
|
|
let dummyHost = false
|
|
if (/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) {
|
|
// Ensure spaces are encoded as %20
|
|
str = encodeURI(str).replace(/\%25(\d\d)/g, '%$1')
|
|
}
|
|
|
|
try {
|
|
result = new URL(str, 'postgres://base')
|
|
} catch (e) {
|
|
// The URL is invalid so try again with a dummy host
|
|
result = new URL(str.replace('@/', '@___DUMMY___/'), 'postgres://base')
|
|
dummyHost = true
|
|
}
|
|
|
|
// We'd like to use Object.fromEntries() here but Node.js 10 does not support it
|
|
for (const entry of result.searchParams.entries()) {
|
|
config[entry[0]] = entry[1]
|
|
}
|
|
|
|
config.user = config.user || decodeURIComponent(result.username)
|
|
config.password = config.password || decodeURIComponent(result.password)
|
|
|
|
if (result.protocol == 'socket:') {
|
|
config.host = decodeURI(result.pathname)
|
|
config.database = result.searchParams.get('db')
|
|
config.client_encoding = result.searchParams.get('encoding')
|
|
return config
|
|
}
|
|
const hostname = dummyHost ? '' : result.hostname
|
|
if (!config.host) {
|
|
// Only set the host if there is no equivalent query param.
|
|
config.host = decodeURIComponent(hostname)
|
|
} else if (hostname && /^%2f/i.test(hostname)) {
|
|
// Only prepend the hostname to the pathname if it is not a URL encoded Unix socket host.
|
|
result.pathname = hostname + result.pathname
|
|
}
|
|
if (!config.port) {
|
|
// Only set the port if there is no equivalent query param.
|
|
config.port = result.port
|
|
}
|
|
|
|
const pathname = result.pathname.slice(1) || null
|
|
config.database = pathname ? decodeURI(pathname) : null
|
|
|
|
if (config.ssl === 'true' || config.ssl === '1') {
|
|
config.ssl = true
|
|
}
|
|
|
|
if (config.ssl === '0') {
|
|
config.ssl = false
|
|
}
|
|
|
|
if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) {
|
|
config.ssl = {}
|
|
}
|
|
|
|
// Only try to load fs if we expect to read from the disk
|
|
const fs = config.sslcert || config.sslkey || config.sslrootcert ? require('fs') : null
|
|
|
|
if (config.sslcert) {
|
|
config.ssl.cert = fs.readFileSync(config.sslcert).toString()
|
|
}
|
|
|
|
if (config.sslkey) {
|
|
config.ssl.key = fs.readFileSync(config.sslkey).toString()
|
|
}
|
|
|
|
if (config.sslrootcert) {
|
|
config.ssl.ca = fs.readFileSync(config.sslrootcert).toString()
|
|
}
|
|
|
|
switch (config.sslmode) {
|
|
case 'disable': {
|
|
config.ssl = false
|
|
break
|
|
}
|
|
case 'prefer':
|
|
case 'require':
|
|
case 'verify-ca':
|
|
case 'verify-full': {
|
|
break
|
|
}
|
|
case 'no-verify': {
|
|
config.ssl.rejectUnauthorized = false
|
|
break
|
|
}
|
|
}
|
|
|
|
return config
|
|
}
|
|
|
|
module.exports = parse
|
|
|
|
parse.parse = parse
|