| 80 | // opposite of credentialsToUri |
| 81 | // maybe rename, since it's about returning a parsed uri object? connection info? |
| 82 | export function uriToCredentials(connectionString: string): DatabaseCredentials { |
| 83 | // rename to url everywhere? |
| 84 | let uri: NodeURL.URL |
| 85 | try { |
| 86 | uri = new NodeURL.URL(connectionString) |
| 87 | } catch (e) { |
| 88 | throw new Error('Invalid data source URL, see https://pris.ly/d/config-url') |
| 89 | } |
| 90 | |
| 91 | const type = protocolToConnectorType(uri.protocol) |
| 92 | |
| 93 | // needed, as the URL implementation adds empty strings |
| 94 | const exists = (str): boolean => str && str.length > 0 |
| 95 | |
| 96 | const extraFields = {} |
| 97 | const schema = uri.searchParams.get('schema') |
| 98 | const socket = uri.searchParams.get('socket') |
| 99 | |
| 100 | for (const [name, value] of uri.searchParams) { |
| 101 | if (!['schema', 'socket'].includes(name)) { |
| 102 | extraFields[name] = value |
| 103 | } |
| 104 | } |
| 105 | |
| 106 | let database: string | undefined = undefined |
| 107 | |
| 108 | if (type === 'sqlite' && uri.pathname) { |
| 109 | // weird conditionals here |
| 110 | if (uri.pathname.startsWith('file:')) { |
| 111 | database = uri.pathname.slice(5) |
| 112 | } else { |
| 113 | // here it's only the file name? |
| 114 | database = path.basename(uri.pathname) |
| 115 | } |
| 116 | } |
| 117 | // why length more than 1? |
| 118 | // probably for slicing `/` or `?`? |
| 119 | else if (uri.pathname.length > 1) { |
| 120 | database = uri.pathname.slice(1) |
| 121 | |
| 122 | // if after slicing "database" is empty |
| 123 | if (type === 'postgresql' && !database) { |
| 124 | // use postgres as default, it's 99% accurate |
| 125 | // could also be template1 for example in rare cases |
| 126 | database = 'postgres' |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | return { |
| 131 | type, |
| 132 | host: exists(uri.hostname) ? uri.hostname : undefined, |
| 133 | user: exists(uri.username) ? uri.username : undefined, |
| 134 | port: exists(uri.port) ? Number(uri.port) : undefined, |
| 135 | password: exists(uri.password) ? uri.password : undefined, |
| 136 | database, |
| 137 | schema: schema || undefined, |
| 138 | uri: connectionString, |
| 139 | ssl: Boolean(uri.searchParams.get('sslmode')), |