diff --git a/README.md b/README.md index 8e361fa..f418b3b 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,17 @@ findFile(files, (file) => file.endsWith('.css')); findFile(files, 'index.abcdef12.js', { ignoreHash: false }); ``` +### findFiles + +Finds all matching paths with the same matcher and options as `findFile`. Returns an empty array when no files match. + +```ts +import { findFiles } from '@rstackjs/test-utils'; + +const cssFiles = findFiles(files, '.css'); +// ['/dist/styles.css'] +``` + ### getDistFiles Recursively reads UTF-8 files from a dist directory. Source map files are excluded by default. diff --git a/src/findFile.ts b/src/findFile.ts index b45ccfb..1d387ff 100644 --- a/src/findFile.ts +++ b/src/findFile.ts @@ -45,3 +45,17 @@ export const findFile = ( throw new Error(`Unable to find file matching "${matcher.toString()}"`); }; + +/** Find all file paths that match the provided matcher. */ +export const findFiles = ( + files: Record, + matcher: FileMatcher, + options: FindFileOptions = {}, +): string[] => { + const { ignoreHash = true } = options; + const matcherFn = toMatcher(matcher); + + return Object.keys(files).filter((file) => + matcherFn(ignoreHash ? file.replace(HASH_PATTERN, '') : file), + ); +}; diff --git a/src/index.ts b/src/index.ts index 087c202..b9bddf9 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,6 +4,7 @@ export { type FileMatcher, findFile, type FindFileOptions, + findFiles, } from './findFile.js'; export { getDistFiles } from './getDistFiles.js'; export { getFileContent } from './getFileContent.js'; diff --git a/tests/findFiles.test.ts b/tests/findFiles.test.ts new file mode 100644 index 0000000..3e1934e --- /dev/null +++ b/tests/findFiles.test.ts @@ -0,0 +1,29 @@ +import { expect, test } from 'rstack/test'; +import { findFiles } from '../src/index'; + +const files = { + '/dist/index.abcdef12.js': 'console.log("index")', + '/dist/nested/index.12345678.js': 'console.log("nested")', + '/dist/styles.css': '.root {}', +}; + +test('should return all matching paths for string, regex and function matchers', () => { + const expected = [ + '/dist/index.abcdef12.js', + '/dist/nested/index.12345678.js', + ]; + + expect(findFiles(files, 'index.js')).toEqual(expected); + expect(findFiles(files, /index\.js$/g)).toEqual(expected); + expect(findFiles(files, (file) => file.endsWith('index.js'))).toEqual( + expected, + ); + expect(findFiles(files, 'missing.js')).toEqual([]); +}); + +test('should match original paths when ignoreHash is false', () => { + expect(findFiles(files, 'index.js', { ignoreHash: false })).toEqual([]); + expect(findFiles(files, 'index.abcdef12.js', { ignoreHash: false })).toEqual([ + '/dist/index.abcdef12.js', + ]); +});