Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

matched

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

matched - npm Package Compare versions

Comparing version 0.2.2 to 0.3.0

.verb.md

195

index.js

@@ -1,119 +0,122 @@

/**
* matched <https://github.com/jonschlinkert/matched>
*
* Copyright (c) 2014 Jon Schlinkert, contributors.
* Licensed under the MIT license.
*/
'use strict';
var fs = require('fs');
var path = require('path');
var root = require('find-root');
var glob = require('globby');
var flatten = require('array-flatten');
var differ = require('array-differ');
var union = require('array-union');
var unique = require('array-uniq');
var normalize = require('normalize-path');
var segments = require('path-segments');
var parsePath = require('parse-filepath');
var extend = require('xtend');
var utils = require('./utils');
module.exports = function (patterns, config, cb) {
if (typeof config === 'function') {
cb = config;
config = {};
}
function resolve(cwd) {
return function(filepath) {
return normalize(path.resolve(cwd, filepath));
};
}
if (typeof cb !== 'function') {
throw new Error('expected a callback function.');
}
function listDirs(cwd) {
return fs.readdirSync(cwd).filter(function(filepath) {
filepath = path.join(cwd, filepath);
return fs.statSync(filepath).isDirectory();
}).map(resolve(cwd));
}
if (!utils.isValidGlob(patterns)) {
cb(new Error('invalid glob pattern: ' + patterns));
return;
}
var base = function(options) {
options = options || {};
var filepath = path.resolve(options.cwd || root());
return normalize(filepath);
};
// shallow clone options
var options = utils.extend({cwd: ''}, config);
options.cwd = cwd(options);
var sifted = siftPatterns(patterns, options);
var arrayify = function(arr) {
return !Array.isArray(arr) ? [arr] : arr;
function updateOptions(inclusive) {
return setIgnores(options, sifted.excludes, inclusive.index);
}
utils.reduce(sifted.includes, [], function (acc, include, next) {
var opts = updateOptions(include);
utils.glob(include.pattern, opts, function (err, files) {
if (err) return next(err);
next(null, acc.concat(files));
})
}, cb);
};
module.exports.sync = function (patterns, config) {
if (!utils.isValidGlob(patterns)) {
throw new Error('invalid glob pattern: ' + patterns);
}
/**
* ## filterDirs
*
* Return an array of directories except for exclusions.
*
* @param {String} `base` The base directory to start from.
* @param {Object} `options`
* @return {Array}
* @api private
*/
// shallow clone options
var options = utils.extend({cwd: ''}, config);
options.cwd = cwd(options);
var sifted = siftPatterns(patterns, options);
var filterDirs = function(options) {
options = options || {};
var cwd = base(options);
var len = sifted.includes.length, i = -1;
var res = [];
// list directories starting with the cwd
var dirs = listDirs(cwd).map(resolve(cwd));
// Omit folders from root directory
var rootOmit = ['.git', 'node_modules', 'temp', 'tmp'];
var rootDirs = union(rootOmit, arrayify(options.omit || []));
return differ(dirs, rootDirs.map(resolve(cwd)));
while (++i < len) {
var include = sifted.includes[i];
var opts = setIgnores(options, sifted.excludes, include.index);
res.push.apply(res, utils.glob.sync(include.pattern, opts));
}
return res;
};
var splitPatterns = function(patterns) {
var arr = [];
patterns.forEach(function(pattern) {
var re = /^\*\*\//;
arr.push(pattern);
if (re.test(pattern)) {
arr.push(pattern.replace(re, ''));
function siftPatterns(patterns, opts) {
patterns = utils.arrayify(patterns);
var res = { includes: [], excludes: [] };
var len = patterns.length, i = -1;
while (++i < len) {
var stats = new Stats(patterns[i], i);
if (opts.relative) {
stats.pattern = toRelative(stats.pattern, opts);
delete opts.cwd;
}
});
return unique(arr);
};
if (stats.isNegated) {
res.excludes.push(stats);
} else {
res.includes.push(stats);
}
}
return res;
}
module.exports = function matched(patterns, options) {
options = options || {};
var cwd = base(options);
var opts;
function setIgnores(options, excludes, inclusiveIndex) {
var opts = utils.extend({}, options);
var negations = [];
var p = splitPatterns(arrayify(patterns));
var len = excludes.length, i = -1;
while (++i < len) {
var exclusion = excludes[i];
if (exclusion.index > inclusiveIndex) {
negations.push(exclusion.pattern);
}
}
opts.ignore = utils.arrayify(opts.ignore || []);
opts.ignore.push.apply(opts.ignore, negations);
return opts;
}
return unique(flatten(filterDirs(options).reduce(function (acc, start) {
var normalized = p.map(function (pattern) {
var dir = start;
if (!/\*\*\//.test(pattern)) {
start = cwd;
}
if (/\{,/.test(pattern)) {
start = normalize(path.resolve(options.cwd || start));
}
function Stats(pattern, i) {
this.index = i
this.isNegated = false;
this.pattern = pattern;
opts = extend({}, options, {
pattern: pattern,
cwd: start,
root: start
});
if (pattern.charAt(0) === '!') {
this.isNegated = true;
this.pattern = pattern.slice(1);
}
}
// reset cwd;
start = dir;
return opts;
});
function cwd(opts) {
if (/^\W/.test(opts.cwd)) {
return utils.resolve(opts.cwd);
}
return opts.cwd;
}
return normalized.map(function(obj) {
opts = extend({}, {cwd: obj.cwd, srcBase: obj.srcBase, root: obj.root});
var result = glob.sync(obj.pattern, opts);
return result.map(resolve(opts.cwd));
});
}, [])));
};
function toRelative(pattern, opts) {
var fp = path.resolve(opts.cwd, pattern);
return path.relative(process.cwd(), fp);
}
{
"name": "matched",
"description": "Super fast globbing library.",
"version": "0.2.2",
"description": "Adds array support to node-glob, sync and async. Also supports tilde expansion (user home) and resolving to global npm modules.",
"version": "0.3.0",
"homepage": "https://github.com/jonschlinkert/matched",
"author": {
"name": "Jon Schlinkert",
"url": "https://github.com/jonschlinkert"
},
"repository": {
"type": "git",
"url": "git://github.com/jonschlinkert/matched.git"
},
"author": "Jon Schlinkert (https://github.com/jonschlinkert)",
"repository": "jonschlinkert/matched",
"bugs": {
"url": "https://github.com/jonschlinkert/matched/issues"
},
"licenses": [
{
"type": "MIT",
"url": "https://github.com/jonschlinkert/matched/blob/master/LICENSE-MIT"
}
],
"license": "MIT",
"main": "index.js",

@@ -28,23 +17,20 @@ "engines": {

"dependencies": {
"array-differ": "^0.1.0",
"array-flatten": "0.0.2",
"array-union": "^0.1.0",
"array-uniq": "^0.1.0",
"find-root": "^0.1.1",
"globby": "^0.1.1",
"normalize-path": "^0.1.0",
"parse-filepath": "^0.3.0",
"path-segments": "^0.1.1",
"xtend": "^3.0.0"
"async-array-reduce": "^0.1.0",
"extend-shallow": "^2.0.1",
"glob": "^5.0.15",
"is-valid-glob": "^0.3.0",
"lazy-cache": "^0.2.3",
"resolve-dir": "^0.1.0"
},
"devDependencies": {
"chai": "^1.9.1",
"mocha": "^1.20.1",
"verb": "^0.2.13"
"gulp": "^3.9.0",
"gulp-istanbul": "^0.10.1",
"gulp-jshint": "^1.11.2",
"gulp-mocha": "^2.1.3",
"jshint-stylish": "^2.0.1",
"mocha": "^2.3.3"
},
"keywords": [
"array",
"card",
"directories",
"dirs",
"exclude",

@@ -55,3 +41,2 @@ "exclusions",

"filesystem",
"filter",
"find",

@@ -63,2 +48,3 @@ "fnmatch",

"globbing",
"globby",
"globs",

@@ -69,9 +55,10 @@ "globstar",

"matcher",
"matching",
"minimatch",
"multi",
"multimatch",
"multiple",
"negate",
"node_modules",
"omissions",
"omit",
"node",
"node-glob",
"paths",

@@ -81,9 +68,14 @@ "pattern",

"star",
"traverse",
"util",
"utility",
"wild",
"wildcard",
"wildcards"
]
],
"verb": {
"related": {
"list": [
"is-glob",
"micromatch",
"look-up"
]
}
}
}

@@ -1,12 +0,17 @@

# matched [![NPM version](https://badge.fury.io/js/matched.png)](http://badge.fury.io/js/matched)
# matched [![NPM version](https://badge.fury.io/js/matched.svg)](http://badge.fury.io/js/matched)
> Super fast globbing library.
> Adds array support to node-glob, sync and async. Also supports tilde expansion (user home) and resolving to global npm modules.
#### [Why?](#why)
**TODO**
* [x] async
* [x] sync
* [ ] promise
## Install
Install with [npm](npmjs.org):
```bash
npm i matched --save-dev
Install with [npm](https://www.npmjs.com/)
```sh
$ npm i matched --save
```

@@ -16,112 +21,63 @@

```js
var glob = require('matched');
```
├── node_modules/...
├── index.js
├── README.md
└── test/test.js
```
## API
**async**
```js
matched(patterns, options)
glob(['*.js'], function(err, files) {
//=> ['utils.js', 'index.js']
});
```
See supported [globby](https://github.com/sindresorhus/globby) options.
**sync**
### patterns
*Required*
Type: `string|array`
See [minimatch](https://github.com/isaacs/minimatch#usage) for options and supported patterns.
### options
Type: `object`
#### exclusions
Matched excludes certain directories to speed up search.
Type: `array`
Default: `['.git', 'node_modules', 'temp', 'tmp']`
Pass an array of additional directories to exclude:
```js
matched(['**/*.js'], {omit: ['vendor']});
var files = glob.sync(['*.js']);
//=> ['utils.js', 'index.js']
```
See [node-glob](https://github.com/isaacs/node-glob#properties) for all supported options.
**options**
Both sync and async take options as the second argument:
## Tests
In the command line, run:
```bash
mocha
```js
glob(['*.js'], {cwd: 'test'}, function(err, files) {
//=> ['test.js']
});
```
## Globbing patterns
## Related projects
Just a quick overview.
* [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://www.npmjs.com/package/is-glob) | [homepage](https://github.com/jonschlinkert/is-glob)
* [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)
* [micromatch](https://www.npmjs.com/package/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://www.npmjs.com/package/micromatch) | [homepage](https://github.com/jonschlinkert/micromatch)
- `*` matches any number of characters, but not `/`
- `?` matches a single character, but not `/`
- `**` matches any number of characters, including `/`, as long as it's the only thing in a path part
- `{}` allows for a comma-separated list of "or" expressions
- `!` at the beginning of a pattern will negate the match
## Running tests
[Various patterns and expected matches](https://github.com/sindresorhus/multimatch/blob/master/test.js).
Install dev dependencies:
## Related
See [multimatch](https://github.com/sindresorhus/multimatch) if you need to match against a list instead of the filesystem.
## Why?
**Problem**
Let's say you want to return all of the `.js` files in a project, excluding `node_modules` and a few other similar directories. Normally you would need to do something like this:
```js
glob(['**/*.js', '!**/node_modules/**']);
```sh
$ npm i -d && npm test
```
The problem with this approach is that typically _even the excluded file paths are fully expanded before the result set is returned_. e.g. all of the files in `node_modules` would be scanned first.
## Contributing
**Solution**
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/matched/issues/new).
Matched allows you to exlude directories before they reach [globby](https://github.com/sindresorhus/globby). In a nutshell, matched uses `fs.readdirSync` to build up a list of directories relative to the `cwd`, then for each (non-excluded) directory matched passes the glob pattern to globby. The following is all that's needed to return all of the `.js` files in a project.
```js
var matched = require('matched');
matched('**/*.js');
//=> ['index.js', 'test/test.js']
```
Try it, you'll be surprised how fast it is comparatively. However, I'm not sure how well this approach will scale with complicated patterns. See [the tests](./test/test.js) for the use cases that are covered so far. Feel free to create pull requests or issues if you have suggestions for improvement.
## Author
**Jon Schlinkert**
+ [github/jonschlinkert](https://github.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
## License
Copyright (c) 2014 Jon Schlinkert, contributors.
Released under the MIT license
Copyright © 2015 Jon Schlinkert
Released under the MIT license.
***
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on June 26, 2014._
[globule]: https://github.com/cowboy/node-globule
[multimatch]: https://github.com/sindresorhus/multimatch
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on October 08, 2015._

@@ -1,108 +0,146 @@

/*!
* matched <https://github.com/jonschlinkert/matched>
*
* Copyright (c) 2014 Jon Schlinkert, contributors.
* Licensed under the MIT License
*/
'use strict';
var fs = require('fs');
var path = require('path');
var expect = require('chai').expect;
var matched = require('../');
require('mocha');
var assert = require('assert');
var glob = require('..');
// True if the filepath actually exist.
var exists = function() {
var filepath = path.join.apply(path, arguments);
return fs.existsSync(filepath);
};
describe('glob', function () {
describe('async', function () {
it('should be a function', function() {
assert(glob);
assert(typeof glob === 'function');
});
// log the files found
var log = function(arr) {
console.log(' Found', arr.length, 'files.');
};
it('should support globs as a string', function(done) {
glob('*.js', function(err, files) {
assert(!err);
assert(files);
done();
});
});
describe('when a cwd is used:', function () {
it('should only return file paths from the cwd.', function () {
var actual = matched(['{,*/}/*.*'], {cwd: 'test'});
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
});
it('should take options', function(done) {
glob('*.txt', {cwd: 'test/fixtures'}, function(err, files) {
assert(!err);
assert(files);
assert(files.length);
done();
});
});
it('should only return file paths from the cwd.', function () {
var actual = matched('*.js', {cwd: 'test'});
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
});
it('should return filepaths relative to process.cwd', function(done) {
var opts = {cwd: 'test/fixtures', relative: true};
glob('*.txt', opts, function(err, files) {
assert(!err);
assert(files);
assert(files.length);
assert(files[0] === 'test/fixtures/a.txt');
assert(files[1] === 'test/fixtures/b.txt');
assert(files[2] === 'test/fixtures/c.txt');
done();
});
});
it('should only return file paths from the cwd.', function () {
var actual = matched('**/*.js', {cwd: 'test/a'});
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
});
it('should take ignore patterns', function(done) {
var opts = {cwd: 'test/fixtures', ignore: ['*.js']};
glob(['*.*'], opts, function(err, files) {
assert(!err);
assert(files);
assert(files.length);
assert(~files.indexOf('a.md'));
assert(!~files.indexOf('a.js'));
done();
});
});
it('should return correct file paths.', function () {
var actual = matched(['{,*/}/*.md', '**/*.md'], {cwd: 'test'});
log(actual);
it('should take negation patterns', function(done) {
var opts = {cwd: 'test/fixtures'};
glob(['*.*', '!*.js'], opts, function(err, files) {
assert(!err);
assert(files);
assert(files.length);
assert(~files.indexOf('a.md'));
assert(!~files.indexOf('a.js'));
done();
});
});
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
});
});
it('should use ignore and negation patterns', function(done) {
glob(['*.js', '!gulpfile.js'], {ignore: ['utils.js']}, function(err, files) {
assert(!err);
assert(files);
assert(files.length === 1);
assert(files.indexOf('gulpfile.js') === -1);
done();
});
});
describe('when glob patterns are passed:', function () {
it('should return correct file paths.', function () {
var actual = matched(['{,*/}/*.md', '**/*.md']);
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
});
it('should expand tildes in cwd', function(done) {
glob(['*'], {cwd: '~'}, function(err, files) {
assert(!err);
assert(files);
assert(files.length > 0);
done();
});
});
it('should return correct file paths.', function () {
var actual = matched(['**/*.{js,md}', '**/*.md']);
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
});
it('should expand @ in cwd (global npm modules)', function(done) {
glob(['*'], {cwd: '@'}, function(err, files) {
assert(!err);
assert(files);
assert(files.length > 0);
done();
});
});
it('should return correct file paths.', function () {
var actual = matched(['**/*']);
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
});
it('should pass an error in the callback if the glob is bad', function(done) {
glob({}, {cwd: 'test/fixtures'}, function(err, files) {
assert(err);
assert(err.message);
assert(err.message === 'invalid glob pattern: [object Object]');
done();
});
});
it('should return correct file paths.', function () {
var actual = matched('*.js');
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
it('should throw an error if no callback is passed', function(done) {
try {
glob('abc');
done(new Error('expected an error'));
} catch(err) {
assert(err);
assert(err.message);
assert(err.message === 'expected a callback function.');
done();
}
});
});
it('should return correct file paths.', function () {
var actual = matched(['*.js', '**/*.js']);
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
});
describe('sync', function () {
it('should expose a sync method', function() {
assert(glob.sync);
assert(typeof glob.sync === 'function');
});
it('should return correct file paths.', function () {
var actual = matched('**/*.js');
log(actual);
actual.forEach(function(filepath) {
expect(exists(filepath)).to.equal(true);
})
it('should support globs as a string', function() {
var files = glob.sync('*.js');
assert(files);
});
it('should take options', function() {
var files = glob.sync('*.txt', {cwd: 'test/fixtures'});
assert(files);
assert(files.length > 1);
});
it('should throw an error if the glob is bad', function() {
try {
glob.sync({});
done(new Error('expected an error'));
} catch(err) {
assert(err);
assert(err.message);
assert(err.message === 'invalid glob pattern: [object Object]');
}
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc