replace-in-file
Advanced tools
Comparing version 8.2.0 to 8.3.0
{ | ||
"name": "replace-in-file", | ||
"type": "module", | ||
"version": "8.2.0", | ||
"version": "8.3.0", | ||
"description": "A simple utility to quickly replace text in one or more files.", | ||
@@ -6,0 +6,0 @@ "homepage": "https://github.com/adamreisnz/replace-in-file#readme", |
@@ -371,6 +371,6 @@ # Replace in file | ||
//To include hidden files (starting with a dot) | ||
dot: true, | ||
dot: true, | ||
//To fix paths on Windows OS when path.join() is used to create paths | ||
windowsPathsNoEscape: true, | ||
windowsPathsNoEscape: true, | ||
}, | ||
@@ -441,2 +441,14 @@ } | ||
Alongside the `processor`, there is also `processorAsync` which is the equivalent for asynchronous processing. It should return a promise that resolves with the processed content: | ||
```js | ||
const results = await replaceInFile({ | ||
files: 'path/to/files/*.html', | ||
processorAsync: async (input, file) => { | ||
const asyncResult = await doAsyncOperation(input, file); | ||
return input.replace(/foo/g, asyncResult) | ||
}, | ||
}) | ||
``` | ||
### Using a custom file system API | ||
@@ -443,0 +455,0 @@ `replace-in-file` defaults to using `'node:fs/promises'` and `'node:fs'` to provide file reading and write APIs. |
@@ -58,3 +58,3 @@ import path from 'node:path' | ||
//Extract data | ||
const {files, getTargetFile, from, to, processor, ignore, encoding} = config | ||
const {files, getTargetFile, from, to, processor, processorAsync, ignore, encoding} = config | ||
if (typeof processor !== 'undefined') { | ||
@@ -65,2 +65,7 @@ if (typeof processor !== 'function' && !Array.isArray(processor)) { | ||
} | ||
else if (typeof processorAsync !== 'undefined') { | ||
if (typeof processorAsync !== 'function' && !Array.isArray(processorAsync)) { | ||
throw new Error(`ProcessorAsync should be either a function or an array of functions`) | ||
} | ||
} | ||
else { | ||
@@ -67,0 +72,0 @@ if (typeof files === 'undefined') { |
@@ -99,2 +99,11 @@ import {expect, use, should} from 'chai' | ||
it('should error when an invalid `processorAsync` is specified', () => { | ||
expect(() => parseConfig({ | ||
processorAsync: 'foo', | ||
files: ['test1', 'test2', 'test3'], | ||
from: [/re/g, /place/g], | ||
to: ['b'], | ||
})).to.throw(Error) | ||
}) | ||
it('should error when `files` are not specified', () => { | ||
@@ -101,0 +110,0 @@ expect(() => parseConfig({ |
@@ -44,2 +44,24 @@ | ||
/** | ||
* Run processors (async) | ||
*/ | ||
export async function runProcessorsAsync(contents, processorAsync, file) { | ||
//Ensure array and prepare result | ||
const processorAsyncs = Array.isArray(processorAsync) ? processorAsync : [processorAsync] | ||
//Run processors | ||
let newContents = contents | ||
for (const processor of processorAsyncs) { | ||
newContents = await processor(newContents, file) | ||
} | ||
//Check if contents changed and prepare result | ||
const hasChanged = (newContents !== contents) | ||
const result = {file, hasChanged} | ||
//Return along with new contents | ||
return [result, newContents] | ||
} | ||
/** | ||
* Helper to process in a single file (async) | ||
@@ -54,3 +76,3 @@ */ | ||
//Make replacements | ||
const [result, newContents] = runProcessors(contents, processor, file) | ||
const [result, newContents] = await runProcessorsAsync(contents, processor, file) | ||
@@ -57,0 +79,0 @@ //Contents changed and not a dry run? Write to file |
@@ -13,3 +13,3 @@ import {parseConfig} from './helpers/config.js' | ||
config = parseConfig(config) | ||
const {files, processor, dry, verbose} = config | ||
const {files, processor, processorAsync, dry, verbose} = config | ||
@@ -21,3 +21,3 @@ //Dry run? | ||
const paths = await pathsAsync(files, config) | ||
const promises = paths.map(path => processAsync(path, processor, config)) | ||
const promises = paths.map(path => processAsync(path, processor ?? processorAsync, config)) | ||
const results = await Promise.all(promises) | ||
@@ -24,0 +24,0 @@ |
@@ -75,2 +75,18 @@ import {expect, use, should} from 'chai' | ||
it('should run processorAsync', done => { | ||
processFile({ | ||
files: 'test1', | ||
processorAsync: async (input) => { | ||
const replaceValue = await Promise.resolve('b') | ||
return input.replace(/re\splace/g, replaceValue) | ||
}, | ||
}).then(() => { | ||
const test1 = fs.readFileSync('test1', 'utf8') | ||
const test2 = fs.readFileSync('test2', 'utf8') | ||
expect(test1).to.equal('a b c') | ||
expect(test2).to.equal(testData) | ||
done() | ||
}) | ||
}) | ||
it('should replace contents in a single file with regex', done => { | ||
@@ -404,3 +420,3 @@ processFile(fromToToProcessor({ | ||
it('should return corret results for multiple files', function() { | ||
it('should return correct results for multiple files', function() { | ||
const results = processFileSync(fromToToProcessor({ | ||
@@ -407,0 +423,0 @@ files: ['test1', 'test2', 'test3'], |
@@ -13,3 +13,3 @@ import {parseConfig} from './helpers/config.js' | ||
//If custom processor is provided use it instead | ||
if (config && config.processor) { | ||
if (config && (config.processor || config.processorAsync)) { | ||
return await processFile(config) | ||
@@ -39,2 +39,6 @@ } | ||
if (config && config.processorAsync) { | ||
throw new Error('ProcessorAsync cannot be used in synchronous mode') | ||
} | ||
//If custom processor is provided use it instead | ||
@@ -41,0 +45,0 @@ if (config && config.processor) { |
@@ -472,2 +472,12 @@ import {expect, use, should} from 'chai' | ||
it('should error with processorAsync', function() { | ||
return expect(() => replaceInFileSync({ | ||
files: 'test1', | ||
processorAsync: async (input) => { | ||
const replaceValue = await Promise.resolve('b') | ||
return input.replace(/re\splace/g, replaceValue) | ||
}, | ||
})).to.throw(Error) | ||
}) | ||
it('should replace contents in a single file with regex', function() { | ||
@@ -474,0 +484,0 @@ replaceInFileSync({ |
@@ -24,2 +24,3 @@ | ||
to?: To | Array<To>; | ||
getTargetFile?(source: string): string; | ||
countMatches?: boolean; | ||
@@ -32,2 +33,3 @@ allowEmptyPaths?: boolean; | ||
processor?: ProcessorCallback | Array<ProcessorCallback>; | ||
processorAsync?: ProcessorAsyncCallback | Array<ProcessorAsyncCallback>; | ||
} | ||
@@ -46,1 +48,2 @@ | ||
type ProcessorCallback = (input: string, file: string) => string; | ||
type ProcessorAsyncCallback = (input: string, file: string) => Promise<string>; |
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
276662
2258
584