Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@jepz20/conman

Package Overview
Dependencies
Maintainers
1
Versions
11
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@jepz20/conman - npm Package Compare versions

Comparing version 0.0.4 to 0.0.5

.eslintignore

60

package.json
{
"name": "@jepz20/conman",
"version": "0.0.4",
"version": "0.0.5",
"description": "Configuration manager that supports ttl and plugabble sources",
"main": "index.js",
"main": "./src/conman",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "jest",
"coverage": "jest --coverage",
"precommit": "lint-staged",
"lint": "node_modules/.bin/eslint \"**/*.js\" --ignore-path .eslintignore"
},

@@ -14,3 +17,52 @@ "author": "",

},
"gitHead": "62d1fe3df9508bdb270869ce4f8f64bfa40d381a"
"gitHead": "747563d5d0f979b87d9bd1a8d3f94bd6790e33ba",
"lint-staged": {
"src/**/*.*": [
"yarn lint",
"prettier --write",
"git add"
]
},
"dependencies": {
"app-root-path": "^2.2.1",
"jsonfile": "^5.0.0",
"ramda": "^0.26.1"
},
"devDependencies": {
"eslint": "^6.1.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-config-prettier": "^6.0.0",
"eslint-loader": "1.9.0",
"eslint-plugin-import": "2.18.2",
"eslint-plugin-jest": "^22.15.1",
"eslint-plugin-prettier": "2.7.0",
"husky": "^0.14.3",
"jest": "^24.8.0",
"jest-fetch-mock": "^2.1.2",
"jest-junit": "^7.0.0",
"lint-staged": "^7.3.0",
"prettier": "1.18.2",
"prettier-eslint-cli": "4.7.1"
},
"eslintConfig": {
"extends": [
"airbnb-base",
"prettier"
],
"plugins": [
"jest"
],
"rules": {
"no-underscore-dangle": 0,
"no-use-before-define": 0,
"jest/no-disabled-tests": "warn",
"jest/no-focused-tests": "error",
"jest/no-identical-title": "error",
"jest/prefer-to-have-length": "warn",
"jest/valid-expect": "error"
},
"env": {
"jest/globals": true
}
}
}

209

