I believe that you should be able to remove a configuration property during boot up. Currently this is not possible. I should be able to set the property to null and instead of trying to merge it, it should delete the property.
Let me give you an example. Suppose I am using GMail SMTP for testing but I also want the ability to set a environment variable and use a local SMTP server instead for testing. Also suppose that in production I will be using Mandrill.
I set up my datasources.json file as so:
"emailer": {
"name": "emailer",
"connector": "mail",
"transports": [
{
"type": "smtp",
"host": "smtp.gmail.com",
"secure": false,
"port": 587,
"tls": { "rejectUnauthorized": false },
"auth": {
"user": "xxxx...@gmail.com",
"pass": "xxxxxxxxx"
}
}
]
}
I set up my datasources.local.js file like so:
var localSMTP = process.env.localSMTP == null ? false :
( process.env.localSMTP.toLowerCase( ) == 'true' ? true : false );
if( localSMTP )
{
console.log( 'using local SMTP server' );
module.exports = {
emailer: {
transports: [
{
type: 'smtp',
host: '192.168.10.10',
secure: false,
port: 25,
tls: { 'rejectUnauthorized': false }
}
]
}
};
}
Further, I set up datasources.production.js as follows:
module.exports = {
emailer: {
connector: 'lb-connector-mandrill',
apikey: 'xxxxxxxxxxxxxxxxxxx'
}
};
Unfortunately, this doesn't work because of the way loopback-boot merges the configurations. My development and production emails go out but my development environment using the local SMTP fails because my local SMTP server is using anonymous access but the connector is hanging onto the transports.auth property it got from datasources.json. So it is trying to authenticate when it isn't necessary and getting bounced. Also, even though the emails go out in the production environment, the email connector still has the transports property attached (luckily I believe the Mandrill connector isn't using it so it is ignored).
I propose doing something like this within loopback-boot/lib/config-loader.js;
function mergeSingleItemOrProperty( target, config, key, fullKey )
{
var origValue = target[key];
var newValue = config[key];
// start proposed change
if( newValue == null )
{
delete target[key];
return null;
}
// end proposed change
if( !hasCompatibleType( origValue, newValue ) )
{
return 'Cannot merge values of incompatible types for the option `' +
fullKey + '`.';
}
if( Array.isArray( origValue ) )
{
return mergeArrays( origValue, newValue, fullKey );
}
if( typeof origValue === 'object' )
{
return mergeObjects( origValue, newValue, fullKey );
}
target[key] = newValue;
return null; // no error
}
This way within my datasources.local.js and datasources.production.js files I can do the following.
datasources.local.js\
var localSMTP = process.env.localSMTP == null ? false :
( process.env.localSMTP.toLowerCase( ) == 'true' ? true : false );
if( localSMTP )
{
console.log( 'using local SMTP server' );
module.exports = {
emailer: {
transports: [
{
type: 'smtp',
host: '192.168.0.10',
secure: false,
port: 25,
tls: { 'rejectUnauthorized': false },
auth: null
}
]
}
};
}
datasources.production.js:
module.exports = {
emailer: {
connector: 'lb-connector-mandrill',
apikey: 'xxxxxxxxxxxxxxxxxx',
transports: null
}
};
So setting a property to null in the environment config files will remove a property that was acquired from lower in the configuration hierarchy. Make sense?
I believe that you should be able to remove a configuration property during boot up. Currently this is not possible. I should be able to set the property to null and instead of trying to merge it, it should delete the property.
Let me give you an example. Suppose I am using GMail SMTP for testing but I also want the ability to set a environment variable and use a local SMTP server instead for testing. Also suppose that in production I will be using Mandrill.
I set up my datasources.json file as so:
I set up my datasources.local.js file like so:
Further, I set up datasources.production.js as follows:
Unfortunately, this doesn't work because of the way loopback-boot merges the configurations. My development and production emails go out but my development environment using the local SMTP fails because my local SMTP server is using anonymous access but the connector is hanging onto the transports.auth property it got from datasources.json. So it is trying to authenticate when it isn't necessary and getting bounced. Also, even though the emails go out in the production environment, the email connector still has the transports property attached (luckily I believe the Mandrill connector isn't using it so it is ignored).
I propose doing something like this within loopback-boot/lib/config-loader.js;
This way within my datasources.local.js and datasources.production.js files I can do the following.
datasources.local.js\
So setting a property to null in the environment config files will remove a property that was acquired from lower in the configuration hierarchy. Make sense?