Comparing version 2.0.1 to 3.0.0
@@ -5,3 +5,3 @@ 'use strict'; | ||
module.exports = function(patterns, options, callback) { | ||
module.exports = (patterns, options, callback) => { | ||
if (typeof options === 'function') { | ||
@@ -12,3 +12,3 @@ callback = options; | ||
const promise = glob(patterns, options); | ||
let promise = glob(patterns, options); | ||
@@ -15,0 +15,0 @@ if (typeof callback === 'function') { |
'use strict'; | ||
const Glob = require('glob').Glob; | ||
const isValidGlob = require('is-valid-glob'); | ||
const hasGlob = require('has-glob'); | ||
const path = require('path'); | ||
const util = require('util'); | ||
const glob = util.promisify(require('glob')); | ||
const utils = require('./utils'); | ||
module.exports = async function(patterns, options) { | ||
if (!isValidGlob(patterns)) { | ||
throw new Error('invalid glob pattern: ' + patterns); | ||
} | ||
module.exports = async(patterns, options) => { | ||
let { expand, getPaths, sift, setIgnores } = utils; | ||
patterns = [].concat(patterns || []); | ||
patterns = utils.arrayify(patterns); | ||
let opts = Object.assign({ cwd: '.' }, options); | ||
opts.cwd = path.resolve(expand(opts.cwd)); | ||
const opts = Object.assign({ cwd: process.cwd() }, options); | ||
opts.cwd = utils.cwd(opts); | ||
opts.cache = {}; | ||
if (!hasGlob(patterns)) { | ||
return Promise.resolve(utils.getPaths(patterns, opts)); | ||
let sifted = sift(patterns, opts); | ||
if (sifted === null) { | ||
throw new Error('invalid glob pattern: ' + patterns); | ||
} | ||
const glob = (pattern, options) => { | ||
return new Promise((resolve, reject) => { | ||
let acc = new Glob(pattern, options, (err, files) => { | ||
if (err) { | ||
reject(err); | ||
} else { | ||
acc.files = files; | ||
resolve(acc); | ||
} | ||
}); | ||
}); | ||
}; | ||
const sifted = utils.sift(patterns, opts); | ||
const excludes = sifted.excludes; | ||
const includes = sifted.includes; | ||
const cache = []; | ||
const files = []; | ||
let acc = { cache: {} }; | ||
function updateOptions(include) { | ||
return utils.setIgnores(opts, excludes, include.index); | ||
if (sifted.globs === 0) { | ||
return Promise.resolve(getPaths(patterns, opts)); | ||
} | ||
for (const include of includes) { | ||
const opt = updateOptions(include); | ||
opt.cache = acc.cache; | ||
let { excludes, includes } = sifted; | ||
let update = include => setIgnores(opts, excludes, include.index); | ||
let pending = []; | ||
let files = []; | ||
acc = await glob(include.pattern, opt); | ||
cache.push(acc.cache); | ||
files.push.apply(files, acc.found); | ||
for (let include of includes) { | ||
pending.push(glob(include.pattern, update(include)).then(res => files.push(...res))); | ||
} | ||
Object.defineProperty(files, 'cache', { | ||
configurable: true, | ||
enumerable: false, | ||
get: () => utils.createCache(cache) | ||
}); | ||
return files; | ||
return Promise.all(pending).then(() => files); | ||
}; |
'use strict'; | ||
const Glob = require('glob').Glob; | ||
const isValidGlob = require('is-valid-glob'); | ||
const hasGlob = require('has-glob'); | ||
const path = require('path'); | ||
const glob = require('glob'); | ||
const utils = require('./utils'); | ||
module.exports = function(patterns, options) { | ||
if (!isValidGlob(patterns)) { | ||
throw new Error('invalid glob pattern: ' + patterns); | ||
} | ||
module.exports = (patterns, options) => { | ||
let { expand, getPaths, sift, setIgnores } = utils; | ||
patterns = [].concat(patterns || []); | ||
patterns = utils.arrayify(patterns); | ||
// shallow clone options | ||
const opts = Object.assign({ cwd: '', nosort: true }, options); | ||
opts.cwd = utils.cwd(opts); | ||
opts.cache = {}; | ||
const opts = Object.assign({ cwd: '.', nosort: true }, options); | ||
opts.cwd = path.resolve(expand(opts.cwd)); | ||
if (!hasGlob(patterns)) { | ||
return utils.getPaths(patterns, opts); | ||
let sifted = sift(patterns, opts); | ||
if (sifted === null) { | ||
throw new Error('invalid glob pattern: ' + patterns); | ||
} | ||
const sifted = utils.sift(patterns, opts); | ||
const excludes = sifted.excludes; | ||
const includes = sifted.includes; | ||
const cache = []; | ||
const files = []; | ||
let acc = { cache: {} }; | ||
function updateOptions(include) { | ||
return utils.setIgnores(opts, excludes, include.index); | ||
if (sifted.globs === 0) { | ||
return getPaths(patterns, opts); | ||
} | ||
for (const include of includes) { | ||
const opt = updateOptions(include); | ||
opt.cache = acc.cache; | ||
opt.sync = true; | ||
let { excludes, includes } = sifted; | ||
let update = include => setIgnores(opts, excludes, include.index); | ||
let files = []; | ||
acc = new Glob(include.pattern, opt); | ||
cache.push(acc.cache); | ||
files.push.apply(files, acc.found); | ||
for (let include of includes) { | ||
files.push(...glob.sync(include.pattern, update(include))); | ||
} | ||
Object.defineProperty(files, 'cache', { | ||
configurable: true, | ||
enumerable: false, | ||
get: () => utils.createCache(cache) | ||
}); | ||
return files; | ||
}; |
119
lib/utils.js
@@ -5,76 +5,27 @@ 'use strict'; | ||
const path = require('path'); | ||
const union = require('arr-union'); | ||
const resolve = require('resolve-dir'); | ||
const isGlob = require('is-glob'); | ||
const union = (...args) => [...new Set([].concat.apply([], args).filter(Boolean))]; | ||
/** | ||
* Create a new `GlobStat` object with information about a | ||
* single glob pattern. | ||
* | ||
* @param {String} `pattern` GlobStat pattern | ||
* @param {Number} `idx` Index of the glob in the given array of patterns | ||
* Expand tilde | ||
*/ | ||
class GlobStat { | ||
constructor(pattern, idx) { | ||
this.index = idx; | ||
this.isNegated = false; | ||
this.pattern = pattern; | ||
exports.expand = str => str.replace(/^~/, process.cwd()); | ||
if (pattern.charAt(0) === '!' && pattern.charAt(1) !== '(') { | ||
this.isNegated = true; | ||
this.pattern = pattern.slice(1); | ||
} | ||
} | ||
} | ||
/** | ||
* Resolve the `cwd` to use for a glob operation. | ||
* | ||
* @param {Object} `options` | ||
* @return {String} | ||
* Create an object with information about the given glob pattern. | ||
* @param {String} `pattern` GlobStat pattern | ||
* @param {Number} `idx` Index of the glob in the given array of patterns | ||
*/ | ||
exports.cwd = options => path.resolve(resolve(options.cwd)); | ||
/** | ||
* exports | ||
*/ | ||
exports.arrayify = function(val) { | ||
return val ? (Array.isArray(val) ? val : [val]) : []; | ||
const globStat = (pattern, index) => { | ||
let details = { index, pattern, isNegated: false, isGlob: isGlob(pattern) }; | ||
if (pattern.charAt(0) === '!' && pattern.charAt(1) !== '(') { | ||
details.isNegated = true; | ||
details.pattern = pattern.slice(1); | ||
} | ||
return details; | ||
}; | ||
/** | ||
* Returns a unique-ified array of all cached filepaths from | ||
* the `glob.cache` property exposed by [node-glob][]. | ||
* | ||
* The most time-instensive part of globbing is hitting the | ||
* file system, so node-glob caches file paths internally to | ||
* allow multiple matching operations to be performed on the | ||
* same array - without hitting the file system again. Here, we're | ||
* simply pushing those cache objects into an array to expose | ||
* them to the user. | ||
* | ||
* @param {Array} `arr` Array of `glob.cache` objects. | ||
* @return {Array} | ||
*/ | ||
exports.createCache = function(arr) { | ||
const join = cwd => fp => path.join(cwd, fp); | ||
return arr.reduce(function(acc, cache) { | ||
for (const key of Object.keys(cache)) { | ||
const val = cache[key]; | ||
if (Array.isArray(val)) { | ||
union(acc, val.map(join(key))); | ||
} else { | ||
union(acc, [key]); | ||
} | ||
} | ||
return acc; | ||
}, []); | ||
}; | ||
/** | ||
* Sift glob patterns into inclusive and exclusive patterns. | ||
@@ -87,13 +38,15 @@ * | ||
exports.sift = function(patterns, opts) { | ||
patterns = exports.arrayify(patterns); | ||
const res = { includes: [], excludes: [] }; | ||
exports.sift = (patterns, options = {}) => { | ||
patterns = [].concat(patterns || []); | ||
let res = { includes: [], excludes: [], globs: 0 }; | ||
let n = 0; | ||
for (const pattern of patterns) { | ||
const stat = new GlobStat(pattern, n++); | ||
for (let pattern of patterns) { | ||
if (typeof pattern !== 'string') return null; | ||
let stat = globStat(pattern, n++); | ||
if (stat.isGlob) res.globs++; | ||
if (opts.relative) { | ||
stat.pattern = exports.toRelative(stat.pattern, opts); | ||
delete opts.cwd; | ||
if (options.relative) { | ||
stat.pattern = exports.toRelative(stat.pattern, options); | ||
delete options.cwd; | ||
} | ||
@@ -119,7 +72,7 @@ | ||
exports.setIgnores = function(options, excludes, inclusiveIndex) { | ||
const opts = Object.assign({}, options); | ||
const negations = []; | ||
exports.setIgnores = (options, excludes, inclusiveIndex) => { | ||
let opts = Object.assign({}, options); | ||
let negations = []; | ||
for (const exclusive of excludes) { | ||
for (let exclusive of excludes) { | ||
if (exclusive.index > inclusiveIndex) { | ||
@@ -130,4 +83,3 @@ negations.push(exclusive.pattern); | ||
opts.ignore = exports.arrayify(opts.ignore || []); | ||
opts.ignore.push.apply(opts.ignore, negations); | ||
opts.ignore = union([], opts.ignore, negations); | ||
return opts; | ||
@@ -144,4 +96,4 @@ }; | ||
exports.toRelative = function(pattern, opts) { | ||
return path.relative(process.cwd(), path.resolve(opts.cwd, pattern)); | ||
exports.toRelative = (pattern, opts) => { | ||
return path.relative(process.cwd(), path.resolve(exports.expand(opts.cwd), pattern)); | ||
}; | ||
@@ -157,8 +109,9 @@ | ||
exports.getPaths = function(paths, opts) { | ||
paths = paths.filter(fp => fs.existsSync(path.resolve(opts.cwd, fp))); | ||
if (opts.realpath) { | ||
return paths.map(fp => path.resolve(opts.cwd, fp)); | ||
exports.getPaths = (paths, options = {}) => { | ||
let resolve = fp => path.resolve(exports.expand(options.cwd), fp); | ||
paths = paths.filter(fp => fs.existsSync(resolve(fp))); | ||
if (options.realpath) { | ||
return paths.map(resolve); | ||
} | ||
return paths; | ||
}; |
{ | ||
"name": "matched", | ||
"description": "Adds array support to node-glob, sync and async. Also supports tilde expansion (user home) and resolving to global npm modules.", | ||
"version": "2.0.1", | ||
"version": "3.0.0", | ||
"homepage": "https://github.com/jonschlinkert/matched", | ||
@@ -22,21 +22,19 @@ "author": "Jon Schlinkert (https://github.com/jonschlinkert)", | ||
"engines": { | ||
"node": ">= 7" | ||
"node": ">=8" | ||
}, | ||
"scripts": { | ||
"report": "nyc report --reporter=html", | ||
"test": "nyc mocha test/*.js", | ||
"cover": "nyc mocha test/*.js", | ||
"test": "mocha", | ||
"posttest": "eslint *.js test/*.js lib/*.js" | ||
}, | ||
"dependencies": { | ||
"arr-union": "^3.1.0", | ||
"glob": "^7.1.2", | ||
"has-glob": "^1.0.0", | ||
"is-valid-glob": "^1.0.0", | ||
"resolve-dir": "^1.0.1" | ||
"glob": "^7.1.3", | ||
"is-glob": "^4.0.0" | ||
}, | ||
"devDependencies": { | ||
"eslint": "^4.19.0", | ||
"eslint": "^5.4.0", | ||
"gulp-format-md": "^1.0.0", | ||
"mocha": "^3.5.3", | ||
"nyc": "^11.6.0", | ||
"mocha": "^5.2.0", | ||
"nyc": "^12.0.2", | ||
"rimraf": "^2.6.2" | ||
@@ -91,13 +89,7 @@ }, | ||
"list": [ | ||
"findup-sync", | ||
"is-glob", | ||
"look-up", | ||
"micromatch" | ||
] | ||
}, | ||
"reflinks": [ | ||
"glob-stream", | ||
"verb", | ||
"verb-readme-generator", | ||
"vinyl" | ||
], | ||
"lint": { | ||
@@ -104,0 +96,0 @@ "reflinks": true |
@@ -17,8 +17,16 @@ # matched [![NPM version](https://img.shields.io/npm/v/matched.svg?style=flat)](https://www.npmjs.com/package/matched) [![NPM monthly downloads](https://img.shields.io/npm/dm/matched.svg?style=flat)](https://npmjs.org/package/matched) [![NPM total downloads](https://img.shields.io/npm/dt/matched.svg?style=flat)](https://npmjs.org/package/matched) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/matched.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/matched) | ||
If non-glob patterns (e.g. file paths) are passed, only paths that exist on the file system are returned. | ||
```js | ||
const glob = require('matched'); | ||
// async signature | ||
glob(patterns[, options]); | ||
// sync signature | ||
glob.sync(patterns[, options]); | ||
``` | ||
* `patterns` (string|array) - one or more glob patterns | ||
* `options` - options to pass to [node-glob](https://github.com/isaacs/node-glob); | ||
_Also note that if non-glob file paths are passed, only paths that exist on the file system will be returned._ | ||
**promise** | ||
@@ -32,16 +40,9 @@ | ||
// or with async-await | ||
(async function() { | ||
const files = await glob('*.txt'); | ||
(async() => { | ||
let files = await glob('*.txt'); | ||
console.log(files); | ||
//=> ['foo.txt', 'bar.txt'] | ||
})(); | ||
``` | ||
**sync** | ||
```js | ||
const files = glob.sync(['*.js']); | ||
//=> ['utils.js', 'index.js'] | ||
``` | ||
**callback** | ||
@@ -56,5 +57,12 @@ | ||
**sync** | ||
```js | ||
let files = glob.sync(['*.js']); | ||
//=> ['utils.js', 'index.js'] | ||
``` | ||
**options** | ||
All methods take [node-glob](https://github.com/isaacs/node-glob) options as the second argument: | ||
All methods take an options object to be forwarded to [node-glob](https://github.com/isaacs/node-glob) as the second argument. | ||
@@ -66,8 +74,11 @@ ```js | ||
## Release history | ||
## v3.0 | ||
**v0.4.1** | ||
* Removes `cache` property from results array. | ||
* Optimizations | ||
* Exposes a non-enumerable `cache` property on the returned files array. This is a patch relase since the property does not change the existing API and should not otherwise effect behavior or results. | ||
## v0.4.1 | ||
* Exposes a non-enumerable `cache` property on the returned files array. This is a patch release since the property does not change the existing API and should not otherwise effect behavior or results. | ||
## About | ||
@@ -110,4 +121,4 @@ | ||
* [findup-sync](https://www.npmjs.com/package/findup-sync): Find the first file matching a given pattern in the current directory or the nearest… [more](https://github.com/js-cli/node-findup-sync#readme) | [homepage](https://github.com/js-cli/node-findup-sync#readme "Find the first file matching a given pattern in the current directory or the nearest ancestor directory.") | ||
* [is-glob](https://www.npmjs.com/package/is-glob): Returns `true` if the given string looks like a glob pattern or an extglob pattern… [more](https://github.com/jonschlinkert/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob "Returns `true` if the given string looks like a glob pattern or an extglob pattern. This makes it easy to create code that only uses external modules like node-glob when necessary, resulting in much faster code execution and initialization time, and a bet") | ||
* [look-up](https://www.npmjs.com/package/look-up): Faster drop-in replacement for find-up and findup-sync. | [homepage](https://github.com/jonschlinkert/look-up "Faster drop-in replacement for find-up and findup-sync.") | ||
* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. | [homepage](https://github.com/micromatch/micromatch "Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch.") | ||
@@ -119,3 +130,3 @@ | ||
| --- | --- | | ||
| 56 | [jonschlinkert](https://github.com/jonschlinkert) | | ||
| 62 | [jonschlinkert](https://github.com/jonschlinkert) | | ||
| 8 | [TrySound](https://github.com/TrySound) | | ||
@@ -128,5 +139,5 @@ | 1 | [sindresorhus](https://github.com/sindresorhus) | | ||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) | ||
* [GitHub Profile](https://github.com/jonschlinkert) | ||
* [Twitter Profile](https://twitter.com/jonschlinkert) | ||
* [LinkedIn Profile](https://linkedin.com/in/jonschlinkert) | ||
@@ -140,2 +151,2 @@ ### License | ||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on March 21, 2018._ | ||
_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.6.0, on August 27, 2018._ |
Sorry, the diff of this file is not supported yet
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
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
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
2
144
13056
162
1
+ Addedis-glob@^4.0.0
+ Addedis-glob@4.0.3(transitive)
- Removedarr-union@^3.1.0
- Removedhas-glob@^1.0.0
- Removedis-valid-glob@^1.0.0
- Removedresolve-dir@^1.0.1
- Removedarr-union@3.1.0(transitive)
- Removedexpand-tilde@2.0.2(transitive)
- Removedglobal-modules@1.0.0(transitive)
- Removedglobal-prefix@1.0.2(transitive)
- Removedhas-glob@1.0.0(transitive)
- Removedhomedir-polyfill@1.0.3(transitive)
- Removedini@1.3.8(transitive)
- Removedis-glob@3.1.0(transitive)
- Removedis-valid-glob@1.0.0(transitive)
- Removedis-windows@1.0.2(transitive)
- Removedisexe@2.0.0(transitive)
- Removedparse-passwd@1.0.0(transitive)
- Removedresolve-dir@1.0.1(transitive)
- Removedwhich@1.3.1(transitive)
Updatedglob@^7.1.3