@jepz20/conman
Advanced tools
Comparing version 0.0.12 to 0.0.13
{ | ||
"name": "@jepz20/conman", | ||
"version": "0.0.12", | ||
"version": "0.0.13", | ||
"description": "Configuration manager that supports ttl and plugabble sources", | ||
@@ -17,3 +17,3 @@ "main": "./src/conman", | ||
}, | ||
"gitHead": "e742f415a7c1a42cddcff5f619b34a3113681af2", | ||
"gitHead": "520960b62d7a636a1a4c13d5933a06d2aefc852d", | ||
"lint-staged": { | ||
@@ -20,0 +20,0 @@ "src/**/*.*": [ |
@@ -66,3 +66,4 @@ # CONMAN | ||
`conman.build()` builds the configuration object by calling the `build` function from all the added sources and returns promise the resolves when the build is completed and schedules a new build base on the `ttl` option. If `ttl` is `0` a new built is NOT schedule. | ||
`conman.build()` | ||
Build the sources added by the `addSource` method in order from all the added sources and returns promise the resolves when the build is completed and schedules a new build base on the `ttl` option. If `ttl` is `0` a new built is NOT schedule. | ||
@@ -138,10 +139,2 @@ If `useFile` option is true, it will try to read a cache file and write the new config to the cache file. | ||
### stop | ||
`conman.stop()` stops the rebuilt interval schedule base on the TTL | ||
### reset | ||
`conman.reset()` clears all the sources, the configuration cache and resets all defaults options | ||
### getObfuscate | ||
@@ -192,4 +185,10 @@ | ||
## Integrating Conman with ExpressJS | ||
### stop | ||
`conman.stop()` stops the rebuilt interval schedule base on the TTL | ||
### reset | ||
`conman.reset()` clears all the sources, the configuration cache and resets all defaults options | ||
## Creating your own source | ||
@@ -196,0 +195,0 @@ |
@@ -24,87 +24,171 @@ const { mergeDeepRight } = require('ramda'); | ||
const _log = opts => (type, ...args) => { | ||
if (opts.logEnabled) { | ||
opts.logger[type](...args); | ||
} | ||
}; | ||
/** | ||
* Logs only when the option is enabled | ||
* @private | ||
* @param {boolean} isEnabled Should log? | ||
* @param {object} logger Object that atleast a log and error function | ||
* @param logger.log Logs info | ||
* @param logger.error Logs error | ||
* @return {function(string, *)} Function that logs if enabled with the set logger | ||
*/ | ||
function _log(isEnabled, logger) { | ||
return function inner(type, ...args) { | ||
if (isEnabled) { | ||
logger[type](...args); | ||
} | ||
}; | ||
} | ||
function conman(userOptions) { | ||
let sources = []; | ||
let privateCache; | ||
let ttlInterval; | ||
let logger; | ||
let options = { ...defaultOptions, ...userOptions }; | ||
/** | ||
* Format the config to have a timestamp | ||
* @private | ||
* @param {object} tree | ||
*/ | ||
function _prepareCacheObject(tree) { | ||
return { | ||
lastModified: new Date().getTime(), | ||
data: tree | ||
}; | ||
} | ||
logger = _log(options); | ||
const selector = nodeSelector(logger); | ||
/** | ||
* Writes cache object | ||
* @private | ||
* @param {object} cacheObject | ||
* @param {object} opts Options to write file | ||
* @param {string} opts.cacheFileName Filename where to save the file | ||
* @param {object} opts.logger Object that atleast a log and error function | ||
*/ | ||
function _prepareCacheObject(tree) { | ||
return { | ||
lastModified: new Date().getTime(), | ||
data: tree | ||
}; | ||
} | ||
function _writeToFile(cacheObject, opts) { | ||
opts.logger('log', 'Writing conman cache to file'); | ||
return jsonfile | ||
.writeFile(opts.cacheFileName, cacheObject, { | ||
spaces: 2, | ||
EOL: '\r\n' | ||
}) | ||
.then(res => { | ||
opts.logger( | ||
'log', | ||
`Succesfully wrote conman cache to file ${opts.cacheFileName}` | ||
); | ||
return res; | ||
}) | ||
.catch(error => { | ||
opts.logger( | ||
'error', | ||
`Couldn't write cache to file ${opts.cacheFileName}`, | ||
error | ||
); | ||
}); | ||
} | ||
/** | ||
* Calculates if TTL has expired | ||
* @private | ||
* @param {number} lastModified Timestamp when it was last modified | ||
* @param {number} ttl Miliseconds until next expiration | ||
*/ | ||
function _isExpired(lastModified, ttl) { | ||
return new Date().getTime() - lastModified <= ttl; | ||
} | ||
function _writeToFile(cacheObject, opts) { | ||
if (!opts.useFile) { | ||
return Promise.resolve(); | ||
} | ||
logger('log', 'Writing conman cache to file'); | ||
return jsonfile | ||
.writeFile(opts.cacheFileName, cacheObject, { | ||
spaces: 2, | ||
EOL: '\r\n' | ||
}) | ||
.then(res => { | ||
logger( | ||
/** | ||
* Reads file with the cache object | ||
* @private | ||
* @param {object} opts Options to Read file | ||
* @param {string} opts.cacheFileName Filename where to read the file | ||
* @param {object} opts.logger Object with atleast a log and error function | ||
*/ | ||
function _readFromFile(opts) { | ||
return jsonfile | ||
.readFile(opts.cacheFileName) | ||
.then(cache => { | ||
const { lastModified } = cache || {}; | ||
if (_isExpired(lastModified, opts.ttl)) { | ||
opts.logger( | ||
'log', | ||
`Succesfully wrote conman cache to file ${opts.cacheFileName}` | ||
`Succesfully read cache from file ${opts.cacheFileName}` | ||
); | ||
return res; | ||
}) | ||
.catch(error => { | ||
logger( | ||
'error', | ||
`Couldn't write cache to file ${opts.cacheFileName}`, | ||
error | ||
); | ||
}); | ||
return cache.data; | ||
} | ||
return null; | ||
}) | ||
.catch(err => { | ||
opts.logger( | ||
'error', | ||
`Could not read cache config file "${opts.cacheFileName}"`, | ||
err | ||
); | ||
return null; | ||
}); | ||
} | ||
/** | ||
* Validate if a source has all the necessary properties | ||
* @private | ||
* @param {Object} source | ||
*/ | ||
function _validateSource(source) { | ||
if (typeof source.build !== 'function') { | ||
return 'Source should have a build function'; | ||
} | ||
function _isExpired(cache, opts) { | ||
return new Date().getTime() - cache.lastModified <= opts.ttl; | ||
if (!source.type) { | ||
return 'Source should have a type'; | ||
} | ||
return null; | ||
} | ||
/** | ||
* @private | ||
* @param {function} selector function that gets the key from the cache | ||
* @param {sting} key | ||
* @param {object} _privateCache | ||
*/ | ||
function _get(selector, key, _privateCache) { | ||
const safeCache = _privateCache || {}; | ||
if (key === undefined) { | ||
return safeCache; | ||
} | ||
function _readFromFile(opts) { | ||
return jsonfile | ||
.readFile(opts.cacheFileName) | ||
.then(cache => { | ||
if (cache && cache.lastModified && _isExpired(cache, opts)) { | ||
logger( | ||
'log', | ||
`Succesfully read cache from file ${opts.cacheFileName}` | ||
); | ||
return cache.data; | ||
} | ||
return null; | ||
}) | ||
.catch(err => { | ||
logger( | ||
'error', | ||
`Could not read cache config file "${opts.cacheFileName}"`, | ||
err | ||
); | ||
return null; | ||
}); | ||
return selector.query(safeCache || {}, key); | ||
} | ||
/** | ||
* Builds the sources sequencially | ||
* @private | ||
* @param {array} _sources array of sources | ||
*/ | ||
function _buildSources(_sources) { | ||
async function buildSource(config, source) { | ||
const sourceConfig = await source.build(config); | ||
const parseConfig = source.key | ||
? { [source.key]: sourceConfig } | ||
: sourceConfig; | ||
return mergeDeepRight(config, parseConfig); | ||
} | ||
function _validateSource(source) { | ||
if (typeof source.build !== 'function') { | ||
return 'Source should have a build function'; | ||
} | ||
if (!source.type) { | ||
return 'Source should have a type'; | ||
} | ||
return null; | ||
return serialize(_sources, buildSource, {}); | ||
} | ||
/** | ||
* Factory to generate Conman Instances | ||
* @namespace | ||
* @param {Object} userOptions | ||
* @param {number} userOptions.ttl Milliseconds before rebuilding the config | ||
* @param {boolean} userOptions.logEnabled Should it log? | ||
* @param {logger} userOptions.logger Object with atleast a log and error function | ||
* @param {boolean} userOptions.useFile Should it read and write the config to a file | ||
* @param {string} userOptions.cacheFileName Name of the file where cache config will be saved | ||
* @returns {object} | ||
*/ | ||
function conman(userOptions) { | ||
let sources = []; | ||
let privateCache; | ||
let ttlInterval; | ||
let options = { ...defaultOptions, ...userOptions }; | ||
options.logger = _log(options.logEnabled, options.logger); | ||
const selector = nodeSelector(options.logger); | ||
function _setPrivateCache(config) { | ||
privateCache = config; | ||
return config; | ||
} | ||
@@ -121,54 +205,5 @@ | ||
function addSource(source) { | ||
const sourceError = _validateSource(source); | ||
if (sourceError) { | ||
throw new Error(sourceError); | ||
} | ||
logger('log', `Source "${source.type}" added to conman`); | ||
sources.push(source); | ||
return this; | ||
} | ||
function _get(key, _privateCache) { | ||
const safeCache = _privateCache || {} | ||
if (key === undefined) { | ||
return safeCache; | ||
} | ||
return selector.query(safeCache || {}, key); | ||
} | ||
function get(keys) { | ||
if (Array.isArray(keys)) { | ||
return keys.map(key => _get(key, privateCache)); | ||
} | ||
return _get(keys, privateCache); | ||
} | ||
function getObfuscate(keys, params) { | ||
return obfuscate(get(keys), params); | ||
} | ||
function _buildSources(_sources) { | ||
async function buildSource(config, source) { | ||
const sourceConfig = await source.build(config); | ||
const parseConfig = source.key | ||
? { [source.key]: sourceConfig } | ||
: sourceConfig; | ||
return mergeDeepRight(config, parseConfig); | ||
} | ||
return serialize(_sources, buildSource, {}); | ||
} | ||
function _setPrivateCache(config) { | ||
privateCache = config; | ||
return config; | ||
} | ||
async function _buildAndSaveCache(_sources) { | ||
const sourcesTypes = _sources.map(({ name, type }) => name || type); | ||
logger( | ||
options.logger( | ||
'log', | ||
@@ -178,10 +213,44 @@ `Build triggered for sources: "${sourcesTypes.join()}" at ${new Date().toISOString()}` | ||
const configs = await _buildSources(_sources); | ||
logger( | ||
options.logger( | ||
'log', | ||
`Build completed for sources: "${sourcesTypes.join()}" at ${new Date().toISOString()}` | ||
); | ||
await _writeToFile(_prepareCacheObject(configs), options); | ||
if (options.useFile) { | ||
await _writeToFile(_prepareCacheObject(configs), options); | ||
} | ||
return _setPrivateCache(configs); | ||
} | ||
/** | ||
* @function sourceBuild | ||
* @param {object} config - config built by previous sources | ||
* @returns {object} built config by the source | ||
*/ | ||
/** | ||
* Adds a source to the conman instance | ||
* @param {object} source | ||
* @param {sourceBuild} source.build function that receives the config built by previous sources and returns and object | ||
* @param {string} source.type string the identifies the type of source | ||
* @param {string=} source.name string the identifies the specific source | ||
* @param {string=} source.key if a key is provided the result from build will be added to that key | ||
* @returns {object} conman instance | ||
*/ | ||
function addSource(source) { | ||
const sourceError = _validateSource(source); | ||
if (sourceError) { | ||
throw new Error(sourceError); | ||
} | ||
options.logger('log', `Source "${source.type}" added to conman`); | ||
sources.push(source); | ||
return this; | ||
} | ||
/** | ||
* Build the sources added by the `addSource` method in order | ||
* if the useFile flag is set it would read the config from the cache file if it hasn't expired | ||
* if ttl options is not 0 it would rebuild the config in ttl milliseconds | ||
* @returns {Promise<object>} Promise that resolves with the generated config | ||
*/ | ||
async function build() { | ||
@@ -201,7 +270,39 @@ _triggerInterval(); | ||
} | ||
/** | ||
* Gets a single key, an array of keys, or the complete config from the configuration object. | ||
* If you want to retrieve a nested key add a `.` between each key | ||
* @param {(Array<string>|string)=} keys Array of keys or single to key to get from the property | ||
* @returns {(Array<*>|*)} If an array of keys is provided it returns an array of values, if a single key was provided returns the value of that key | ||
*/ | ||
function get(keys) { | ||
if (Array.isArray(keys)) { | ||
return keys.map(key => _get(selector, key, privateCache)); | ||
} | ||
return _get(selector, keys, privateCache); | ||
} | ||
/** | ||
* Behaves exactly as `conman.get` but returns an obfuscated version of the value. | ||
* @param {(Array<string>|string)=} keys Array of keys or single to key to get from the property | ||
* @param {object} params params to obfuscate the values | ||
* @param {float} [0.5] percentage Wercentage of the values that should be obfuscated (replaced by the `character` option | ||
* @param {string} [""] separator Wow to divide the value that will be obfuscated | ||
* @param {string} ["end"] What part of the value to obfuscate `start` or `end` | ||
* @param {string} ["*"] character What character should be used to obfuscate the value | ||
* @returns {(Array<*>|*)} If an array of keys is provided it returns an array of values, if a single key was provided returns the value of that key | ||
*/ | ||
function getObfuscate(keys, params) { | ||
return obfuscate(get(keys), params); | ||
} | ||
/** | ||
* Stops the rebuilt interval schedule base on the TTL | ||
*/ | ||
function stop() { | ||
clearInterval(ttlInterval); | ||
} | ||
/** | ||
* Clears all the sources, the configuration cache and resets all defaults options | ||
*/ | ||
function reset() { | ||
@@ -212,3 +313,2 @@ sources = []; | ||
privateCache = undefined; | ||
logger = undefined; | ||
clearInterval(ttlInterval); | ||
@@ -215,0 +315,0 @@ } |
jest.mock('jsonfile'); | ||
const jsonfile = require('jsonfile'); | ||
const Conman = require('./conman'); | ||
const conman = require('./conman'); | ||
@@ -52,6 +52,6 @@ const source = (obj = {}, { key, name } = {}) => { | ||
it('should work with default options and no sources', async () => { | ||
const conman = Conman(); | ||
const config = await conman.build(); | ||
conman.stop(); | ||
expect(config).toEqual({}); | ||
const config = conman(); | ||
const data = await config.build(); | ||
config.stop(); | ||
expect(data).toEqual({}); | ||
}); | ||
@@ -61,6 +61,6 @@ | ||
const source1 = asyncSource({ test: 'test' }); | ||
const conman = Conman(); | ||
const config = await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(config).toEqual({ test: 'test' }); | ||
const config = conman(); | ||
const data = await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(data).toEqual({ test: 'test' }); | ||
}); | ||
@@ -70,6 +70,6 @@ | ||
const source1 = source({ test: 'test' }, { key: 'TEST' }); | ||
const conman = Conman(); | ||
const config = await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(config).toEqual({ TEST: { test: 'test' } }); | ||
const config = conman(); | ||
const data = await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(data).toEqual({ TEST: { test: 'test' } }); | ||
}); | ||
@@ -80,9 +80,9 @@ | ||
const source2 = source({ test: 'usesConfig' }); | ||
const conman = Conman(); | ||
const config = await conman | ||
const config = conman(); | ||
const data = await config | ||
.addSource(source1) | ||
.addSource(source2) | ||
.build(); | ||
conman.stop(); | ||
expect(config).toEqual({ test: 'usesConfig', extra: 'extra config' }); | ||
config.stop(); | ||
expect(data).toEqual({ test: 'usesConfig', extra: 'extra config' }); | ||
}); | ||
@@ -93,9 +93,9 @@ | ||
const source2 = asyncSource({ test: 'usesConfig' }); | ||
const conman = Conman(); | ||
const config = await conman | ||
const config = conman(); | ||
const data = await config | ||
.addSource(source1) | ||
.addSource(source2) | ||
.build(); | ||
conman.stop(); | ||
expect(config).toEqual({ test: 'usesConfig', extra: 'extra config async' }); | ||
config.stop(); | ||
expect(data).toEqual({ test: 'usesConfig', extra: 'extra config async' }); | ||
}); | ||
@@ -105,6 +105,6 @@ | ||
const source1 = source({ test: 'test async' }); | ||
const conman = Conman(); | ||
const config = await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(config).toEqual({ test: 'test async' }); | ||
const config = conman(); | ||
const data = await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(data).toEqual({ test: 'test async' }); | ||
}); | ||
@@ -115,9 +115,9 @@ | ||
const source2 = source({ test: 'test', test3: 'test3' }); | ||
const conman = Conman(); | ||
const config = await conman | ||
const config = conman(); | ||
const data = await config | ||
.addSource(source1) | ||
.addSource(source2) | ||
.build(); | ||
conman.stop(); | ||
expect(config).toEqual({ test: 'test', test2: 'test2', test3: 'test3' }); | ||
config.stop(); | ||
expect(data).toEqual({ test: 'test', test2: 'test2', test3: 'test3' }); | ||
expect(jsonfile.writeFile).toHaveBeenCalledTimes(1); | ||
@@ -129,6 +129,6 @@ expect(jsonfile.readFile).toHaveBeenCalledTimes(1); | ||
const source1 = source({ test: 'test async' }); | ||
const conman = Conman(); | ||
await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(conman.get('test')).toBe('test async'); | ||
const config = conman(); | ||
await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(config.get('test')).toBe('test async'); | ||
}); | ||
@@ -142,6 +142,6 @@ | ||
}); | ||
const conman = Conman(); | ||
await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(conman.get(['test', 'test2'])).toEqual(['test async', 'test2']); | ||
const config = conman(); | ||
await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(config.get(['test', 'test2'])).toEqual(['test async', 'test2']); | ||
}); | ||
@@ -157,6 +157,6 @@ | ||
}); | ||
const conman = Conman(); | ||
await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(conman.get('test.test2.test3')).toBe('test3'); | ||
const config = conman(); | ||
await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(config.get('test.test2.test3')).toBe('test3'); | ||
}); | ||
@@ -176,13 +176,13 @@ | ||
}); | ||
const conman = Conman(); | ||
await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(conman.getObfuscate('test')).toBe('te**'); | ||
expect(conman.getObfuscate('testUndefined')).toBe(undefined); | ||
expect(conman.getObfuscate('testNull')).toBe(null); | ||
expect(conman.getObfuscate('testNumber')).toBe('12**'); | ||
expect(conman.getObfuscate('testBoolean')).toBe('tr**'); | ||
expect(conman.getObfuscate('testObj')).toEqual({ 'va***': 'v**' }); | ||
expect(conman.getObfuscate('testArr')).toEqual(['ar**', 'ar**']); | ||
expect(conman.getObfuscate(['testObj', 'test'])).toEqual([ | ||
const config = conman(); | ||
await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(config.getObfuscate('test')).toBe('te**'); | ||
expect(config.getObfuscate('testUndefined')).toBe(undefined); | ||
expect(config.getObfuscate('testNull')).toBe(null); | ||
expect(config.getObfuscate('testNumber')).toBe('12**'); | ||
expect(config.getObfuscate('testBoolean')).toBe('tr**'); | ||
expect(config.getObfuscate('testObj')).toEqual({ 'va***': 'v**' }); | ||
expect(config.getObfuscate('testArr')).toEqual(['ar**', 'ar**']); | ||
expect(config.getObfuscate(['testObj', 'test'])).toEqual([ | ||
{ 'va***': 'v**' }, | ||
@@ -201,7 +201,7 @@ 'te**' | ||
}); | ||
const conman = Conman(); | ||
await conman.addSource(source1).build(); | ||
conman.stop(); | ||
const config = conman(); | ||
await config.addSource(source1).build(); | ||
config.stop(); | ||
expect( | ||
conman.getObfuscate('test', { position: 'start', separator: '-' }) | ||
config.getObfuscate('test', { position: 'start', separator: '-' }) | ||
).toBe('***st'); | ||
@@ -218,6 +218,6 @@ }); | ||
}); | ||
const conman = Conman(); | ||
await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(conman.get('test.test2.test4')).toBe(undefined); | ||
const config = conman(); | ||
await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(config.get('test.test2.test4')).toBe(undefined); | ||
}); | ||
@@ -227,6 +227,6 @@ | ||
const source1 = source({ test: 'test async', test2: 'test2' }); | ||
const conman = Conman(); | ||
await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(conman.get()).toEqual({ test: 'test async', test2: 'test2' }); | ||
const config = conman(); | ||
await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(config.get()).toEqual({ test: 'test async', test2: 'test2' }); | ||
}); | ||
@@ -237,7 +237,7 @@ | ||
jest.spyOn(source1, 'build'); | ||
const conman = Conman({ ttl: 1000 }); | ||
await conman.addSource(source1).build(); | ||
const config = conman({ ttl: 1000 }); | ||
await config.addSource(source1).build(); | ||
await new Promise(r => setTimeout(r, 3000)); | ||
conman.stop(); | ||
config.stop(); | ||
expect(source1.build).toHaveBeenCalledTimes(3); | ||
@@ -256,4 +256,4 @@ }); | ||
jest.spyOn(source1, 'build'); | ||
const conman = Conman(options); | ||
await conman.addSource(source1).build(); | ||
const config = conman(options); | ||
await config.addSource(source1).build(); | ||
expect(options.logger.log).toHaveBeenCalled(); | ||
@@ -273,6 +273,6 @@ expect(jsonfile.writeFile).toHaveBeenCalledTimes(0); | ||
}); | ||
const conman = Conman(); | ||
const config = await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(config).toEqual({ | ||
const config = conman(); | ||
const data = await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(data).toEqual({ | ||
test: 'readfromfile' | ||
@@ -290,6 +290,6 @@ }); | ||
}); | ||
const conman = Conman(); | ||
const config = await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(config).toEqual({ | ||
const config = conman(); | ||
const data = await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(data).toEqual({ | ||
test: 'builtfromsource' | ||
@@ -302,9 +302,9 @@ }); | ||
jsonfile.readFile.mockRejectedValueOnce(); | ||
const conman = Conman({ | ||
const config = conman({ | ||
logEnabled: true, | ||
logger | ||
}); | ||
const config = await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(config).toEqual({ | ||
const data = await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(data).toEqual({ | ||
test: 'builtfromsource' | ||
@@ -318,9 +318,9 @@ }); | ||
jsonfile.writeFile.mockRejectedValueOnce(); | ||
const conman = Conman({ | ||
const config = conman({ | ||
logEnabled: true, | ||
logger | ||
}); | ||
const config = await conman.addSource(source1).build(); | ||
conman.stop(); | ||
expect(config).toEqual({ test: 'test', test3: 'test3' }); | ||
const data = await config.addSource(source1).build(); | ||
config.stop(); | ||
expect(data).toEqual({ test: 'test', test3: 'test3' }); | ||
expect(logger.error).toHaveBeenCalledTimes(1); | ||
@@ -330,22 +330,18 @@ }); | ||
it(`should create independent instances with the provider`, async () => { | ||
const instance1 = Conman({ ttl: 0 }); | ||
const instance2 = Conman({ ttl: 0 }); | ||
const conman1 = conman({ ttl: 0 }); | ||
const conman2 = conman({ ttl: 0 }); | ||
await instance1 | ||
.addSource(source({ test: 'instance1' })) | ||
.build(); | ||
await instance2 | ||
.addSource(source({ test: 'instance2' })) | ||
.build(); | ||
await conman1.addSource(source({ test: 'conman1' })).build(); | ||
await conman2.addSource(source({ test: 'conman2' })).build(); | ||
expect(instance1.get()).toEqual({ test: 'instance1' }); | ||
expect(instance2.get()).toEqual({ test: 'instance2' }); | ||
expect(conman1.get()).toEqual({ test: 'conman1' }); | ||
expect(conman2.get()).toEqual({ test: 'conman2' }); | ||
instance1.reset(); | ||
expect(instance1.get()).toEqual({}); | ||
expect(instance2.get()).toEqual({ test: 'instance2' }); | ||
conman1.reset(); | ||
expect(conman1.get()).toEqual({}); | ||
expect(conman2.get()).toEqual({ test: 'conman2' }); | ||
}); | ||
it('should throw an error if the source is missing its build property', async () => { | ||
expect(() => Conman().addSource({ type: 'source' })).toThrow(); | ||
expect(() => conman().addSource({ type: 'source' })).toThrow(); | ||
}); | ||
@@ -355,3 +351,3 @@ | ||
expect(() => | ||
Conman().addSource({ type: 'source', build: 'not a function' }) | ||
conman().addSource({ type: 'source', build: 'not a function' }) | ||
).toThrow(); | ||
@@ -362,3 +358,3 @@ }); | ||
expect(() => | ||
Conman().addSource({ | ||
conman().addSource({ | ||
build() { | ||
@@ -365,0 +361,0 @@ return {}; |
Mixed license
License(Experimental) Package contains multiple licenses.
Found 1 instance in 1 package
1318510
41
1449
1
218