config-ninja
Advanced tools
Comparing version 0.2.4 to 1.0.0
@@ -7,45 +7,66 @@ 'use strict'; | ||
const ME = module.exports; | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const clc = require('cli-color'); | ||
const extender = require('object-extender'); | ||
const stackTrace = require(`stack-trace`); | ||
const extender = require(`object-extender`); | ||
const ConfigBuilder = require(`./modules/configBuilder`); | ||
const ConfigError = require(`./modules/configError`); | ||
const utilityFunctions = { | ||
'__inspect': __inspect, | ||
'__reload': __reload, | ||
'__switch': __switch, | ||
'__addLocal': __addLocal, | ||
'__get': __get, | ||
'__raw': __raw, | ||
'__plain': __plain, | ||
'__trace': __trace, | ||
}; | ||
const utilityFunctionNames = Object.keys(utilityFunctions); | ||
const configCache = {}; | ||
/* | ||
* Loads in a config file and converts it to a JSON string ready for parsing, whilst handling errors. | ||
* Utility function to the return the options used to construct the config and its meta information. | ||
*/ | ||
const readConfigFile = function (type, name, dir, absolutePath, configInFilename, ignoreMissing) { | ||
function __inspect (object) { | ||
let filename = path.join(dir, `${name}${configInFilename ? '.config' : ''}.json`); | ||
let cfg; | ||
return { | ||
options: extender.clone(object.options), | ||
meta: extender.clone(object.meta), | ||
}; | ||
// If the user is not passing in an absolute path to the config then we use the current working directory. | ||
if (!absolutePath) { filename = path.join(process.cwd(), filename); } | ||
} | ||
try { | ||
cfg = fs.readFileSync(filename).toString(); | ||
} catch (err) { | ||
if (!ignoreMissing) { | ||
throw new Error(clc.redBright(`Unable to read ${type} config "${name}" (${err.code}) from path "${filename}".`)); | ||
} | ||
} | ||
/* | ||
* Reload the existing config and return the result. If the immutable option is not set, the original config object will | ||
* be mutated. | ||
*/ | ||
function __reload (object) { | ||
return prepareConfig(object.configId, null, null, object.options); | ||
} | ||
return cfg || null; | ||
/* | ||
* Switch the config to a new environment and return the result. If the immutable option is not set, the original config | ||
* object will be mutated. | ||
*/ | ||
function __switch (object, env) { | ||
}; | ||
if (!env) { throw new ConfigError(`You must specify an environment to switch to.`); } | ||
const newOptions = extender.merge(object.options, { env }); | ||
return prepareConfig(object.configId, null, null, newOptions); | ||
} | ||
/* | ||
* Takes a JSON string and returns a nicely formatted config object, whilst handling errors. | ||
* Reload the existing config and return the result, adding in the extra local config files specified. If the immutable | ||
* option is not set, the original config object will be mutated. | ||
*/ | ||
const parseConfigJSON = function (type, name, input) { | ||
function __addLocal (object, _localConfig) { | ||
let output; | ||
const localConfig = (typeof _localConfig === `string` ? [_localConfig] : _localConfig); | ||
try { | ||
output = JSON.parse(input); | ||
} catch (err) { | ||
throw new Error(clc.redBright(`The ${type} config "${name}" is not valid JSON (${err.name}).`)); | ||
} | ||
if (!Array.isArray(localConfig)) { throw new ConfigError(`You must specify an array of local config files to add.`); } | ||
return output; | ||
const newOptions = extender.merge(object.options, { localConfig: localConfig.concat(localConfig) }); | ||
return prepareConfig(object.configId, null, null, newOptions); | ||
@@ -55,119 +76,214 @@ } | ||
/* | ||
* Load and merge the config files synchronously. | ||
* Gets the specified environment's config as if that were the new environment and return the result. Does not modify | ||
* the existing config. | ||
*/ | ||
ME.init = function (dir, env, _options) { | ||
function __get (object, env) { | ||
// Default options. | ||
let options = extender.defaults({ | ||
configInFilename: true, | ||
setEnvProperty: { 'production': 1, 'staging': 2, 'development': 3 }, | ||
additionalMergeFiles: [], | ||
ignoreMissingAdditional: true, | ||
absolutePath: false, | ||
returnCopy: false, | ||
}, _options); | ||
if (!env) { throw new ConfigError(`You must specify an environment to get.`); } | ||
// If no dir is specified assume we are reloading. | ||
if (!dir) { | ||
dir = ME._cfgPath; | ||
if (!env) { env = ME._env; } | ||
options = extender.defaults(ME._options, _options); | ||
} | ||
const newOptions = extender.merge(object.options, { env }); | ||
return prepareConfig(object.configId, null, null, newOptions, true); | ||
// Which environment are we operating in? | ||
if (!env) { env = process.env.NODE_ENV || 'development'; } | ||
} | ||
const configList = []; | ||
let prodCfg; | ||
let envCfg; | ||
let merged; | ||
/* | ||
* Utiliy function to return the raw config values for the given environment before they were merged in. | ||
*/ | ||
function __raw (object, env) { | ||
// Prepare the production config. | ||
prodCfg = readConfigFile('production', 'production', dir, options.absolutePath, options.configInFilename); | ||
prodCfg = parseConfigJSON('production', 'production', prodCfg); | ||
// If no environment is specified return all the raw files in a hash. | ||
if (!env) { return extender.clone(object.raw); } | ||
// Load the environment config? | ||
if (env !== 'production') { | ||
envCfg = readConfigFile('environment', env, dir, options.absolutePath, options.configInFilename); | ||
envCfg = parseConfigJSON('environment', env, envCfg); | ||
} | ||
if (!object.raw[env]) { throw new ConfigError(`There is no config loaded called "${env}".`); } | ||
// Add in our internal properties. | ||
const defaults = { | ||
_env: env, | ||
_cfgPath: dir, | ||
_options: options, | ||
}; | ||
return extender.clone(object.raw[env]); | ||
} | ||
// Prepare the list of config objects. | ||
configList.push(defaults, prodCfg, envCfg); | ||
/* | ||
* Returns a copy of the config properties without any of the utility functions added in. | ||
*/ | ||
function __plain (object) { | ||
return use(object.configId, object.options.immutable, true); | ||
} | ||
// Do we have any additional files to merge in? | ||
if (options.additionalMergeFiles && options.additionalMergeFiles.length) { | ||
/* | ||
* Utility function to return the trace of the stack that initialised the config. | ||
*/ | ||
function __trace (object) { | ||
return Array.from(object.trace); | ||
} | ||
for (var a = 0, alen = options.additionalMergeFiles.length; a < alen; a++) { | ||
const additionalMergeFile = options.additionalMergeFiles[a]; | ||
let addCfg; | ||
/* | ||
* Handle the different function signatures for .init(). | ||
*/ | ||
function initParameterSwitching (param2, param3, param4) { | ||
// Attempt to load in the config file. | ||
addCfg = readConfigFile('additional', additionalMergeFile, dir, options.absolutePath, options.configInFilename, options.ignoreMissingAdditional); | ||
if (!addCfg) { continue; } | ||
let dir = null; | ||
let env = null; | ||
let options = null; | ||
// JSONify. | ||
addCfg = parseConfigJSON('additional', additionalMergeFile, addCfg); | ||
// .init(configId, dir, env, options); | ||
if (typeof param2 !== `undefined` && typeof param3 !== `undefined` && typeof param4 !== `undefined`) { | ||
dir = param2; | ||
env = param3; | ||
options = param4; | ||
} | ||
// Store the additional config ready for merging. | ||
configList.push(addCfg); | ||
} | ||
// .init(configId, dir, env); | ||
else if (typeof param2 !== `undefined` && typeof param3 === `string` && typeof param4 === `undefined`) { | ||
dir = param2; | ||
env = param3; | ||
} | ||
} | ||
// .init(configId, dir, options); | ||
else if (typeof param2 !== `undefined` && typeof param3 === `object` && typeof param4 === `undefined`) { | ||
dir = param2; | ||
options = param3; | ||
} | ||
// Merge the configs together. | ||
merged = extender.merge(...configList); | ||
// .init(configId, dir); | ||
else if (typeof param2 === `string` && typeof param3 === `undefined` && typeof param4 === `undefined`) { | ||
dir = param2; | ||
} | ||
// Add the env properties? | ||
if (options.setEnvProperty && !merged.env) { | ||
const environmentLevels = (typeof options.setEnvProperty === 'object' ? options.setEnvProperty : null); | ||
merged.env = { | ||
id: env, | ||
level: (environmentLevels && typeof environmentLevels[env] !== 'undefined' ? environmentLevels[env] : null), | ||
}; | ||
} | ||
// .init(configId, options); | ||
// .init(configId); | ||
else { | ||
options = param2; | ||
} | ||
// Drop out here if we just need to return a copy of the config. | ||
if (options.returnCopy) { return merged; } | ||
return { dir, env, options: options || {} }; | ||
// Copy the configs onto the 'config-ninja' object. | ||
extender.mergeInto(ME, merged); | ||
} | ||
// Allow immediate use of 'config'. | ||
return ME; | ||
/* | ||
* Factory to create a new config. Can only be used once per config id. | ||
*/ | ||
function init (configId, param2, param3, param4) { | ||
}; | ||
// We can only initialise each config id once. | ||
if (configCache[configId]) { | ||
throw new ConfigError(`The config "${configId}" already exists! Use ".use()" to obtain an immutable copy of it.`); | ||
} | ||
const { dir, env, options } = initParameterSwitching(param2, param3, param4); | ||
return prepareConfig(configId, dir, env, options); | ||
} | ||
/* | ||
* Returns a temporary copy of the given config. | ||
* Creates a new config. | ||
*/ | ||
ME.get = function (useEnv, raw) { | ||
function prepareConfig (configId, dir, env, options, returnOnly = false) { | ||
// Must initialise the config first. | ||
if (!ME._env) { throw new Error('Config has not been initialised yet.'); } | ||
const builder = new ConfigBuilder(configId, dir, env, options); | ||
let useOptions = extender.defaults(ME._options, { | ||
returnCopy: true, | ||
}); | ||
// Just returns the config values without storing the config. | ||
if (returnOnly) { return extender.clone(builder.getValues()); } | ||
// Return just a single file without merging it. | ||
if (raw) { | ||
let rawCfg; | ||
// The config has previously been loaded and we the immutable option is not set. | ||
if (configCache[configId] && !options.immutable) { | ||
// Prepare the config. | ||
rawCfg = readConfigFile('raw', env, useOptions, dir, useOptions.absolutePath, useOptions.configInFilename); | ||
rawCfg = parseConfigJSON('raw', env, rawCfg); | ||
return rawCfg; | ||
} | ||
// Remove all old properties from the config values so it's empty without destroying the values object itself. | ||
for (const key in configCache[configId].values) { | ||
if (configCache[configId].values.hasOwnProperty(key)) { | ||
delete configCache[configId].values[key]; | ||
} | ||
} | ||
// Return a copy of the given config. | ||
return ME.init(ME._cfgPath, useEnv, useOptions); | ||
// Merge in the new config. | ||
extender.mergeInto(configCache[configId].values, builder.getValues()); | ||
// Overwrite these with the new values (rather than merging). | ||
configCache[configId].options = builder.getOptions(); | ||
configCache[configId].meta = builder.getMeta(); | ||
configCache[configId].raw = builder.getRaw(); | ||
} | ||
// Otherwise the immutable option is set, or this is the first init of the config. | ||
else { | ||
configCache[configId] = { | ||
configId, | ||
values: builder.getValues(), | ||
options: builder.getOptions(), | ||
meta: builder.getMeta(), | ||
raw: builder.getRaw(), | ||
trace: stackTrace.get().map(item => item.toString()), | ||
}; | ||
} | ||
// Return the config. | ||
const immutable = options && options.immutable; | ||
return use(configId, immutable); | ||
} | ||
/* | ||
* Returns a copy of the config in memory. | ||
*/ | ||
function use (configId, _immutable = false, _plain = false) { | ||
// Ensure the config was previously initialised. | ||
if (!configCache[configId]) { | ||
throw new ConfigError(`The config "${configId}" has not been initialised with the ".init()" method!`); | ||
} | ||
// Create a copy to make the config immutable if the immutable option is truthy. | ||
const object = configCache[configId]; | ||
const immutable = object.options.immutable || _immutable || false; | ||
const plain = object.options.plain || _plain || false; | ||
const config = (immutable ? extender.clone(object.values) : object.values); | ||
// Plain objects should not have any of the utility functions attached. | ||
if (plain) { | ||
for (const key in config) { | ||
if (config.hasOwnProperty(key)) { | ||
if (utilityFunctionNames.includes(key)) { delete config[key]; } | ||
} | ||
} | ||
} | ||
// Otherwise we add the utility functions to the config. | ||
else { | ||
for (const key in utilityFunctions) { | ||
if (utilityFunctions.hasOwnProperty(key)) { | ||
const func = utilityFunctions[key]; | ||
config[key] = func.bind(null, object); | ||
} | ||
} | ||
} | ||
return config; | ||
} | ||
/* | ||
* Removes an existing config, without preventing any other modules from using it if they have already obtained a copy. | ||
*/ | ||
function wipe (configId) { | ||
// Ensure the config was previously initialised. | ||
if (!configCache[configId]) { | ||
throw new ConfigError(`The config "${configId}" has not been initialised with the ".init()" method!`); | ||
} | ||
delete configCache[configId]; | ||
} | ||
/* | ||
* Export. | ||
*/ | ||
module.exports = { | ||
init, | ||
use, | ||
wipe, | ||
}; |
@@ -8,13 +8,15 @@ 'use strict'; | ||
/* eslint no-console: 0 */ | ||
// Ensure we always work relative to this script. | ||
process.chdir(__dirname); | ||
// Prepare the ninja on application load. | ||
const configInModuleA = require('../configNinja').init(__dirname + '/cfg', null, { | ||
additionalMergeFiles: ['local'], | ||
absolutePath: true, | ||
}); | ||
const configInModuleA = require(`../configNinja`).init(`my-config`); | ||
// In another module we need config again... | ||
const configinModuleB = require('../configNinja'); | ||
const configInModuleB = require(`../configNinja`).use(`my-config`); | ||
// Use our config. | ||
console.dir(configinModuleB); | ||
console.log('Nested Number:', configinModuleB.nested.number); | ||
console.log(`Config:`, configInModuleA); | ||
console.log(`\nNested Number: ${configInModuleB.nested.number}\n`); | ||
console.log(`Plain:`, configInModuleA.__plain()); |
{ | ||
"publishConfig": { | ||
"registry": "https://registry.npmjs.org" | ||
}, | ||
"repository": { | ||
@@ -13,3 +10,3 @@ "type": "git", | ||
"name": "config-ninja", | ||
"version": "0.2.4", | ||
"version": "1.0.0", | ||
"description": "Environmental JSON config.", | ||
@@ -42,5 +39,17 @@ "keywords": [ | ||
"cli-color": "^1.2.0", | ||
"object-extender": "^2.0.3" | ||
"object-extender": "^2.0.3", | ||
"stack-trace": "^0.0.10" | ||
}, | ||
"license": "MIT" | ||
"devDependencies": { | ||
"eslint": "latest", | ||
"eslint-config-recombix": "latest", | ||
"eslint-plugin-filenames": "latest", | ||
"eslint-plugin-json": "latest", | ||
"eslint-plugin-node": "^4.2.1", | ||
"eslint-plugin-promise": "latest" | ||
}, | ||
"license": "MIT", | ||
"engines": { | ||
"node": ">=6" | ||
} | ||
} |
118
README.md
# Config-Ninja | ||
A quick and easy way to read in config files from disk depending on the environment. By default Config Ninja uses the `NODE_ENV` environment variable to determine whether we are running in `production` mode, otherwise `development` mode is assumed. | ||
A quick and easy way to read in config files from disk depending on the environment. By default Config Ninja uses the `NODE_ENV` environment variable to determine whether we are running in `production` mode, `staging`, or any other environment, otherwise `development` mode is assumed. | ||
Once your config has been initialised Config-Ninja allows you to `const config = require('config-ninja');` in any of your modules and get access to your config object. | ||
Once your config has been initialised Config-Ninja allows you to `const config = require('config-ninja').use('my-config');` in any of your modules and get access to your config object. | ||
@@ -9,7 +9,7 @@ **Important:** The `production` config is always the default config. If you specify another environment such as `staging` or `development`, Config Ninja will deep merge the properties from that environment into the production config, overwriting any values that already exist. You can nest properties as deeply as you like. No changes are persisted to disk. | ||
## Quick Start | ||
Create a directory to hold your config files and create a `production.config.json` file which will contain all your configuration. Then create a `development.config.json` file which will hold only the _specific_ values that need to be different in your development environment. Then in your application entry point, e.g. `index.js`: | ||
Create a directory to hold your config files and create a `production.config.json` file which will contain all your configuration properties. Then create a `development.config.json` file which will hold only the _specific_ values that need to be different in your development environment. Then in your application entry point, e.g. `index.js`: | ||
```javascript | ||
// Prepare the ninja on application load. | ||
const config = require('config-ninja').init('/path/to/cfg/dir/'); | ||
const config = require('config-ninja').init('my-config', '/path/to/cfg/dir/'); | ||
``` | ||
@@ -20,3 +20,3 @@ | ||
// Load in the config again, taking advantage of Node's module caching. | ||
const config = require('config-ninja'); | ||
const config = require('config-ninja').use('my-config'); | ||
@@ -28,5 +28,5 @@ // Use the config! | ||
See `example.js` for a working example which you can run with `node ./examples/example`. | ||
**Example:** See `example.js` for a working example which you can run with `node ./examples/example`. | ||
## Setup Config Files | ||
## Setup your Config Files | ||
You will need at least 2 config files, one for `production` and one for `development`. You may also want config files for other environments such as `staging`. You can have as many files as you need. | ||
@@ -42,8 +42,20 @@ | ||
## Local Config | ||
You may also wish to add local config files that are not committed to your repo but must be present on every developer's machine e.g. `local.config.json`. Use the ignore rules for your VCS (e.g. `.gitignore`) to ignore the local files and prevent them from being committed. | ||
By default we assume you might have a local file called `local.config.json`. You can change this by passing in an array of names in the `localConfig` option. If you want to throw an error if any of the specified local config files are missing then set the `requireLocalConfig` option to true. | ||
```javascript | ||
// Default options for local config. | ||
const config = require('config-ninja').use('my-config', { | ||
localConfig: ['local'], | ||
requireLocalConfig: false, | ||
}); | ||
``` | ||
## Override the Environment | ||
By default `production` and `development` environment strings are understood. If you have additional environments you can override the environment string by passing in a second parameter `env`: | ||
By default `production` and `development` environment strings are understood. If you have additional environments you can override the environment string by passing in a third parameter called `env`, which matches the name of your config file (e.g. `staging.config.json`): | ||
```javascript | ||
const config = require('config-ninja').init('/path/to/cfg/dir/', 'staging'); | ||
const config = require('config-ninja').init('my-config', '/path/to/cfg/dir/', 'staging'); | ||
``` | ||
Where `env` matches the name of your config file e.g. `staging.config.json`. | ||
@@ -62,10 +74,4 @@ ## Specify Extra Options | ||
| Option | Default | Description | | ||
|-------------------------|---------|-------------| | ||
| configInFilename | true | Set false if you want to your config filenames to be in the format of `development.json` instead of the default `development.config.json`. | | ||
| setEnvProperty | `{'production': 1, 'staging': 2, 'development': 3 }` | If the property `env` is not already specified in your config files this option will set `env.id` to the environment string e.g. "production", and will set `env.level` to the corresponding integer specified in this option. | | ||
| additionalMergeFiles[] | [] | Specify a list of other filenames to merge into your config, if the files don't exist they will just be ignored. Properties in additional files will overwrite properties with the same name in your config. | | ||
| ignoreMissingAdditional | true | By default we don't throw an error if an additional config file is missing. | | ||
| absolutePath | false | Set true if passing in an absolute directory path to `.init()`. | | ||
## Get a Different Config | ||
@@ -81,26 +87,82 @@ To return a copy of a different config (perhaps for temporary use) call the `get` method. Config-Ninja must have been initialised somewhere before you do this. | ||
## Reserved Property Names | ||
All these property names are reserved by Config-Ninja and cannot be used in the root of your config files. You can however use them as sub properties. | ||
Properties in the top level of your config that begin with two underscores (i.e. `__reload`) are reserved names and should not be used as config properties. | ||
* init | ||
* get | ||
* \_env | ||
* \_cfgPath | ||
* \_options | ||
## API Overview | ||
### .init(configId, dir = './config', env = process.env.NODE_ENV, options = null) | ||
Sets up a new config object and returns it. Any of the following function signatures are acceptable: | ||
* `.init(configId)` | ||
* `.init(configId, dir)` | ||
* `.init(configId, dir, env)` | ||
* `.init(configId, dir, env, options)` | ||
* `.init(configId, dir, options)` | ||
* `.init(configId, options)` | ||
You can specify the following options. You can either pass `dir` and `env` into the function, or add them as options, or rely on the default values. | ||
| Option | Default | Description | | ||
|-------------------------|----------------------|-------------| | ||
| dir | `./config` | Set the directory where your config is stored. Relative paths are relative to the current working directory of your process. | | ||
| env | process.env.NODE_ENV | Set the environment to a specific environment string (e.g. "production"), defaults to process.env.NODE_ENV or "development". | | ||
| shortFilenames | false | Set true if you want to your config filenames to be in the format of `development.json` instead of the default `development.config.json`. | | ||
| environmentLevels | `{ production: 1, staging: 2, development: 3 }` | If the property `env` is not already specified in your config files this option will set `env.id` to the environment string (e.g. "production"), and will set `env.level` to the corresponding integer specified in this option. Pass in a falsy value to disable this feature. | | ||
| localConfig[] | [`local`] | Specify a list of other filenames to merge into your config, if the files don't exist they will just be ignored by default. Properties in local files will overwrite properties with the same name in your config. | | ||
| requireLocalConfig | false | By default we don't throw an error if an additional config file is missing. Set true to throw an error instead. | | ||
| immutable | false | Set true to force the config objects to always be immutable. | | ||
| plain | false | Set true to always construct the config without any of the utility functions attached. | | ||
### .use(configId, immutable = false, plain = false) | ||
Return an existing config object that has been initialised with `.init()`. You can pass true as the second parameter to return a copy of the config, which prevents accidental changes to the config from propagating through to other modules. This has no affect if the `immutable` option was passed to `.init()` as true. You can also pass true as the third parameter if you wish to return a plain copy of the config without the utility functions attached. This has no affect if the `plain` option was passed to `.init()`. | ||
### .wipe(configId) | ||
This will remove the config from memory, allowing you to re-use an existing config id. This will NOT prevent other parts of your application from continuing to use the config if they have already got a copy from `.use()`. | ||
## Config Overview | ||
### config.\_\_inspect() | ||
Returns information about the config object, including some meta data and the options used to initialise the config in `.init()`. | ||
### config.\_\_reload() | ||
Reloads the config files from disk, using the original options passed to `.init()`. Returns the reloaded config, and if the `immutable` option was not set it will also mutate the config object itself. **Warning:** This operation is synchronous and blocking. | ||
### config.\_\_switch(env) | ||
Reloads the config files from disk and switches to the new environment specified, using the original options passed to `.init()`. Returns the new config, and if the `immutable` option was not set it will also mutate the config object itself. **Warning:** This operation is synchronous and blocking. | ||
### config.\_\_addLocal(localConfig) | ||
Reloads the config using the original options passed to `.init()`, but adds in the extra specified local files. Returns the reloaded config, and if the `immutable` option was not set it will also mutate the config object itself. **Warning:** This operation is synchronous and blocking. | ||
### config.\_\_get(env) | ||
Loads and prepares the config for the specified environment, without actually modifying the existing config. Returns the result without mutating the existing config. **Warning:** This operation is synchronous and blocking. | ||
### config.\_\_raw(env) | ||
Returns the raw JSON from the config file for the specified environment (from memory). Does not do any merging and does not mutate the existing config. | ||
### config.\_\_plain() | ||
Returns a copy of the config without any of the utility functions attached. | ||
### config.\_\_trace() | ||
Returns a stack trace for when the config was initialised as an array of strings. Can be used for debugging to see which module instantiated the config. | ||
## FAQ | ||
#### How can I tell which environment string my config was initialised with? | ||
The environment string for a given config variable is stored under `config._env`, so you can simply do `if (config._env === 'production') { ... }`. **Warning:** If any of your config files contain a property called `_env` this will not work. | ||
By default, the `env.id` property will be set inside your config. If you have manually specified `env` in your config or the feature has been disabled (by setting the `localConfig` option) you can use the `config.__inspect()` method: | ||
```javascript | ||
const inspection = config.__inspect(); | ||
console.log(inspection.options.env); | ||
``` | ||
#### How can I reload my config from disk? | ||
Simply call `config.init()` again without any parameters and your config files will be read from disk. **Warning:** Your config files must not contain any of the reserved property names in order for this to work. | ||
Simply call `config.__reload()`. See the Config Overview above. | ||
#### How can I change the environment of my config after initialisation? | ||
Call `config.init(null, 'new-environment-string');` This will reload the config with the new environment set. | ||
Call `config.__switch(env)`. This will reload the config with the new environment set. See the Config Overview above. | ||
#### How can I load in additional config files from disk after initialisation? | ||
Call `config.init(null, null, { additionalMergeFiles: [ ... ] });` This will reload the config with the extra config files merged in. | ||
Call `config.__addLocal(localConfig)` and pass in an array of local config files to load. This will reload the config with the extra config files merged in. See the Config Overview section above. | ||
#### How can I create a code branch that executes on multiple environments? | ||
See the `setEnvProperty` initilisation option. If your config files don't include a property called `env` then Config-Ninja will add in a property with this shape: | ||
See the `localConfig` initilisation option. If your config files do not include a property called `env` then Config-Ninja will add in a property with this shape by default: | ||
```javascript | ||
@@ -107,0 +169,0 @@ { |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
61574
13
422
1
188
3
6
12
1
+ Addedstack-trace@^0.0.10
+ Addedstack-trace@0.0.10(transitive)