diff --git a/src/lib/filterAndReject.ts b/src/lib/filterAndReject.ts index f27cdb0c..1fdf0a5a 100644 --- a/src/lib/filterAndReject.ts +++ b/src/lib/filterAndReject.ts @@ -1,4 +1,4 @@ -import { and } from 'fp-and-or' +import { and, or } from 'fp-and-or' import identity from 'lodash/identity' import negate from 'lodash/negate' import minimatch from 'minimatch' @@ -31,7 +31,19 @@ function composeFilter(filterPattern: FilterRejectPattern): (name: string, versi // glob string else { const patterns = filterPattern.split(/[\s,]+/) - predicate = (dependencyName: string) => patterns.some(pattern => minimatch(dependencyName, pattern)) + predicate = (dependencyName: string) => { + /** Returns true if the pattern matches an unscoped dependency name. */ + const matchUnscoped = (pattern: string) => minimatch(dependencyName, pattern) + + /** Returns true if the pattern matches a scoped dependency name. */ + const matchScoped = (pattern: string) => + !pattern.includes('/') && + dependencyName.includes('/') && + minimatch(dependencyName.replace(/\//g, '_'), pattern) + + // return true if any of the provided patterns match the dependency name + return patterns.some(or(matchUnscoped, matchScoped)) + } } } // array diff --git a/test/filter.test.ts b/test/filter.test.ts index 3da3dc08..2e3bb54e 100644 --- a/test/filter.test.ts +++ b/test/filter.test.ts @@ -41,6 +41,51 @@ describe('filter', () => { upgraded.should.have.property('lodash.filter') }) + it('filter with wildcard for scoped package', async () => { + const pkg = { + dependencies: { + vite: '1.0.0', + '@vitejs/plugin-react': '1.0.0', + '@vitejs/plugin-vue': '1.0.0', + }, + } + + { + const upgraded = await ncu({ packageData: pkg, filter: ['vite'] }) + upgraded!.should.have.property('vite') + upgraded!.should.not.have.property('@vitejs/plugin-react') + upgraded!.should.not.have.property('@vitejs/plugin-vue') + } + + { + const upgraded = await ncu({ packageData: pkg, filter: ['@vite*'] }) + upgraded!.should.not.have.property('vite') + upgraded!.should.have.property('@vitejs/plugin-react') + upgraded!.should.have.property('@vitejs/plugin-vue') + } + + { + const upgraded = await ncu({ packageData: pkg, filter: ['*vite*'] }) + upgraded!.should.have.property('vite') + upgraded!.should.have.property('@vitejs/plugin-react') + upgraded!.should.have.property('@vitejs/plugin-vue') + } + + { + const upgraded = await ncu({ packageData: pkg, filter: ['*vite*/*react*'] }) + upgraded!.should.not.have.property('vite') + upgraded!.should.have.property('@vitejs/plugin-react') + upgraded!.should.not.have.property('@vitejs/plugin-vue') + } + + { + const upgraded = await ncu({ packageData: pkg, filter: ['*vite*vue*'] }) + upgraded!.should.not.have.property('vite') + upgraded!.should.not.have.property('@vitejs/plugin-react') + upgraded!.should.have.property('@vitejs/plugin-vue') + } + }) + it('filter with negated wildcard', async () => { const upgraded = (await ncu({ packageData: {