123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 |
- /**
- * Module dependencies
- */
- var assert = require('assert');
- var util = require('util');
- var url = require('url');
- var _ = require('@sailshq/lodash');
- var flaverr = require('flaverr');
- var qs = require('qs');
- var normalizeDatabase = require('./private/normalize-database');
- var normalizeUser = require('./private/normalize-user');
- var normalizePort = require('./private/normalize-port');
- var normalizeHost = require('./private/normalize-host');
- var normalizePassword = require('./private/normalize-password');
- /**
- * normalizeDatastoreConfig()
- *
- * Normalize (mutate) the provided datastore config dictionary (in-place).
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * NOTES:
- * • This implementation was originally taken from sails-mongo
- * https://github.com/balderdashy/sails-mongo/tree/2816d81359a5846550c90bd1dbfa98967ac13786/lib/private/normalize-datastore-config
- * • All modifications are performed in-place!
- * • Top-level overrides like `host`, `port`, `user`, etc. are normalized and validated.
- * • Top-level overrides like `host`, `port`, `user`, etc. take precedence over whatever is in the URL.
- * • Normalized versions of top-level overrides like `host`, `port`, `user`, etc. °°ARE°° sucked into the URL automatically.
- * • Recognized URL pieces like the host, port, user, etc. **ARE NOT** attached as top-level props automatically.
- * • Recognized URL pieces like the host, port, user, etc. **ARE** validated and normalized individually, rebuilding the URL if necessary.
- * • Miscellanous properties **ARE NOT** sucked in to the URL automatically.
- * • Miscellaneous querystring opts in the URL °°ARE°° attached automatically as top-level props.
- * · They are left as-is in the URL as well.
- * · They are treated as strings (e.g. `?foo=0&bar=false` becomes `{foo:'0', bar: 'false'}`)
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * @param {Dictionary} dsConfig
- * ˚¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯\
- * ˙ url: {String?} ::
- * ˙ host: {String?} ::
- * ˙ port: {String?} ::
- * ˙ user: {String?} ::
- * ˙ password: {String?} ::
- * ˙ database: {String?} ::
- *
- * @param {Array?} whitelist
- * Optional. If provided, this is an array of strings indicating which custom settings
- * are recognized and should be allowed. The standard `url`/`host`/`database` etc. are
- * always allowed, no matter what. e.g. `['ssl', 'replicaSet']`
- *
- * @param {String?} expectedProtocolPrefix
- * Optional. If specified, this restricts `dsConfig.url` to use a mandatory protocol (e.g. "mongodb")
- * If no protocol is included (or if it is simply `://`), then this mandatory protocol
- * will be tacked on automatically.
- *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- * ╔═╗╦ ╦╔╦╗╦ ╦╦═╗╔═╗
- * ╠╣ ║ ║ ║ ║ ║╠╦╝║╣
- * ╚ ╚═╝ ╩ ╚═╝╩╚═╚═╝
- * FUTURE:
- *
- * @param {Number} defaultPort
- * @param {String} tolerateNoDatabase
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- */
- module.exports = function normalizeDatastoreConfig (dsConfig, whitelist, expectedProtocolPrefix) {
- // Sanity checks
- assert(_.isObject(dsConfig), '`dsConfig` should exist and be a dictionary!');
- assert(_.isUndefined(whitelist) || _.isArray(whitelist), 'If provided, 2nd argument should be a whitelist of valid custom settings-- e.g. [\'ssl\', \'replicaSet\']');
- assert(_.isUndefined(expectedProtocolPrefix) || _.isString(expectedProtocolPrefix), 'If provided, 2nd argument should be a string (e.g. "mongodb") representing the prefix for the expected protocol.');
- // Default top-level things.
- // If items in BASELINE_PROPS are included in the querystring of the connection url,
- // they are allowed to remain, but are not automatically applied at the top-level.
- // (Note that this whitelist applies to overrides AND to querystring-encoded values)
- var BASELINE_PROPS = [
- 'adapter',
- 'schema',
- 'identity',
- 'url',
- 'protocolPrefix',
- 'user',
- 'password',
- 'host',
- 'port',
- 'database',
- ];
- // Have a look at the datastore config to get an idea of what's there.
- var hasUrl = !_.isUndefined(dsConfig.url);
- var hasUserOverride = !_.isUndefined(dsConfig.user);
- var hasPasswordOverride = !_.isUndefined(dsConfig.password);
- var hasHostOverride = !_.isUndefined(dsConfig.host);
- var hasPortOverride = !_.isUndefined(dsConfig.port);
- var hasDatabaseOverride = !_.isUndefined(dsConfig.database);
- // ┌┐┌┌─┐┬─┐┌┬┐┌─┐┬ ┬┌─┐┌─┐ ╔═╗╦ ╦╔═╗╦═╗╦═╗╦╔╦╗╔═╗╔═╗
- // ││││ │├┬┘│││├─┤│ │┌─┘├┤ ║ ║╚╗╔╝║╣ ╠╦╝╠╦╝║ ║║║╣ ╚═╗
- // ┘└┘└─┘┴└─┴ ┴┴ ┴┴─┘┴└─┘└─┘ ╚═╝ ╚╝ ╚═╝╩╚═╩╚═╩═╩╝╚═╝╚═╝
- // ┬ ┌─┐ ┌─┐┌─┐┌┬┐┌┬┐┬┌┐┌┌─┐┌─┐ ┌┬┐┬ ┬┌─┐┌┬┐ ┌┬┐┌─┐┬┌─┌─┐
- // │ ├┤ └─┐├┤ │ │ │││││ ┬└─┐ │ ├─┤├─┤ │ │ ├─┤├┴┐├┤
- // ooo ┴o└─┘o └─┘└─┘ ┴ ┴ ┴┘└┘└─┘└─┘ ┴ ┴ ┴┴ ┴ ┴ ┴ ┴ ┴┴ ┴└─┘
- // ┌─┐┬─┐┌─┐┌─┐┌─┐┌┬┐┌─┐┌┐┌┌─┐┌─┐ ┌─┐┬ ┬┌─┐┬─┐ ┌─┐┌┬┐┌─┐┌┐┌┌┬┐┌─┐┬─┐┌┬┐
- // ├─┘├┬┘├┤ │ ├┤ ││├┤ ││││ ├┤ │ │└┐┌┘├┤ ├┬┘ └─┐ │ ├─┤│││ ││├─┤├┬┘ ││
- // ┴ ┴└─└─┘└─┘└─┘─┴┘└─┘┘└┘└─┘└─┘ └─┘ └┘ └─┘┴└─ └─┘ ┴ ┴ ┴┘└┘─┴┘┴ ┴┴└──┴┘
- // ┌─┐┬ ┬┬ ┬┌┐┌┬┌─┌─┐ ┌─┐┌─┐ ┌┬┐┬ ┬┌─┐ ┌─┐┌─┐┌┐┌┌┐┌┌─┐┌─┐┌┬┐┬┌─┐┌┐┌ ┬ ┬┬─┐┬
- // │ ├─┤│ ││││├┴┐└─┐ │ │├┤ │ ├─┤├┤ │ │ │││││││├┤ │ │ ││ ││││ │ │├┬┘│
- // └─┘┴ ┴└─┘┘└┘┴ ┴└─┘ └─┘└ ┴ ┴ ┴└─┘ └─┘└─┘┘└┘┘└┘└─┘└─┘ ┴ ┴└─┘┘└┘ └─┘┴└─┴─┘
- try {
- if (hasUserOverride) {
- dsConfig.user = normalizeUser(dsConfig.user);
- }
- if (hasPasswordOverride) {
- dsConfig.password = normalizePassword(dsConfig.password);
- }
- if (hasHostOverride) {
- dsConfig.host = normalizeHost(dsConfig.host);
- }
- if (hasPortOverride) {
- dsConfig.port = normalizePort(dsConfig.port);
- }
- if (hasDatabaseOverride) {
- dsConfig.database = normalizeDatabase(dsConfig.database);
- }
- } catch (e) {
- switch (e.code) {
- case 'E_BAD_CONFIG': throw flaverr('E_BAD_CONFIG', new Error(
- 'Invalid override specified. '+e.message+'\n'+
- '--\n'+
- 'Please correct this and try again... Or better yet, specify a `url`! '+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- default: throw e;
- }
- }//</catch>
- // Strip out any overrides w/ undefined values.
- // (And along the way, check overrides against whitelist if relevant)
- var unrecognizedKeys;
- _.each(Object.keys(dsConfig), function (key) {
- if (_.isUndefined(dsConfig[key])) {
- delete dsConfig[key];
- }
- if (whitelist && !_.contains(whitelist, key) && !_.contains(BASELINE_PROPS, key)) {
- unrecognizedKeys = unrecognizedKeys || [];
- unrecognizedKeys.push(key);
- }
- });
- if (unrecognizedKeys) {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'Unrecognized options (`'+unrecognizedKeys+'`) specified as config overrides.\n'+
- 'This adapter expects only whitelisted properties.\n'+
- '--\n'+
- 'See http://sailsjs.com/config/datastores#?the-connection-url for info,\n'+
- 'or visit https://sailsjs.com/support for more help.'
- ));
- }
- // ┬ ┬┌─┐┌┐┌┌┬┐┬ ┌─┐ ┌─┐┌┐ ┌─┐┌─┐┌┐┌┌─┐┌─┐ ┌─┐┌─┐ ┬ ┬┬─┐┬
- // ├─┤├─┤│││ │││ ├┤ ├─┤├┴┐└─┐├┤ ││││ ├┤ │ │├┤ │ │├┬┘│
- // ┴ ┴┴ ┴┘└┘─┴┘┴─┘└─┘ ┴ ┴└─┘└─┘└─┘┘└┘└─┘└─┘ └─┘└ └─┘┴└─┴─┘
- // ┌─ ┌┐ ┌─┐┌─┐┬┌─┬ ┬┌─┐┬─┐┌┬┐┌─┐ ┌─┐┌─┐┌┬┐┌─┐┌─┐┌┬┐┬┌┐ ┬┬ ┬┌┬┐┬ ┬ ─┐
- // │─── ├┴┐├─┤│ ├┴┐│││├─┤├┬┘ ││└─┐───│ │ ││││├─┘├─┤ │ │├┴┐││ │ │ └┬┘ ───│
- // └─ └─┘┴ ┴└─┘┴ ┴└┴┘┴ ┴┴└──┴┘└─┘ └─┘└─┘┴ ┴┴ ┴ ┴ ┴ ┴└─┘┴┴─┘┴ ┴ ┴ ─┘
- // If a URL config value was not given, ensure that all the various pieces
- // needed to create one exist. Then build a URL and attach it to the datastore config.
- if (!hasUrl) {
- // Invent a connection URL on the fly.
- var inventedUrl = (expectedProtocolPrefix||'db')+'://';
- // ^^FUTURE: Potentially use `protocolPrefix` here if one was specified
- // If no .protocolPrefix property is already defined on dsConfig, and an
- // explicit expected protocol prefix was specified, then attach that.
- if (expectedProtocolPrefix && dsConfig.protocolPrefix === undefined) {
- dsConfig.protocolPrefix = expectedProtocolPrefix;
- }
- // FUTURE: Appropriately URL/URIComponent-encode this stuff as we build the url
- // If authentication info was specified, add it:
- if (hasPasswordOverride && hasUserOverride) {
- inventedUrl += dsConfig.user+':'+dsConfig.password+'@';
- }
- else if (!hasPasswordOverride && hasUserOverride) {
- inventedUrl += dsConfig.user+'@';
- }
- else if (hasPasswordOverride && !hasUserOverride) {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'No `url` was specified, so tried to infer an appropriate connection URL from other properties. '+
- 'However, it looks like a `password` was specified, but no `user` was specified to go along with it.\n'+
- '--\n'+
- 'Please remove `password` or also specify a `user`. Or better yet, specify a `url`! '+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- }
- // If a host was specified, use it.
- if (hasHostOverride) {
- inventedUrl += dsConfig.host;
- }
- else {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'No `url` was specified, and no appropriate connection URL can be inferred (tried to use '+
- '`host: '+util.inspect(dsConfig.host)+'`).\n'+
- '--\n'+
- 'Please specify a `host`... Or better yet, specify a `url`! '+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- // Or alternatively...
- // ```
- // inventedUrl += 'localhost';
- // ```
- }
- // If a port was specified, use it.
- if (hasPortOverride) {
- inventedUrl += ':'+dsConfig.port;
- }
- // If a database was specified, use it.
- if (hasDatabaseOverride) {
- inventedUrl += '/'+dsConfig.database;
- }
- else {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'No `url` was specified, and no appropriate connection URL can be inferred (tried to use '+
- '`database: '+util.inspect(dsConfig.database)+'`).\n'+
- '--\n'+
- 'Please specify a `database`... Or better yet, specify a `url`! '+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- }
- // - - - - - - - - - - - - - - - - - - - - - - - -
- // FUTURE: Log a compatibility warning..? Maybe.
- //
- // > To help standardize configuration for end users, adapter authors
- // > are encouraged to support the `url` setting, if conceivable.
- // >
- // > Read more here:
- // > http://sailsjs.com/config/datastores#?the-connection-url
- // - - - - - - - - - - - - - - - - - - - - - - - -
- // Now save our invented URL as `url`.
- dsConfig.url = inventedUrl;
- }
- // ┌─┐┌─┐┬─┐┌─┐┌─┐ ┬ ┌┐┌┌─┐┬─┐┌┬┐┌─┐┬ ┬┌─┐┌─┐ ┌─┐┌─┐┌┐┌┌┐┌┌─┐┌─┐┌┬┐┬┌─┐┌┐┌ ╦ ╦╦═╗╦
- // ├─┘├─┤├┬┘└─┐├┤ ┌┼─ ││││ │├┬┘│││├─┤│ │┌─┘├┤ │ │ │││││││├┤ │ │ ││ ││││ ║ ║╠╦╝║
- // ┴ ┴ ┴┴└─└─┘└─┘ └┘ ┘└┘└─┘┴└─┴ ┴┴ ┴┴─┘┴└─┘└─┘ └─┘└─┘┘└┘┘└┘└─┘└─┘ ┴ ┴└─┘┘└┘ ╚═╝╩╚═╩═╝
- // Otherwise, normalize & parse the connection URL.
- else {
- // Perform a basic sanity check & string coercion.
- if (!_.isString(dsConfig.url) || dsConfig.url === '') {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'Invalid `url` specified. Must be a non-empty string.\n'+
- '--\n'+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- }
- // Before beginning to do further string parsing, look for a little loophole:
- // If the given URL includes a comma, we'll assume it's a complex URL like you get
- // from Mongo Atlas and trust that it contains all the info we need.
- //
- // > But note that this _does not_ handle automatically attaching host, password,
- // > port, etc. to the `dsConfig` dictionary. It also doesn't do any verification
- // > of these aspects of the URL, which means it could be entirely invalid.
- if (dsConfig.url.indexOf(',') > -1) {
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // FUTURE: Implement explicit parsing for this kind of URL instead of just bailing silently.
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- return;
- }//•
- // IWMIH, this is the general case where we're actually going to validate the URL like normal.
- // First, make sure there's a protocol:
- // We don't actually care about the protocol... but the underlying library (e.g. `mongodb`) might.
- // Plus, more importantly, Node's `url.parse()` returns funky results if the argument doesn't
- // have one. So we'll add one if necessary.
- // > See https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Syntax
- var urlToParse;
- if (dsConfig.url.match(/^:\/\//)) {
- urlToParse = dsConfig.url.replace(/^:\/\//, (expectedProtocolPrefix||'db')+'://');
- }
- else if (!dsConfig.url.match(/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//)) {
- urlToParse = (expectedProtocolPrefix||'db')+'://'+dsConfig.url;
- }
- else {
- urlToParse = dsConfig.url;
- }
- // console.log('dsConfig.url',dsConfig.url);
- // console.log('\n\n**********\nurl to parse:',urlToParse, (new Error()).stack);
- // Now attempt to parse out the URL's pieces and validate each one.
- var parsedConnectionStr = url.parse(urlToParse);
- // Ensure a valid protocol.
- // Validate that a protocol was found before other pieces
- // (otherwise other parsed info could be very weird and wrong)
- if (!parsedConnectionStr.protocol) {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'Could not parse provided URL ('+util.inspect(dsConfig.url,{depth:5})+').\n'+
- '(If you continue to experience issues, try checking that the URL begins with an '+
- 'appropriate protocol; e.g. `mysql://` or `mongo://`.\n'+
- '--\n'+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- }
- // If relevant, validate that the RIGHT protocol was found.
- if (expectedProtocolPrefix) {
- if (parsedConnectionStr.protocol !== expectedProtocolPrefix+':') {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'Provided URL ('+util.inspect(dsConfig.url,{depth:5})+') has an invalid protocol.\n'+
- 'If included, the protocol must be "'+expectedProtocolPrefix+'://".\n'+
- '--\n'+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- }
- // FUTURE: Potentially also check `.protocolPrefix` prop if one was specified
- }//>-
- // If the connection string contains a specific protocol, save it in the
- // dsconfig -- unless a `protocolPrefix` property is already defined.
- if (parsedConnectionStr !== 'db:' && dsConfig.protocolPrefix === undefined) {
- dsConfig.protocolPrefix = (parsedConnectionStr.protocol||'').replace(/\:$/,'');
- }
- // Parse authentication credentials from url, if specified.
- var userInUrl;
- var passwordInUrl;
- if (parsedConnectionStr.auth && _.isString(parsedConnectionStr.auth)) {
- var authPieces = parsedConnectionStr.auth.split(/:/);
- if (authPieces[0]) {
- userInUrl = authPieces[0];
- }//>-
- if (authPieces[1]) {
- passwordInUrl = authPieces[1];
- }
- }
- // Parse the rest of the standard information from the URL.
- var hostInUrl = parsedConnectionStr.hostname;
- var portInUrl = parsedConnectionStr.port;
- var databaseInUrl = parsedConnectionStr.pathname;
- // And finally parse the non-standard info from the URL's querystring.
- var miscOptsInUrlQs;
- try {
- miscOptsInUrlQs = qs.parse(parsedConnectionStr.query);
- } catch (e) {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'Could not parse query string from URL: `'+dsConfig.url+'`. '+
- 'Details: '+e.stack
- ));
- }
- // Now normalize + restore parsed values back into overrides.
- // > • Note that we prefer overrides to URL data here.
- // > • Also remember that overrides have already been normalized/validated above.
- // > • And finally, also note that we enforce the whitelist for non-standard props
- // > here, if relevant. This is so we can provide a clear error message about where
- // > the whitelist violation came from.
- try {
- if (userInUrl && !hasUserOverride) {
- dsConfig.user = normalizeUser(userInUrl);
- }
- if (passwordInUrl && !hasPasswordOverride) {
- dsConfig.password = normalizePassword(passwordInUrl);
- }
- if (hostInUrl && !hasHostOverride) {
- dsConfig.host = normalizeHost(hostInUrl);
- }
- if (portInUrl && !hasPortOverride) {
- dsConfig.port = normalizePort(portInUrl);
- }
- if (databaseInUrl && !hasDatabaseOverride) {
- databaseInUrl = _.trim(databaseInUrl, '/');
- dsConfig.database = normalizeDatabase(databaseInUrl);
- }
- _.each(miscOptsInUrlQs, function (val, key) {
- if (whitelist && !_.contains(whitelist, key)) {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'Unrecognized option (`'+key+'`) specified in query string of connection URL.\n'+
- '(This adapter expects only standard, whitelisted properties.)\n'+
- '--\n'+
- 'See http://sailsjs.com/config/datastores#?the-connection-url for info, or visit\n)'+
- 'https://sailsjs.com/support for more help.'
- ));
- }
- if (_.contains(BASELINE_PROPS, key)) {
- // Currently, we ignore these-- we'll technically put them back in the URL later below,
- // but we're careful not to also stick them at the top level (because they would interfere
- // with other reserved properties).
- //
- // We're leaving it this way for now in the interest of flexibility. But there's another way:
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // FUTURE: consider bringing this back instead, for clarity:
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- // throw flaverr('E_BAD_CONFIG', new Error(
- // 'Unexpected option (`'+key+'`) is NEVER allowed in the query string of a connection URL.\n'+
- // '--\n'+
- // 'See http://sailsjs.com/config/datastores#?the-connection-url for info, or visit\n)'+
- // 'https://sailsjs.com/support for more help.'
- // ));
- // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- }
- else if (_.isUndefined(dsConfig[key])) {
- dsConfig[key] = val;
- }
- });//</_.each()>
- } catch (e) {
- switch (e.code) {
- case 'E_BAD_CONFIG': throw flaverr('E_BAD_CONFIG', new Error(
- 'Could not process connection url. '+e.message+'\n'+
- '--\n'+
- 'Please correct this and try again.\n'+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- default: throw e;
- }
- }//</catch>
- // And finally, rebuild the URL
- var rebuiltUrl = '';
- // Start with the protocol...
- rebuiltUrl += parsedConnectionStr.protocol+'//';
- // FUTURE: Potentially use `protocolPrefix` here if one was specified
- // If user/password were specified in the url OR as overrides, use them.
- if (dsConfig.user && dsConfig.password) {
- rebuiltUrl += dsConfig.user+':'+dsConfig.password+'@';
- }
- else if (!dsConfig.password && dsConfig.user) {
- rebuiltUrl += dsConfig.user+'@';
- }
- else if (dsConfig.password && !dsConfig.user) {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'It looks like a `password` was specified, but no `user` was specified to go along with it.\n'+
- '--\n'+
- 'Please remove `password` or also specify a `user`. '+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- }
- // If a host was specified in the url OR as an override, use it.
- // (prefer override)
- if (dsConfig.host) {
- rebuiltUrl += dsConfig.host;
- }
- else {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'No host could be determined from configuration (tried to use '+
- '`host: '+util.inspect(dsConfig.host)+'`).\n'+
- '--\n'+
- 'Please specify a `host` or, better yet, include it in the `url`. '+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- // Or alternatively...
- // ```
- // rebuiltUrl += 'localhost';
- // ```
- }
- // If a port was specified in the url OR as an override, use it.
- // (prefer override)
- if (dsConfig.port) {
- rebuiltUrl += ':'+dsConfig.port;
- }
- // If a database was specified in the url OR as an override, use it.
- // (prefer override)
- if (dsConfig.database) {
- rebuiltUrl += '/'+dsConfig.database;
- }
- else {
- throw flaverr('E_BAD_CONFIG', new Error(
- 'No database could be determined from configuration (tried to use '+
- '`database: '+util.inspect(dsConfig.database)+'`).\n'+
- '--\n'+
- 'Please specify a `database` or, better yet, include it in the `url`. '+
- '(See http://sailsjs.com/config/datastores#?the-connection-url for more info.)'
- ));
- }
- // Reattach any non-standard querystring options from the URL.
- // > If there were any non-standard options, we'll **LEAVE THEM IN** the URL
- // > when we rebuild it. But note that we did fold them into the dsConfig
- // > dictionary as well earlier.
- var newQs = qs.stringify(miscOptsInUrlQs);
- if (newQs.length > 0) {
- rebuiltUrl += '?'+newQs;
- }
- // Now save our rebuilt URL as `url`.
- dsConfig.url = rebuiltUrl;
- }
- };
|