I'm using the Confidence library (in the HapiJS suite) for configuration management in my project (This config file specifically is for WinstonJS transports), and I was wondering if it was possible to set a default value for a single item in a filtered object. I'm not sure I'm explaining this right, I'm not positive what the correct terminology is, so heres an example:
I have a section of my configuration setup like so currently:
module.exports = {
$filter: 'env',
development: {
level: {
console: 'debug',
file: 'debug'
},
path: 'app-core.log'
},
staging: {
level: {
console: 'warn',
file: 'warn'
},
path: 'app-core.log'
},
production: {
level: {
console: 'error',
file: 'error'
},
path: 'prod-app-core.log'
}
}
But since the path
should be the same for all of the env
items, with the exception of production
, I was hoping that I could set the default value for just the path
value. Something like this:
module.exports = {
$filter: 'env',
development: {
level: {
console: 'debug',
file: 'debug'
}
},
staging: {
level: {
console: 'warn',
file: 'warn'
}
},
production: {
level: {
console: 'error',
file: 'error'
},
path: 'prod-app-core.log'
},
$default: {
path: 'app-core.log'
}
}
Obviously, that doesn't work, but I hope it illustrates what I'm trying to accomplish. I can't find a way to set default values for single config items within objects, if I apply a filter (say staging
), then it takes the entire staging object, and doesn't even look at the $default
object.
Thanks!
P.S. While I would like to know if this is possible via Confidence (for other purposes), if it turns out that this isn't possible, then is there a way to set the default path for WinstonJS file transports?
I think you're looking for $base
. See the shared values section in the docs:
If you have values that you would like to share between various configuration objects without duplicating them for each option, you can create a
$base
object.
Here's how it's used with your example:
const Confidence = require('confidence');
const document = {
$filter: 'env',
$base: {
path: 'app-core.log'
},
development: {
level: {
console: 'debug',
file: 'debug'
}
},
staging: {
level: {
console: 'warn',
file: 'warn'
}
},
production: {
level: {
console: 'error',
file: 'error'
},
path: 'prod-app-core.log'
}
};
const store = new Confidence.Store(document);
console.log(store.get('/', { env: 'production' }));
console.log(store.get('/', { env: 'development' }));
Console output:
{ path: 'prod-app-core.log',
level: { console: 'error', file: 'error' } }
{ path: 'app-core.log',
level: { console: 'debug', file: 'debug' } }
So what's $default
for then?
$default
is used to define an object that should be used when the env value doesn't have a corresponding key in the document. Without a $default
, you'd just get undefined
for that path:
const document = {
$filter: 'env',
$base: {
path: 'app-core.log'
},
$default: {
level: {
console: 'something-else',
file: 'something-else'
}
},
development: {
level: {
console: 'debug',
file: 'debug'
}
},
staging: {
level: {
console: 'warn',
file: 'warn'
}
},
production: {
level: {
console: 'error',
file: 'error'
},
path: 'prod-app-core.log'
}
};
const store = new Confidence.Store(document);
console.log(store.get('/', { env: 'dunno' }));
Console output:
{ path: 'app-core.log',
level: { console: 'something-else', file: 'something-else' } }
Anything defined at $default
level or a specific matching filter value will take precedence over the value defined at $base
.