replace-in-file
Advanced tools
Comparing version 2.1.0 to 2.2.0
@@ -10,2 +10,38 @@ 'use strict'; | ||
/** | ||
* Defaults | ||
*/ | ||
const defaults = { | ||
allowEmptyPaths: false, | ||
encoding: 'utf-8', | ||
}; | ||
/** | ||
* Parse config | ||
*/ | ||
function parseConfig(config) { | ||
//Validate input | ||
if (typeof config !== 'object' || config === null) { | ||
throw new Error('Must specify configuration object'); | ||
} | ||
if (typeof config.files === 'undefined') { | ||
throw new Error('Must specify file or files'); | ||
} | ||
if (typeof config.replace === 'undefined') { | ||
throw new Error('Must specify string or regex to replace'); | ||
} | ||
if (typeof config.with === 'undefined') { | ||
throw new Error('Must specify a replacement (can be blank string)'); | ||
} | ||
//Use different naming internally as we can't use `with` as a variable name | ||
config.find = config.replace; | ||
config.replace = config.with; | ||
delete config.with; | ||
//Merge config with defaults | ||
return Object.assign({}, defaults, config); | ||
} | ||
/** | ||
* Get replacement helper | ||
@@ -56,6 +92,6 @@ */ | ||
*/ | ||
function replaceSync(file, find, replace) { | ||
function replaceSync(file, find, replace, enc) { | ||
//Read contents | ||
const contents = fs.readFileSync(file, 'utf8'); | ||
const contents = fs.readFileSync(file, enc); | ||
@@ -69,3 +105,3 @@ //Replace contents and check if anything changed | ||
//Write to file | ||
fs.writeFileSync(file, newContents, 'utf8'); | ||
fs.writeFileSync(file, newContents, enc); | ||
return true; | ||
@@ -77,5 +113,5 @@ } | ||
*/ | ||
function replaceAsync(file, find, replace) { | ||
function replaceAsync(file, find, replace, enc) { | ||
return new Promise((resolve, reject) => { | ||
fs.readFile(file, 'utf8', (error, contents) => { | ||
fs.readFile(file, enc, (error, contents) => { | ||
//istanbul ignore if | ||
@@ -93,3 +129,3 @@ if (error) { | ||
//Write to file | ||
fs.writeFile(file, newContents, 'utf8', error => { | ||
fs.writeFile(file, newContents, enc, error => { | ||
//istanbul ignore if | ||
@@ -133,13 +169,20 @@ if (error) { | ||
//Get data | ||
let globs = config.files; | ||
const allowEmpty = config.allowEmptyPaths; | ||
//No array given? | ||
if (!Array.isArray(globs)) { | ||
globs = [globs]; | ||
//Parse config | ||
try { | ||
config = parseConfig(config); | ||
} | ||
catch (error) { | ||
if (cb) { | ||
return cb(error, null); | ||
} | ||
return Promise.reject(error); | ||
} | ||
//Get config and globs | ||
const {files, find, replace, allowEmptyPaths, encoding} = config; | ||
const globs = Array.isArray(files) ? files : [files]; | ||
//Find files | ||
return Promise.all(globs.map(pattern => globPromise(pattern, allowEmpty))) | ||
return Promise | ||
.all(globs.map(pattern => globPromise(pattern, allowEmptyPaths))) | ||
@@ -151,3 +194,3 @@ //Flatten array | ||
.then(files => Promise.all(files.map(file => { | ||
return replaceAsync(file, config.replace, config.with); | ||
return replaceAsync(file, find, replace, encoding); | ||
}))) | ||
@@ -186,13 +229,16 @@ | ||
//No array given? | ||
if (!Array.isArray(config.files)) { | ||
config.files = [config.files]; | ||
} | ||
//Parse config | ||
config = parseConfig(config); | ||
//Get config and globs | ||
const {files, find, replace, encoding} = config; | ||
const globs = Array.isArray(files) ? files : [files]; | ||
const changedFiles = []; | ||
//Process synchronously | ||
const changedFiles = []; | ||
config.files.forEach(file => { | ||
glob.sync(file, {nodir: true}) | ||
globs.forEach(pattern => { | ||
glob | ||
.sync(pattern, {nodir: true}) | ||
.forEach(file => { | ||
if (replaceSync(file, config.replace, config.with)) { | ||
if (replaceSync(file, find, replace, encoding)) { | ||
changedFiles.push(file); | ||
@@ -202,2 +248,4 @@ } | ||
}); | ||
//Return changed files | ||
return changedFiles; | ||
@@ -204,0 +252,0 @@ }; |
{ | ||
"name": "replace-in-file", | ||
"version": "2.1.0", | ||
"version": "2.2.0", | ||
"description": "A simple utility to quickly replace text in one or more files.", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/adamreisnz/replace-in-file#readme", |
@@ -9,3 +9,3 @@ # Replace in file | ||
A simple utility to quickly replace text in one or more files or globs. Works synchronously or asynchronously with either promises or callbacks. | ||
A simple utility to quickly replace text in one or more files or globs. Works synchronously or asynchronously with either promises or callbacks. Make a single replacement or multiple replacements at once. | ||
@@ -44,13 +44,16 @@ ## Installation | ||
//Multiple replacements with the same string (sequentially in order) | ||
//Multiple replacements with the same string (replaced sequentially) | ||
replace: [/foo/g, /baz/g], | ||
with: 'bar', | ||
//Multiple replacements with different strings (sequentially in order) | ||
//Multiple replacements with different strings (replaced sequentially) | ||
replace: [/foo/g, /baz/g], | ||
with: ['bar', 'bax'], | ||
//Specify if empty/invalid file paths are allowed, defaults to false. | ||
//Specify if empty/invalid file paths are allowed (defaults to false) | ||
//If set to true these paths will fail silently and no error will be thrown. | ||
allowEmptyPaths: false, | ||
//Character encoding for reading/writing files (defaults to utf-8) | ||
encoding: 'utf8', | ||
}; | ||
@@ -57,0 +60,0 @@ ``` |
@@ -6,6 +6,6 @@ 'use strict'; | ||
*/ | ||
let replace = require('../lib/replace-in-file'); | ||
let fs = require('fs'); | ||
let writeFile = Promise.promisify(fs.writeFile); | ||
let deleteFile = Promise.promisify(fs.unlink); | ||
const replace = require('../lib/replace-in-file'); | ||
const fs = require('fs'); | ||
const writeFile = Promise.promisify(fs.writeFile); | ||
const deleteFile = Promise.promisify(fs.unlink); | ||
@@ -18,3 +18,3 @@ /** | ||
//Test JSON | ||
let testData = 'a re place c'; | ||
const testData = 'a re place c'; | ||
@@ -44,5 +44,31 @@ /** | ||
/** | ||
* Tests | ||
*/ | ||
it('should throw an error when no config provided', () => { | ||
return expect(replace()).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should throw an error when invalid config provided', () => { | ||
return expect(replace(42)).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should throw an error when no files defined', () => { | ||
return expect(replace({ | ||
replace: /re\splace/g, | ||
with: 'b', | ||
})).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should throw an error when no replace defined', () => { | ||
return expect(replace({ | ||
files: 'test1', | ||
with: 'b', | ||
})).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should throw an error when no with defined', () => { | ||
return expect(replace({ | ||
files: 'test1', | ||
replace: /re\splace/g, | ||
})).to.eventually.be.rejectedWith(Error); | ||
}); | ||
it('should replace contents in a single file with regex', done => { | ||
@@ -222,5 +248,46 @@ replace({ | ||
/** | ||
* Tests | ||
*/ | ||
it('should throw an error when no config provided', done => { | ||
replace(null, (error) => { | ||
expect(error).to.be.instanceof(Error); | ||
done(); | ||
}); | ||
}); | ||
it('should throw an error when invalid config provided', done => { | ||
replace(42, (error) => { | ||
expect(error).to.be.instanceof(Error); | ||
done(); | ||
}); | ||
}); | ||
it('should throw an error when no files defined', done => { | ||
replace({ | ||
replace: /re\splace/g, | ||
with: 'b', | ||
}, (error) => { | ||
expect(error).to.be.instanceof(Error); | ||
done(); | ||
}); | ||
}); | ||
it('should throw an error when no replace defined', done => { | ||
replace({ | ||
files: 'test1', | ||
with: 'b', | ||
}, (error) => { | ||
expect(error).to.be.instanceof(Error); | ||
done(); | ||
}); | ||
}); | ||
it('should throw an error when no with defined', done => { | ||
replace({ | ||
files: 'test1', | ||
replace: /re\splace/g, | ||
}, (error) => { | ||
expect(error).to.be.instanceof(Error); | ||
done(); | ||
}); | ||
}); | ||
it('should replace contents in a single file with regex', done => { | ||
@@ -297,3 +364,3 @@ replace({ | ||
}, (error) => { | ||
expect(error).not.to.equal(null); | ||
expect(error).to.be.instanceof(Error); | ||
done(); | ||
@@ -410,5 +477,41 @@ }); | ||
/** | ||
* Tests | ||
*/ | ||
it('should throw an error when no config provided', () => { | ||
expect(function() { | ||
replace.sync(); | ||
}).to.throw(Error); | ||
}); | ||
it('should throw an error when invalid config provided', () => { | ||
expect(function() { | ||
replace.sync(42); | ||
}).to.throw(Error); | ||
}); | ||
it('should throw an error when no files defined', () => { | ||
expect(function() { | ||
replace.sync({ | ||
replace: /re\splace/g, | ||
with: 'b', | ||
}); | ||
}).to.throw(Error); | ||
}); | ||
it('should throw an error when no replace defined', () => { | ||
expect(function() { | ||
replace.sync({ | ||
files: 'test1', | ||
with: 'b', | ||
}); | ||
}).to.throw(Error); | ||
}); | ||
it('should throw an error when no with defined', () => { | ||
expect(function() { | ||
replace.sync({ | ||
files: 'test1', | ||
replace: /re\splace/g, | ||
}); | ||
}).to.throw(Error); | ||
}); | ||
it('should replace contents in a single file with regex', function() { | ||
@@ -415,0 +518,0 @@ replace.sync({ |
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
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
116143
791
99