11'use strict'
22
3- var url = require ( 'url' )
4- var fs = require ( 'fs' )
5-
63//Parse method copied from https://github.com/brianc/node-postgres
74//Copyright (c) 2010-2014 Brian Carlson ([email protected] ) 85//MIT License
@@ -11,51 +8,53 @@ var fs = require('fs')
118function parse ( str ) {
129 //unix socket
1310 if ( str . charAt ( 0 ) === '/' ) {
14- var config = str . split ( ' ' )
11+ const config = str . split ( ' ' )
1512 return { host : config [ 0 ] , database : config [ 1 ] }
1613 }
1714
18- // url parse expects spaces encoded as %20
19- var result = url . parse (
20- / | % [ ^ a - f 0 - 9 ] | % [ a - f 0 - 9 ] [ ^ a - f 0 - 9 ] / i. test ( str ) ? encodeURI ( str ) . replace ( / \% 2 5 ( \d \d ) / g, '%$1' ) : str ,
21- true
22- )
23- var config = result . query
24- for ( var k in config ) {
25- if ( Array . isArray ( config [ k ] ) ) {
26- config [ k ] = config [ k ] [ config [ k ] . length - 1 ]
27- }
15+ // Check for empty host in URL
16+
17+ const config = { }
18+ let result
19+ let dummyHost = false
20+ if ( / | % [ ^ a - f 0 - 9 ] | % [ a - f 0 - 9 ] [ ^ a - f 0 - 9 ] / i. test ( str ) ) {
21+ // Ensure spaces are encoded as %20
22+ str = encodeURI ( str ) . replace ( / \% 2 5 ( \d \d ) / g, '%$1' )
23+ }
24+
25+ try {
26+ result = new URL ( str , 'postgres://base' )
27+ } catch ( e ) {
28+ // The URL is invalid so try again with a dummy host
29+ result = new URL ( str . replace ( '@/' , '@___DUMMY___/' ) , 'postgres://base' )
30+ dummyHost = true
2831 }
2932
30- var auth = ( result . auth || ':' ) . split ( ':' )
31- config . user = auth [ 0 ]
32- config . password = auth . splice ( 1 ) . join ( ':' )
33+ // We'd like to use Object.fromEntries() here but Node.js 10 does not support it
34+ for ( const entry of result . searchParams . entries ( ) ) {
35+ config [ entry [ 0 ] ] = entry [ 1 ]
36+ }
37+
38+ config . user = config . user || decodeURIComponent ( result . username )
39+ config . password = config . password || decodeURIComponent ( result . password )
3340
3441 config . port = result . port
3542 if ( result . protocol == 'socket:' ) {
3643 config . host = decodeURI ( result . pathname )
37- config . database = result . query . db
38- config . client_encoding = result . query . encoding
44+ config . database = result . searchParams . get ( 'db' )
45+ config . client_encoding = result . searchParams . get ( ' encoding' )
3946 return config
4047 }
48+ const hostname = dummyHost ? '' : result . hostname
4149 if ( ! config . host ) {
4250 // Only set the host if there is no equivalent query param.
43- config . host = result . hostname
51+ config . host = decodeURIComponent ( hostname )
52+ } else if ( hostname ) {
53+ result . pathname = hostname + result . pathname
4454 }
4555
46- // If the host is missing it might be a URL-encoded path to a socket.
47- var pathname = result . pathname
48- if ( ! config . host && pathname && / ^ % 2 f / i. test ( pathname ) ) {
49- var pathnameSplit = pathname . split ( '/' )
50- config . host = decodeURIComponent ( pathnameSplit [ 0 ] )
51- pathname = pathnameSplit . splice ( 1 ) . join ( '/' )
52- }
53- // result.pathname is not always guaranteed to have a '/' prefix (e.g. relative urls)
54- // only strip the slash if it is present.
55- if ( pathname && pathname . charAt ( 0 ) === '/' ) {
56- pathname = pathname . slice ( 1 ) || null
57- }
58- config . database = pathname && decodeURI ( pathname )
56+ const pathname = result . pathname . slice ( 1 ) || null
57+ config . database = pathname ? decodeURI ( pathname ) : null
5958
6059 if ( config . ssl === 'true' || config . ssl === '1' ) {
6160 config . ssl = true
@@ -69,6 +68,9 @@ function parse(str) {
6968 config . ssl = { }
7069 }
7170
71+ // Only try to load fs if we expect to read from the disk
72+ const fs = config . sslcert || config . sslkey || config . sslrootcert ? require ( 'fs' ) : null
73+
7274 if ( config . sslcert ) {
7375 config . ssl . cert = fs . readFileSync ( config . sslcert ) . toString ( )
7476 }
0 commit comments