src/conman.js
const { mergeDeepRight } = require('ramda');
const NodeSelector = require('./helpers/nodeSelector');
const jsonfile = require('jsonfile');
const appRoot = require('app-root-path');
const nodeSelector = require('./helpers/nodeSelector');
const obfuscate = require('./helpers/obfuscate');
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const defaultLogger = {
log: console.log,
info: console.log,
debug: console.log,
error: console.log,
warn: console.log
};
const defaultLogger = console;
const cacheFileName = `${appRoot}/conman.cache.json`;
let isInitialized = false;
const sources = [];
let options = {
// TODO CHANGE THIS TO 5 MINUTES
ttl: 10 * SECOND,
logEnabled: true,
logger: defaultLogger
const defaultOptions = {
ttl: 5 * MINUTE,
logEnabled: false,
logger: defaultLogger,
useFile: true,
cacheFileName
};
let privateCache = {};
let conman;
let sources = [];
let options = defaultOptions;
let privateCache;
let ttlInterval;
let selector;
let logger;
function _prepareCacheObject(tree) {
return {
lastModified: new Date().getTime(),
data: tree
};
}
const _log = opts => (type, ...args) => {
if (opts.logEnabled) {
opts.logger[type](...args);
}
};
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(
'log',
`Succesfully wrote conman cache to file ${opts.cacheFileName}`
);
return res;
})
.catch(error => {
logger(
'error',
`Couldn't write cache to file ${opts.cacheFileName}`,
error
);
});
}
function _isExpired(cache, opts) {
return new Date().getTime() - cache.lastModified <= opts.ttl;
}
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;
});
}
function _validateSource(source) {

@@ -37,3 +107,3 @@ if (typeof source.build !== 'function') {

function _ttl() {
function _triggerInterval() {
clearInterval(ttlInterval);

@@ -43,2 +113,3 @@ if (options.ttl <= 0) {

}
ttlInterval = setInterval(build, options.ttl);

@@ -48,5 +119,6 @@ }

function _init(userOptions = {}) {
options = { ...options, ...userOptions };
options = { ...defaultOptions, ...userOptions };
logger = _log(options);
isInitialized = true;
selector = new NodeSelector(options);
selector = nodeSelector(logger);
return conman;

@@ -60,3 +132,3 @@ }

}
options.logger.info(`Source "${source.type}" added to conman`);
logger('log', `Source "${source.type}" added to conman`);
sources.push(source);

@@ -66,41 +138,94 @@ return conman;

function get(key) {
function _get(key, _privateCache) {
if (key === undefined) {
return _privateCache;
}
return selector.query(_privateCache, key);
}
function get(keys) {
if (!isInitialized) {
throw new Error('Conman has not been initialize');
}
if (key === undefined) {
return privateCache;
if (Array.isArray(keys)) {
return keys.map(key => _get(key, privateCache));
}
return selector.query(privateCache, key);
return _get(keys, privateCache);
}
function build() {
const sourcesTypes = sources.map(({ name, type }) => name || type);
options.logger.info(
function getObfuscate(keys, params) {
return obfuscate(get(keys), params);
}
function _buildSources(_sources) {
const sourcesTypes = _sources.map(({ name, type }) => name || type);
logger(
'log',
`Build triggered for sources: "${sourcesTypes.join()}" at ${new Date().toISOString()}`
);
_ttl();
return Promise.all(sources.map(source => source.build()))
.then(configs => {
return configs.reduce((acc, config) => {
acc = mergeDeepRight(acc, config);
return acc;
});
})
.then(configs => {
options.logger.info(
`Build completed for sources: "${sourcesTypes.join()}" at ${new Date().toISOString()}`
);
return setPrivateCache(configs);
});
return Promise.all(_sources.map(source => source.build())).then(configs => {
logger(
'log',
`Build completed for sources: "${sourcesTypes.join()}" at ${new Date().toISOString()}`
);
return configs.reduce((acc, config) => {
return mergeDeepRight(acc, config);
}, {});
});
}
function setPrivateCache(config) {
function _setPrivateCache(config) {
privateCache = config;
return config;
}
const conman = _init;
function _buildAndSaveCache(_sources) {
return _buildSources(_sources).then(configs => {
return _writeToFile(_prepareCacheObject(configs), options).then(() =>
_setPrivateCache(configs)
);
});
}
function build() {
_triggerInterval();
// read from file if its the first build
if (!privateCache && options.useFile) {
return _readFromFile(options).then(cache => {
if (!cache) {
return _buildAndSaveCache(sources);
}
return _setPrivateCache(cache);
});
}
return _buildAndSaveCache(sources);
}
function stop() {
clearInterval(ttlInterval);
}
function reset() {
sources = [];
options = defaultOptions;
isInitialized = false;
ttlInterval = undefined;
privateCache = undefined;
logger = undefined;
clearInterval(ttlInterval);
}
conman = _init;
conman.build = build;
conman.stop = stop;
conman.reset = reset;
conman.addSource = addSource;
conman.get = get;
conman.getObfuscate = getObfuscate;
module.exports = conman;

@@ -1,3 +0,1 @@

'use strict';
/**

@@ -8,4 +6,31 @@ * Node Selector traverses a tree structure and fetches the value of a node,

function nodeSelector(options) {
query(tree, property) {
/**
* Private helper function to iterate over tree recursively.
*
* @param {object} tree
* @param {string} property
* @return {Mixed}
*/
function _query(tree, property) {
const propertyNameParts = Array.isArray(property)
? property
: property.split('.');
const name = propertyNameParts[0];
const value = tree[name];
if (propertyNameParts.length <= 1) {
return value;
}
// Note that typeof null === 'object'
if (value === null || typeof value !== 'object') {
return undefined;
}
return _query(value, propertyNameParts.slice(1));
}
function nodeSelector(logger) {
function query(tree, property) {
if (tree === null || tree === undefined) {

@@ -23,6 +48,6 @@ throw new Error(

var value = _query(tree, property);
const value = _query(tree, property);
if (value === undefined) {
options.logger.error('Property "' + property + '" is not defined.');
logger('log', `Property "${property}" is not defined.`);
}

@@ -34,31 +59,5 @@

query
}
};
}
/**
* Private helper function to iterate over tree recursively.
*
* @param {object} tree
* @param {string} property
* @return {Mixed}
*/
function _query(tree, property) {
let propertyNameParts = Array.isArray(property)
? property
: property.split('.'),
name = propertyNameParts[0],
value = tree[name];
if (propertyNameParts.length <= 1) {
return value;
}
// Note that typeof null === 'object'
if (value === null || typeof value !== 'object') {
return undefined;
}
return _query(value, propertyNameParts.slice(1));
}
module.exports = nodeSelector;
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc