Comparing version 0.1.4 to 1.0.0
168
index.js
'use strict'; | ||
var each = require('each-async'); | ||
var fs = require('fs'); | ||
var Mode = require('stat-mode'); | ||
var path = require('path'); | ||
/** | ||
* Search for a file in an array of paths | ||
* Initialize Find | ||
* | ||
* Options: | ||
* | ||
* - `path` Paths to search in | ||
* - `exclude` Paths to exclude | ||
* - `global` Whether to search in `PATH` | ||
* | ||
* @param {String} name | ||
* @param {Object} opts | ||
@@ -20,32 +15,149 @@ * @api public | ||
module.exports = function (name, opts) { | ||
var file; | ||
function Find() { | ||
if (!(this instanceof Find)) { | ||
return new Find(); | ||
} | ||
opts = opts || {}; | ||
opts.path = Array.isArray(opts.path) ? opts.path : [opts.path]; | ||
opts.global = opts.global !== false; | ||
this._where = []; | ||
} | ||
if (opts.global) { | ||
opts.path = opts.path.concat(process.env.PATH.split(path.delimiter)); | ||
/** | ||
* File name to search for | ||
* | ||
* @param {String} str | ||
* @api public | ||
*/ | ||
Find.prototype.name = function (str) { | ||
if (!arguments.length) { | ||
return this._name; | ||
} | ||
if (opts.exclude) { | ||
opts.exclude = Array.isArray(opts.exclude) ? opts.exclude : [opts.exclude]; | ||
this._name = str; | ||
return this; | ||
}; | ||
/** | ||
* Where to search for the file | ||
* | ||
* @param {Array|String} where | ||
* @api public | ||
*/ | ||
Find.prototype.where = function (where) { | ||
if (!arguments.length) { | ||
return this._where; | ||
} | ||
file = opts.path.map(function (dir) { | ||
if (dir && opts.exclude) { | ||
if (dir.indexOf(opts.exclude) === -1) { | ||
return path.join(dir, name); | ||
if (Array.isArray(where)) { | ||
this._where = this._where.concat(where); | ||
} else { | ||
this._where.push(where); | ||
} | ||
return this; | ||
}; | ||
/** | ||
* Run | ||
* | ||
* @param {Function} cb | ||
* @api public | ||
*/ | ||
Find.prototype.run = function (cb) { | ||
var self = this; | ||
this.read(function (err, files) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
self.stat(files, function (err, files) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
} else if (dir) { | ||
return path.join(dir, name); | ||
files = files.filter(function (file) { | ||
return file.name === self.name() && !file.stats.isDirectory(); | ||
}); | ||
cb(null, files); | ||
}); | ||
}); | ||
}; | ||
/** | ||
* Read directories | ||
* | ||
* @param {Function} cb | ||
* @api public | ||
*/ | ||
Find.prototype.read = function (cb) { | ||
var items = []; | ||
each(this.where(), function (dir, i, done) { | ||
fs.readdir(dir, function (err, files) { | ||
if (err) { | ||
done(err); | ||
return; | ||
} | ||
items = items.concat(files); | ||
done(); | ||
}); | ||
}, function (err) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
}).filter(fs.existsSync); | ||
if (!file.length) { | ||
return null; | ||
} | ||
cb(null, items); | ||
}); | ||
}; | ||
return file; | ||
/** | ||
* Stat files | ||
* | ||
* @param {Function} cb | ||
* @api public | ||
*/ | ||
Find.prototype.stat = function (files, cb) { | ||
var items = []; | ||
each(files, function (file, i, done) { | ||
fs.stat(file, function (err, stats) { | ||
if (err) { | ||
done(err); | ||
return; | ||
} | ||
var obj = { | ||
path: file, | ||
name: path.basename(file), | ||
mode: new Mode(stats).toOctal(), | ||
stats: stats | ||
}; | ||
items.push(obj); | ||
done(); | ||
}); | ||
}, function (err) { | ||
if (err) { | ||
cb(err); | ||
return; | ||
} | ||
cb(null, items); | ||
}); | ||
}; | ||
/** | ||
* Module exports | ||
*/ | ||
module.exports = Find; |
{ | ||
"name": "find-file", | ||
"version": "0.1.4", | ||
"version": "1.0.0", | ||
"description": "Search for a file in an array of paths", | ||
"keywords": [ | ||
"find", | ||
"file", | ||
"path", | ||
"search" | ||
], | ||
"homepage": "https://github.com/kevva/find-file", | ||
"bugs": "https://github.com/kevva/find-file/issues", | ||
"license": "MIT", | ||
"repository": "kevva/find-file", | ||
"author": { | ||
@@ -18,17 +12,24 @@ "name": "Kevin Mårtensson", | ||
}, | ||
"license": "MIT", | ||
"repository": "git://github.com/kevva/find-file.git", | ||
"engines": { | ||
"node": ">=0.10.0" | ||
}, | ||
"scripts": { | ||
"test": "mocha --reporter list" | ||
"test": "node test.js" | ||
}, | ||
"main": "index.js", | ||
"files": [ | ||
"index.js" | ||
], | ||
"keywords": [ | ||
"find", | ||
"file", | ||
"path", | ||
"search" | ||
], | ||
"dependencies": { | ||
"each-async": "^1.0.0", | ||
"stat-mode": "^0.2.0" | ||
}, | ||
"devDependencies": { | ||
"mocha": "~1.17.0" | ||
}, | ||
"engines": { | ||
"node": ">=0.10.0" | ||
"ava": "0.0.4" | ||
} | ||
} |
@@ -1,56 +0,32 @@ | ||
# find-file [![Build Status](https://travis-ci.org/kevva/find-file.png?branch=master)](http://travis-ci.org/kevva/find-file) | ||
# find-file [![Build Status](https://travis-ci.org/kevva/find-file.svg?branch=master)](https://travis-ci.org/kevva/find-file) | ||
Search for a file in an array of paths using Node.js. | ||
> Search for a file in an array of paths | ||
## Getting started | ||
## Install | ||
Install with npm: `npm install find-file` | ||
```bash | ||
$ npm install --save find-file | ||
``` | ||
## Examples | ||
## Usage | ||
```js | ||
var findFile = require('find-file'); | ||
var Find = require('find-file'); | ||
// search for gifsicle in `vendor` and `../bin` | ||
findFile('gifsicle', { path: ['vendor', '../bin'] }); | ||
var find = new Find() | ||
.name('foo.jpg') | ||
.where(['./images', './media']); | ||
// search for gifsicle in `vendor` and `../bin` but exclude `PATH` | ||
findFile('gifsicle', { path: ['vendor', '../bin'], global: false }); | ||
find.run(function (err, files) { | ||
if (err) { | ||
throw err; | ||
} | ||
// search for gifsicle in `vendor` and `PATH` but only return the first one | ||
findFile('gifsicle', { path: 'vendor' })[0]; | ||
console.log(files); | ||
//=> [{ path: 'images/foo.jpg', name: 'foo.jpg', ...}] | ||
}); | ||
``` | ||
## API | ||
### findFile(name, opts) | ||
Search for a file in an array of paths. By default it will also search for | ||
files in `PATH`. | ||
## Options | ||
### path | ||
Type: `String|Array` | ||
Default: `undefined` | ||
Paths to search in. | ||
### exclude | ||
Type: `String|Array` | ||
Default: `undefined` | ||
Paths to exclude. | ||
### global | ||
Type: `Boolean` | ||
Default: `true` | ||
Whether to search in `PATH`. | ||
## License | ||
[MIT License](http://en.wikipedia.org/wiki/MIT_License) (c) [Kevin Mårtensson](https://github.com/kevva) | ||
MIT © [Kevin Mårtensson](https://github.com/kevva) |
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
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
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
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
3914
132
1
2
2
33
+ Addedeach-async@^1.0.0
+ Addedstat-mode@^0.2.0
+ Addedeach-async@1.1.1(transitive)
+ Addedonetime@1.1.0(transitive)
+ Addedset-immediate-shim@1.0.1(transitive)
+ Addedstat-mode@0.2.2(transitive)