cosmiconfig
Advanced tools
Comparing version 2.1.3 to 2.2.0
# Changelog | ||
## 2.2.0 | ||
- Added: `sync` option. | ||
- Fixed: `options.configPath` and `--config` flag are respected. | ||
## 2.1.3 | ||
@@ -4,0 +9,0 @@ |
@@ -20,2 +20,3 @@ 'use strict'; | ||
cache: true, | ||
sync: false, | ||
}, options); | ||
@@ -22,0 +23,0 @@ |
@@ -9,8 +9,10 @@ 'use strict'; | ||
var loadDefinedFile = require('./loadDefinedFile'); | ||
var funcRunner = require('./funcRunner'); | ||
module.exports = function (options) { | ||
// These cache Promises that resolve with results, not the results themselves | ||
// When `options.sync` is `false` (default), | ||
// these cache Promises that resolve with results, not the results themselves. | ||
var fileCache = (options.cache) ? new Map() : null; | ||
var directoryCache = (options.cache) ? new Map() : null; | ||
var transform = options.transform || identityPromise; | ||
var transform = options.transform || (options.sync) ? identitySync : identityPromise; | ||
@@ -31,2 +33,6 @@ function clearFileCache() { | ||
function load(searchPath, configPath) { | ||
if (!configPath && options.configPath) { | ||
configPath = options.configPath; | ||
} | ||
if (configPath) { | ||
@@ -37,4 +43,6 @@ var absoluteConfigPath = path.resolve(process.cwd(), configPath); | ||
} | ||
var result = loadDefinedFile(absoluteConfigPath, options) | ||
.then(transform); | ||
var result = (!options.sync) | ||
? loadDefinedFile(absoluteConfigPath, options) | ||
.then(transform) | ||
: transform(loadDefinedFile(absoluteConfigPath, options)); | ||
if (fileCache) fileCache.set(absoluteConfigPath, result); | ||
@@ -44,13 +52,19 @@ return result; | ||
if (!searchPath) return Promise.resolve(null); | ||
if (!searchPath) return (!options.sync) ? Promise.resolve(null) : null; | ||
var absoluteSearchPath = path.resolve(process.cwd(), searchPath); | ||
return isDirectory(absoluteSearchPath) | ||
.then(function (searchPathIsDirectory) { | ||
var directory = (searchPathIsDirectory) | ||
return (!options.sync) | ||
? isDirectory(absoluteSearchPath) | ||
.then(function (searchPathIsDirectory) { | ||
var directory = (searchPathIsDirectory) | ||
? absoluteSearchPath | ||
: path.dirname(absoluteSearchPath); | ||
return searchDirectory(directory); | ||
}) | ||
: searchDirectory( | ||
isDir.sync(absoluteSearchPath) | ||
? absoluteSearchPath | ||
: path.dirname(absoluteSearchPath); | ||
return searchDirectory(directory); | ||
}); | ||
: path.dirname(absoluteSearchPath) | ||
); | ||
} | ||
@@ -63,28 +77,32 @@ | ||
var result = Promise.resolve() | ||
.then(function () { | ||
if (!options.packageProp) return; | ||
return loadPackageProp(directory, options); | ||
}) | ||
.then(function (result) { | ||
if (result || !options.rc) return result; | ||
return loadRc(path.join(directory, options.rc), options); | ||
}) | ||
.then(function (result) { | ||
if (result || !options.js) return result; | ||
return loadJs(path.join(directory, options.js)); | ||
}) | ||
.then(function (result) { | ||
if (result) return result; | ||
var result = funcRunner( | ||
!options.sync ? Promise.resolve() : undefined, | ||
[ | ||
function () { | ||
if (!options.packageProp) return; | ||
return loadPackageProp(directory, options); | ||
}, | ||
function (result) { | ||
if (result || !options.rc) return result; | ||
return loadRc(path.join(directory, options.rc), options); | ||
}, | ||
function (result) { | ||
if (result || !options.js) return result; | ||
return loadJs(path.join(directory, options.js), options); | ||
}, | ||
function (result) { | ||
if (result) return result; | ||
var splitPath = directory.split(path.sep); | ||
var nextDirectory = (splitPath.length > 1) | ||
? splitPath.slice(0, -1).join(path.sep) | ||
: null; | ||
var splitPath = directory.split(path.sep); | ||
var nextDirectory = (splitPath.length > 1) | ||
? splitPath.slice(0, -1).join(path.sep) | ||
: null; | ||
if (!nextDirectory || directory === options.stopDir) return null; | ||
if (!nextDirectory || directory === options.stopDir) return null; | ||
return searchDirectory(nextDirectory); | ||
}) | ||
.then(transform); | ||
return searchDirectory(nextDirectory); | ||
}, | ||
transform, | ||
] | ||
); | ||
@@ -115,1 +133,5 @@ if (directoryCache) directoryCache.set(directory, result); | ||
} | ||
function identitySync(x) { | ||
return x; | ||
} |
@@ -9,3 +9,3 @@ 'use strict'; | ||
module.exports = function (filepath, options) { | ||
return readFile(filepath, { throwNotFound: true }).then(function (content) { | ||
function parseContent(content) { | ||
var parsedConfig = (function () { | ||
@@ -36,3 +36,8 @@ switch (options.format) { | ||
}; | ||
}); | ||
} | ||
return (!options.sync) | ||
? readFile(filepath, { throwNotFound: true }) | ||
.then(parseContent) | ||
: parseContent(readFile.sync(filepath, { throwNotFound: true })); | ||
}; | ||
@@ -39,0 +44,0 @@ |
@@ -6,4 +6,4 @@ 'use strict'; | ||
module.exports = function (filepath) { | ||
return readFile(filepath).then(function (content) { | ||
module.exports = function (filepath, options) { | ||
function parseJsFile(content) { | ||
if (!content) return null; | ||
@@ -15,3 +15,7 @@ | ||
}; | ||
}); | ||
} | ||
return (!options.sync) | ||
? readFile(filepath).then(parseJsFile) | ||
: parseJsFile(readFile.sync(filepath)); | ||
}; |
@@ -10,3 +10,3 @@ 'use strict'; | ||
return readFile(packagePath).then(function (content) { | ||
function parseContent(content) { | ||
if (!content) return null; | ||
@@ -21,3 +21,7 @@ var parsedContent = parseJson(content, packagePath); | ||
}; | ||
}); | ||
} | ||
return (!options.sync) | ||
? readFile(packagePath).then(parseContent) | ||
: parseContent(readFile.sync(packagePath)); | ||
}; |
@@ -7,12 +7,17 @@ 'use strict'; | ||
var parseJson = require('./parseJson'); | ||
var funcRunner = require('./funcRunner'); | ||
module.exports = function (filepath, options) { | ||
return loadExtensionlessRc().then(function (result) { | ||
function afterLoadExtensionlessRc(result) { | ||
if (result) return result; | ||
if (options.rcExtensions) return loadRcWithExtensions(); | ||
return null; | ||
}); | ||
} | ||
return (!options.sync) | ||
? loadExtensionlessRc().then(afterLoadExtensionlessRc) | ||
: afterLoadExtensionlessRc(loadExtensionlessRc()); | ||
function loadExtensionlessRc() { | ||
return readRcFile().then(function (content) { | ||
function parseExtensionlessRcFile(content) { | ||
if (!content) return null; | ||
@@ -29,7 +34,11 @@ | ||
}; | ||
}); | ||
} | ||
return (!options.sync) | ||
? readRcFile().then(parseExtensionlessRcFile) | ||
: parseExtensionlessRcFile(readRcFile()); | ||
} | ||
function loadRcWithExtensions() { | ||
return readRcFile('json').then(function (content) { | ||
function parseJsonRcFile(content) { | ||
if (content) { | ||
@@ -45,3 +54,5 @@ var successFilepath = filepath + '.json'; | ||
return readRcFile('yaml'); | ||
}).then(function (content) { | ||
} | ||
function parseYmlRcFile(content) { | ||
if (content) { | ||
@@ -59,3 +70,5 @@ // If the previous check returned an object with a config | ||
return readRcFile('yml'); | ||
}).then(function (content) { | ||
} | ||
function parseYamlRcFile(content) { | ||
if (content) { | ||
@@ -70,3 +83,5 @@ if (content.config) return content; | ||
return readRcFile('js'); | ||
}).then(function (content) { | ||
} | ||
function parseJsRcFile(content) { | ||
if (content) { | ||
@@ -81,3 +96,8 @@ if (content.config) return content; | ||
return null; | ||
}); | ||
} | ||
return funcRunner( | ||
readRcFile('json'), | ||
[parseJsonRcFile, parseYmlRcFile, parseYamlRcFile, parseJsRcFile] | ||
); | ||
} | ||
@@ -89,4 +109,6 @@ | ||
: filepath; | ||
return readFile(filepathWithExtension); | ||
return (!options.sync) | ||
? readFile(filepathWithExtension) | ||
: readFile.sync(filepathWithExtension); | ||
} | ||
}; |
@@ -5,3 +5,3 @@ 'use strict'; | ||
module.exports = function (filepath, options) { | ||
function readFile(filepath, options) { | ||
options = options || {}; | ||
@@ -21,2 +21,19 @@ options.throwNotFound = options.throwNotFound || false; | ||
}); | ||
} | ||
readFile.sync = function readFileSync(filepath, options) { | ||
options = options || {}; | ||
options.throwNotFound = options.throwNotFound || false; | ||
try { | ||
return fs.readFileSync(filepath, 'utf8'); | ||
} catch (err) { | ||
if (err.code === 'ENOENT' && !options.throwNotFound) { | ||
return null; | ||
} | ||
throw err; | ||
} | ||
}; | ||
module.exports = readFile; | ||
{ | ||
"name": "cosmiconfig", | ||
"version": "2.1.3", | ||
"version": "2.2.0", | ||
"description": "Find and load configuration from a package.json property, rc file, or CommonJS module", | ||
@@ -27,3 +27,4 @@ "main": "index.js", | ||
"contributors": [ | ||
"Bogdan Chadkin <trysound@yandex.ru>" | ||
"Bogdan Chadkin <trysound@yandex.ru>", | ||
"Suhas Karanth <sudo.suhas@gmail.com>" | ||
], | ||
@@ -37,5 +38,6 @@ "license": "MIT", | ||
"is-directory": "^0.3.1", | ||
"js-yaml": "^3.4.3", | ||
"is-promise": "^2.1.0", | ||
"js-yaml": "^3.9.0", | ||
"minimist": "^1.2.0", | ||
"object-assign": "^4.1.0", | ||
"object-assign": "^4.1.1", | ||
"os-homedir": "^1.0.1", | ||
@@ -46,3 +48,3 @@ "parse-json": "^2.2.0", | ||
"devDependencies": { | ||
"eslint": "^3.13.0", | ||
"eslint": "^4.2.0", | ||
"eslint-config-davidtheclark-node": "^0.2.0", | ||
@@ -52,7 +54,7 @@ "eslint-plugin-node": "^3.0.5", | ||
"lodash": "^4.17.4", | ||
"node-version-check": "^2.1.1", | ||
"nyc": "^10.0.0", | ||
"sinon": "^1.17.7", | ||
"node-version-check": "^2.2.0", | ||
"nyc": "^11.0.3", | ||
"sinon": "^2.3.8", | ||
"tap-spec": "^4.1.1", | ||
"tape": "^4.6.3" | ||
"tape": "^4.7.0" | ||
}, | ||
@@ -59,0 +61,0 @@ "engines": { |
@@ -17,3 +17,3 @@ # cosmiconfig | ||
cosmiconfig continues to search in these places all the way down the file tree until it finds acceptable configuration (or hits the home directory). And it does all this asynchronously, so it shouldn't get in your way. | ||
cosmiconfig continues to search in these places all the way down the file tree until it finds acceptable configuration (or hits the home directory). | ||
@@ -53,2 +53,4 @@ Additionally, all of these search locations are configurable: you can customize filenames or turn off any location. | ||
You can also pass option `sync: true` to load the config synchronously, returning the config itself. | ||
So let's say `var yourModuleName = 'goldengrahams'` — here's how cosmiconfig will work: | ||
@@ -173,10 +175,26 @@ | ||
##### sync | ||
Type: `boolean` | ||
Default: `false` | ||
If `true`, config will be loaded synchronously. | ||
##### transform | ||
Type: `Function` returning a Promise | ||
Type: `Function` | ||
A function that transforms the parsed configuration. Receives the result object with `config` and `filepath` properties, and must return a Promise that resolves with the transformed result. | ||
A function that transforms the parsed configuration. Receives the result object with `config` and `filepath` properties. | ||
If the option `sync` is `false` (default), the function must return a Promise that resolves with the transformed result. | ||
If the option `sync` is `true`, though, `transform` should be a synchronous function which returns the transformed result. | ||
The reason you might use this option instead of simply applying your transform function some other way is that *the transformed result will be cached*. If your transformation involves additional filesystem I/O or other potentially slow processing, you can use this option to avoid repeating those steps every time a given configuration is loaded. | ||
##### configPath | ||
Type: `string` | ||
If provided, cosmiconfig will load and parse a config from this path, and will not perform its usual search. | ||
### Instance methods (on `explorer`) | ||
@@ -223,3 +241,3 @@ | ||
- Options. | ||
- Asynchronicity. | ||
- Asynchronous by default (though can be run synchronously). | ||
@@ -226,0 +244,0 @@ ## Contributing & Development |
25433
13
389
245
8
+ Addedis-promise@^2.1.0
+ Addedis-promise@2.2.2(transitive)
Updatedjs-yaml@^3.9.0
Updatedobject-assign@^4.1.1