+176
| // Generated by CoffeeScript 1.7.1 | ||
| (function() { | ||
| 'use strict'; | ||
| var Promise, appdirs, configure, confmerge, jsyaml, path, processDirectory, processPath, readFile, readdir, stat, _ref; | ||
| Promise = (require('es6-promise')).Promise; | ||
| appdirs = require('appdirs'); | ||
| confmerge = require('./confmerge'); | ||
| jsyaml = require('js-yaml'); | ||
| path = require('path'); | ||
| _ref = require('./fs-promise'), readFile = _ref.readFile, stat = _ref.stat, readdir = _ref.readdir; | ||
| /* | ||
| Process configuration files. | ||
| @param {String} environment Environment to select. | ||
| @param {String} directory Directory to process configuration files. | ||
| @param {*} preConfig Base configuration to start with. | ||
| @param {*} postConfig Config to merge on top of final result. | ||
| @return {Promise<Object>} Consolidated configuration object. | ||
| */ | ||
| configure = function(_arg) { | ||
| var directory, envDirectory, environment, postConfig, preConfig; | ||
| environment = _arg.environment, directory = _arg.directory, preConfig = _arg.preConfig, postConfig = _arg.postConfig; | ||
| if (environment == null) { | ||
| environment = process.env.NODE_ENV || 'development'; | ||
| } | ||
| if (directory == null) { | ||
| directory = 'config'; | ||
| } | ||
| if (preConfig == null) { | ||
| preConfig = {}; | ||
| } | ||
| if (postConfig == null) { | ||
| postConfig = {}; | ||
| } | ||
| envDirectory = function(dir) { | ||
| if (dir) { | ||
| return path.join(dir, "" + environment + ".env"); | ||
| } | ||
| }; | ||
| return processDirectory(directory, preConfig).then(function(baseConfig) { | ||
| return processDirectory(envDirectory(directory), baseConfig); | ||
| }).then(function(baseEnvConfig) { | ||
| var a, app, appAuthor, appName; | ||
| app = baseEnvConfig.appdirs || {}; | ||
| appName = app.appName; | ||
| appAuthor = app.appAuthor; | ||
| if (appName) { | ||
| a = new appdirs.AppDirs(appName, appAuthor); | ||
| if (app.siteConfigDir == null) { | ||
| app.siteConfigDir = a.siteConfigDir(); | ||
| } | ||
| if (app.siteDataDir == null) { | ||
| app.siteDataDir = a.siteDataDir(); | ||
| } | ||
| if (app.userCacheDir == null) { | ||
| app.userCacheDir = a.userCacheDir(); | ||
| } | ||
| if (app.userConfigDir == null) { | ||
| app.userConfigDir = a.userConfigDir(); | ||
| } | ||
| if (app.userDataDir == null) { | ||
| app.userDataDir = a.userDataDir(); | ||
| } | ||
| if (app.userLogDir == null) { | ||
| app.userLogDir = a.userLogDir(); | ||
| } | ||
| } | ||
| return processDirectory(app.siteConfigDir, baseEnvConfig).then(function(siteConfig) { | ||
| return processDirectory(envDirectory(app.siteConfigDir), siteConfig); | ||
| }).then(function(siteEnvConfig) { | ||
| return processDirectory(app.userConfigDir, siteEnvConfig); | ||
| }).then(function(userConfig) { | ||
| return processDirectory(envDirectory(app.userConfigDir), userConfig); | ||
| }).then(function(userEnvConfig) { | ||
| return confmerge(userEnvConfig, postConfig); | ||
| }); | ||
| }).then(function(finalConfig) { | ||
| finalConfig.environment = environment; | ||
| return finalConfig; | ||
| }); | ||
| }; | ||
| /* | ||
| Process a directory for configuration files, merging with baseConfig. | ||
| Each file and subdirectory in `directory` is merged with the field in | ||
| `baseConfig` of the corresponding name. | ||
| @param {String} directory - Directory to parse configuration files from. | ||
| @param {Object} baseConfig - Base configuration to merge into. | ||
| @return {Promise<Object>} Resulting merged configuration. | ||
| @private | ||
| */ | ||
| processDirectory = function(directory, baseConfig) { | ||
| if (!directory) { | ||
| return Promise.resolve(baseConfig); | ||
| } else { | ||
| return readdir(directory).then(function(dir) { | ||
| return Promise.all(dir.map(function(file) { | ||
| return processPath(directory, file); | ||
| })); | ||
| }).then(function(res) { | ||
| return res.reduce(confmerge, baseConfig); | ||
| })["catch"](function(err) { | ||
| if (err.code !== 'ENOENT') { | ||
| console.error("Error reading directory: " + err.message); | ||
| throw err; | ||
| } | ||
| return Promise.resolve(baseConfig); | ||
| }); | ||
| } | ||
| }; | ||
| /* | ||
| Process a configuration file, or directory of files. A Promise of its | ||
| corresponding configuration object is returned. | ||
| @param basedir Directory `file` is in. | ||
| @param file Name of the file to parse. | ||
| @return {Promise<Object>} Resulting merged configuration. | ||
| @private | ||
| */ | ||
| processPath = function(basedir, file) { | ||
| var basename, ext; | ||
| ext = path.extname(file); | ||
| basename = path.basename(file, ext); | ||
| file = path.join(basedir, file); | ||
| if (ext === '.json') { | ||
| return readFile(file).then(function(contents) { | ||
| var res; | ||
| res = {}; | ||
| res[basename] = JSON.parse(contents); | ||
| return res; | ||
| }); | ||
| } else if (ext === '.yaml') { | ||
| return readFile(file).then(function(contents) { | ||
| var res; | ||
| res = {}; | ||
| res[basename] = jsyaml.safeLoad(contents); | ||
| return res; | ||
| }); | ||
| } else if (ext === '.env') { | ||
| return Promise.resolve({}); | ||
| } else { | ||
| return stat(file).then(function(stats) { | ||
| if (stats.isDirectory()) { | ||
| return processDirectory(file, {}); | ||
| } else { | ||
| console.error("Unrecognized file type '" + file + "'"); | ||
| return {}; | ||
| } | ||
| }).then(function(subConfig) { | ||
| var res; | ||
| res = {}; | ||
| res[basename] = subConfig; | ||
| return res; | ||
| }); | ||
| } | ||
| }; | ||
| module.exports = configure; | ||
| }).call(this); |
| // Generated by CoffeeScript 1.7.1 | ||
| (function() { | ||
| 'use strict'; | ||
| var confmerge, isPojo, _; | ||
| _ = require('lodash'); | ||
| /* | ||
| Determines whether an object is a plain old JavaScript object (meaning not an | ||
| array, function, etc.) | ||
| @param {*} obj - Object to test. | ||
| @return {Boolean} - True if obj is a POJO. | ||
| @private | ||
| */ | ||
| isPojo = function(obj) { | ||
| return _.isObject(obj) && !(_.isArray(obj) || _.isFunction(obj) || _.isRegExp(obj) || _.isNumber(obj) || _.isString(obj)); | ||
| }; | ||
| /* | ||
| Merge a source object into the target object. | ||
| Only POJO's can be merged. If either object is a non-POJO, then the value of | ||
| source is simply returned. | ||
| @param {*} target - Destination object to merge into. | ||
| @param {*} source - Source object to merge from. | ||
| @return {*} - Newly merged value for target. | ||
| */ | ||
| confmerge = function(target, source) { | ||
| var key, value; | ||
| if (isPojo(target) && isPojo(source)) { | ||
| for (key in source) { | ||
| value = source[key]; | ||
| target[key] = confmerge(target[key], value); | ||
| } | ||
| return target; | ||
| } else { | ||
| return source; | ||
| } | ||
| }; | ||
| module.exports = confmerge; | ||
| }).call(this); |
| // Generated by CoffeeScript 1.7.1 | ||
| (function() { | ||
| 'use strict'; | ||
| var Promise, fs; | ||
| Promise = (require('es6-promise')).Promise; | ||
| fs = require('fs'); | ||
| /* | ||
| Read a UTF-8 text file, returning a promise with the file's contents. | ||
| @param {String} path Path of the file to read. | ||
| @return {Promise<String>} Contents of the file. | ||
| @private | ||
| */ | ||
| exports.readFile = function(path) { | ||
| return new Promise(function(resolve, reject) { | ||
| return fs.readFile(path, 'utf-8', function(err, contents) { | ||
| if (err) { | ||
| return reject(err); | ||
| } else { | ||
| return resolve(contents); | ||
| } | ||
| }); | ||
| }); | ||
| }; | ||
| /* | ||
| Promise returning version of `fs.stat`. | ||
| @param {String} path Path of the file to stat. | ||
| @return {Promise<fs.Stat>} File's stat structure. | ||
| @private | ||
| */ | ||
| exports.stat = function(path) { | ||
| return new Promise(function(resolve, reject) { | ||
| return fs.stat(path, function(err, stat) { | ||
| if (err) { | ||
| return reject(err); | ||
| } else { | ||
| return resolve(stat); | ||
| } | ||
| }); | ||
| }); | ||
| }; | ||
| /* | ||
| Promise returning version of `fs.readdir`. | ||
| @param {String} directory Directory to read. | ||
| @return {Promise<Array<String>>} Filenames in the given directory. | ||
| @private | ||
| */ | ||
| exports.readdir = function(directory) { | ||
| return new Promise(function(resolve, reject) { | ||
| return fs.readdir(directory, function(err, dir) { | ||
| if (err) { | ||
| return reject(err); | ||
| } else { | ||
| return resolve(dir); | ||
| } | ||
| }); | ||
| }); | ||
| }; | ||
| }).call(this); |
+19
| // Generated by CoffeeScript 1.7.1 | ||
| (function() { | ||
| 'use strict'; | ||
| /* | ||
| Parfait.js loader. | ||
| */ | ||
| var configure, confmerge; | ||
| configure = require('./configure'); | ||
| confmerge = require('./confmerge'); | ||
| module.exports = { | ||
| configure: configure, | ||
| confmerge: confmerge | ||
| }; | ||
| }).call(this); |
+2
-3
| /** | ||
| * Helper for loading from JavaScript. | ||
| * Load the compiled JavaScript. | ||
| */ | ||
| require('coffee-script/register'); | ||
| module.exports = require('./src'); | ||
| module.exports = require('./lib'); |
+6
-2
| { | ||
| "name": "parfait", | ||
| "version": "0.7.7", | ||
| "version": "0.8.0", | ||
| "author": "David M. Lee, II <leedm777@yahoo.com>", | ||
@@ -8,4 +8,8 @@ "description": "A sweet multi-layered configuration framework", | ||
| "scripts": { | ||
| "build": "coffee --compile --output lib src", | ||
| "clean": "rm -rf lib/ doc/ coverage.html coverage.json", | ||
| "doc": "codo", | ||
| "lint": "coffeelint src test", | ||
| "postpublish": "npm run clean", | ||
| "prepublish": "npm run build", | ||
| "test": "mocha", | ||
@@ -25,3 +29,2 @@ "test-coverage": "COVERAGE=true mocha -R html-cov 'test/**/*.spec.coffee' > coverage.html", | ||
| "appdirs": "^0.1.1", | ||
| "coffee-script": "^1.7.1", | ||
| "es6-promise": "^1.0.0", | ||
@@ -35,2 +38,3 @@ "js-yaml": "^3.0.1", | ||
| "chai-as-promised": "^4.1.0", | ||
| "coffee-script": "^1.7.1", | ||
| "codo": "^2.0.6", | ||
@@ -37,0 +41,0 @@ "coffeelint": "^1.3.0", |
| # Copyright (c) 2014. David M. Lee, II <leedm777@yahoo.com> | ||
| 'use strict' | ||
| Promise = (require 'es6-promise').Promise | ||
| appdirs = require 'appdirs' | ||
| confmerge = require './confmerge' | ||
| jsyaml = require 'js-yaml' | ||
| path = require 'path' | ||
| {readFile, stat, readdir} = require './fs-promise' | ||
| ### | ||
| Process configuration files. | ||
| @param {String} environment Environment to select. | ||
| @param {String} directory Directory to process configuration files. | ||
| @param {*} preConfig Base configuration to start with. | ||
| @param {*} postConfig Config to merge on top of final result. | ||
| @return {Promise<Object>} Consolidated configuration object. | ||
| ### | ||
| configure = ({environment, directory, preConfig, postConfig}) -> | ||
| environment ?= (process.env && process.env.NODE_ENV) || 'development' | ||
| directory ?= 'config' | ||
| preConfig ?= {} | ||
| postConfig ?= {} | ||
| envDirectory = (dir) -> | ||
| if dir | ||
| path.join dir, "#{environment}.env" | ||
| # Apply the base config to the hard coded preConfig | ||
| processDirectory directory, preConfig | ||
| .then (baseConfig) -> | ||
| # Now the environment specific base config | ||
| processDirectory envDirectory(directory), baseConfig | ||
| .then (baseEnvConfig) -> | ||
| app = baseEnvConfig.appdirs || {} | ||
| appName = app.appName | ||
| appAuthor = app.appAuthor | ||
| if appName | ||
| a = new appdirs.AppDirs(appName, appAuthor) | ||
| app.siteConfigDir ?= a.siteConfigDir() | ||
| app.siteDataDir ?= a.siteDataDir() | ||
| app.userCacheDir ?= a.userCacheDir() | ||
| app.userConfigDir ?= a.userConfigDir() | ||
| app.userDataDir ?= a.userDataDir() | ||
| app.userLogDir ?= a.userLogDir() | ||
| # Now the site config | ||
| processDirectory app.siteConfigDir, baseEnvConfig | ||
| .then (siteConfig) -> | ||
| # Now the environment specific site config | ||
| processDirectory envDirectory(app.siteConfigDir), siteConfig | ||
| .then (siteEnvConfig) -> | ||
| # Now the user config | ||
| processDirectory app.userConfigDir, siteEnvConfig | ||
| .then (userConfig) -> | ||
| # Now the environment specific user config | ||
| processDirectory envDirectory(app.userConfigDir), userConfig | ||
| .then (userEnvConfig) -> | ||
| confmerge userEnvConfig, postConfig | ||
| .then (finalConfig) -> | ||
| finalConfig.environment = environment | ||
| finalConfig | ||
| ### | ||
| Process a directory for configuration files, merging with baseConfig. | ||
| Each file and subdirectory in `directory` is merged with the field in | ||
| `baseConfig` of the corresponding name. | ||
| @param {String} directory - Directory to parse configuration files from. | ||
| @param {Object} baseConfig - Base configuration to merge into. | ||
| @return {Promise<Object>} Resulting merged configuration. | ||
| @private | ||
| ### | ||
| processDirectory = (directory, baseConfig) -> | ||
| if not directory | ||
| Promise.resolve baseConfig | ||
| else | ||
| readdir directory | ||
| .then (dir) -> | ||
| Promise.all dir.map (file) -> process(directory, file) | ||
| .then (res) -> | ||
| res.reduce confmerge, baseConfig | ||
| .catch (err) -> | ||
| # Missing directories are fine; just return the base config | ||
| if err.code != 'ENOENT' | ||
| console.error "Error reading directory: #{err.message}" | ||
| throw err | ||
| Promise.resolve baseConfig | ||
| ### | ||
| Process a configuration file, or directory of files. A Promise of its | ||
| corresponding configuration object is returned. | ||
| @param basedir Directory `file` is in. | ||
| @param file Name of the file to parse. | ||
| @return {Promise<Object>} Resulting merged configuration. | ||
| @private | ||
| ### | ||
| process = (basedir, file) -> | ||
| ext = path.extname file | ||
| basename = path.basename file, ext | ||
| file = path.join basedir, file | ||
| if ext == '.json' | ||
| readFile file | ||
| .then (contents) -> | ||
| res = {} | ||
| res[basename] = JSON.parse(contents) | ||
| res | ||
| else if ext == '.yaml' | ||
| readFile file | ||
| .then (contents) -> | ||
| res = {} | ||
| res[basename] = jsyaml.safeLoad(contents) | ||
| res | ||
| else if ext == '.env' | ||
| # Environment; skip | ||
| Promise.resolve {} | ||
| else | ||
| stat file | ||
| .then (stats) -> | ||
| if stats.isDirectory() | ||
| processDirectory file, {} | ||
| else | ||
| console.error "Unrecognized file type '#{file}'" | ||
| {} | ||
| .then (subConfig) -> | ||
| res = {} | ||
| res[basename] = subConfig | ||
| res | ||
| module.exports = configure |
| # Copyright (c) 2014. David M. Lee, II <leedm777@yahoo.com> | ||
| 'use strict' | ||
| _ = require('lodash') | ||
| ### | ||
| Determines whether an object is a plain old JavaScript object (meaning not an | ||
| array, function, etc.) | ||
| @param {*} obj - Object to test. | ||
| @return {Boolean} - True if obj is a POJO. | ||
| @private | ||
| ### | ||
| isPojo = (obj) -> | ||
| _.isObject(obj) and not ( | ||
| _.isArray(obj) or | ||
| _.isFunction(obj) or | ||
| _.isRegExp(obj) or | ||
| _.isNumber(obj) or | ||
| _.isString(obj) | ||
| ) | ||
| ### | ||
| Merge a source object into the target object. | ||
| Only POJO's can be merged. If either object is a non-POJO, then the value of | ||
| source is simply returned. | ||
| @param {*} target - Destination object to merge into. | ||
| @param {*} source - Source object to merge from. | ||
| @return {*} - Newly merged value for target. | ||
| ### | ||
| confmerge = (target, source) -> | ||
| if isPojo(target) and isPojo(source) | ||
| # Both objects are POJOs; merge them! | ||
| for key, value of source | ||
| target[key] = confmerge target[key], value | ||
| target | ||
| else | ||
| # One or both objects are not a POJO; they can't possibly be merged. | ||
| # Replace target with source instead. | ||
| source | ||
| module.exports = confmerge |
| # Copyright (c) 2014. David M. Lee, II <leedm777@yahoo.com> | ||
| 'use strict' | ||
| Promise = (require 'es6-promise').Promise | ||
| fs = require 'fs' | ||
| ### | ||
| Read a UTF-8 text file, returning a promise with the file's contents. | ||
| @param {String} path Path of the file to read. | ||
| @return {Promise<String>} Contents of the file. | ||
| @private | ||
| ### | ||
| exports.readFile = (path) -> | ||
| new Promise (resolve, reject) -> | ||
| fs.readFile path, 'utf-8', (err, contents) -> | ||
| if (err) | ||
| reject err | ||
| else | ||
| resolve contents | ||
| ### | ||
| Promise returning version of `fs.stat`. | ||
| @param {String} path Path of the file to stat. | ||
| @return {Promise<fs.Stat>} File's stat structure. | ||
| @private | ||
| ### | ||
| exports.stat = (path) -> | ||
| new Promise (resolve, reject) -> | ||
| fs.stat path, (err, stat) -> | ||
| if (err) | ||
| reject err | ||
| else | ||
| resolve stat | ||
| ### | ||
| Promise returning version of `fs.readdir`. | ||
| @param {String} directory Directory to read. | ||
| @return {Promise<Array<String>>} Filenames in the given directory. | ||
| @private | ||
| ### | ||
| exports.readdir = (directory) -> | ||
| new Promise (resolve, reject) -> | ||
| fs.readdir directory, (err, dir) -> | ||
| if (err) | ||
| reject err | ||
| else | ||
| resolve dir |
| # Copyright (c) 2014. David M. Lee, II <leedm777@yahoo.com> | ||
| 'use strict' | ||
| ### | ||
| Parfait.js loader. | ||
| ### | ||
| configure = require './configure' | ||
| confmerge = require './confmerge' | ||
| module.exports = { configure, confmerge } |
Sorry, the diff of this file is not supported yet
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
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
16325
12.84%4
-20%311
547.92%8
14.29%2
Infinity%1
Infinity%- Removed
- Removed