Comparing version 0.1.9 to 1.0.0
207
lib/needs.js
@@ -16,126 +16,137 @@ 'use strict'; | ||
function matchPatterns(patterns, fn) { | ||
var result = false; | ||
// Iterate over flattened patterns array. | ||
_.forEach(_.flatten(patterns), function (pattern) { | ||
// If the first character is ! it should be omitted | ||
var exclusion = pattern.indexOf('!') === 0; | ||
// If the pattern is an exclusion, remove the ! | ||
if (exclusion) { pattern = pattern.slice(1); } | ||
// Find all matching files for this pattern. | ||
var matched = fn(pattern) ; | ||
result = exclusion ? (!matched) : (result || matched); | ||
return !(exclusion && matched);// if excluded return false to exit iteration | ||
}); | ||
return result; | ||
var result = false; | ||
// Iterate over flattened patterns array. | ||
_.forEach(_.flatten(patterns), function (pattern) { | ||
// If the first character is ! it should be omitted | ||
var exclusion = (typeof pattern === 'string') && (pattern.indexOf('!') === 0); | ||
// If the pattern is an exclusion, remove the ! | ||
if (exclusion) { | ||
pattern = pattern.slice(1); | ||
} | ||
// Find all matching files for this pattern. | ||
var matched = fn(pattern); | ||
result = exclusion ? (!matched) : (result || matched); | ||
return !(exclusion && matched);// if excluded return false to exit iteration | ||
}); | ||
return result; | ||
} | ||
function match(filename, patterns, options) { | ||
options = _.assign({ | ||
matchBase: true | ||
}, options); | ||
options = _.assign({ | ||
matchBase: true | ||
}, options); | ||
if (filename == null || filename == null || typeof filename !== 'string') return false; | ||
if (filename === null || filename === null || typeof filename !== 'string') return false; | ||
if (!Array.isArray(patterns)) patterns = [patterns]; | ||
if (!Array.isArray(patterns)) patterns = [patterns]; | ||
if (patterns.length == 0) return false; | ||
if (patterns.length === 0) return false; | ||
return matchPatterns(patterns, function (pattern) { | ||
return minimatch(filename, pattern, options); | ||
}); | ||
return matchPatterns(patterns, function (pattern) { | ||
if (pattern instanceof RegExp) { | ||
return pattern.test(filename); | ||
} else if (typeof pattern === 'string') { | ||
return minimatch(filename, pattern, options); | ||
} else { | ||
throw new Error('Unsupported pattern type: ' + (typeof pattern)); | ||
} | ||
}); | ||
} | ||
function join(args) { | ||
if (args.length === 1) { | ||
return args[0]; | ||
} else if (args.length === 2) { | ||
return path.join(args[0], args[1]) | ||
} else if (args.length === 3) { | ||
return path.join(args[0], args[1], args[2]) | ||
} else if (args.length === 4) { | ||
return path.join(args[0], args[1], args[2], args[3]) | ||
} else { | ||
return path.join.apply(path, args); | ||
} | ||
if (args.length === 1) { | ||
return args[0]; | ||
} else if (args.length === 2) { | ||
return path.join(args[0], args[1]); | ||
} else if (args.length === 3) { | ||
return path.join(args[0], args[1], args[2]); | ||
} else if (args.length === 4) { | ||
return path.join(args[0], args[1], args[2], args[3]); | ||
} else { | ||
return path.join.apply(path, args); | ||
} | ||
} | ||
function needs() { | ||
if (arguments.length == 0 || typeof arguments[0] !== 'string') throw new Error('`dir` must be a string'); | ||
if (arguments.length === 0 || typeof arguments[0] !== 'string') throw new Error('`dir` must be a string'); | ||
var dir, opts = {}; | ||
var args = slice.call(arguments); | ||
var len = args.length; | ||
if (typeof args[len - 1] === 'object') { | ||
opts = args.pop(); | ||
} | ||
var dir, opts = {}; | ||
var args = slice.call(arguments); | ||
var len = args.length; | ||
if (typeof args[len - 1] === 'object' || Array.isArray(args[len - 1])) { | ||
opts = args.pop(); | ||
} | ||
dir = join(args); | ||
opts.prefix = opts.prefix || ''; | ||
opts.patterns = opts.patterns || opts.includes || opts.include || '+(*.js|*.json)'; | ||
opts.excludes = opts.excludes || opts.exclude || '+(*.git|*.svn)'; | ||
dir = join(args); | ||
if (Array.isArray(opts)) { | ||
opts = {patterns: opts}; | ||
} | ||
opts.prefix = opts.prefix || ''; | ||
opts.patterns = opts.patterns || opts.includes || opts.include || '+(*.js|*.json)'; | ||
opts.excludes = opts.excludes || opts.exclude || '+(*.git|*.svn)'; | ||
var filter = typeof opts.filter === 'function' ? opts.filter : defaultFilter; | ||
var filter = typeof opts.filter === 'function' ? opts.filter : defaultFilter; | ||
var modules = {}; | ||
read(dir, opts); | ||
return modules; | ||
var modules = {}; | ||
read(dir, opts); | ||
return modules; | ||
function defaultFilter(info) { | ||
return require(info.file); | ||
} | ||
function defaultFilter(info) { | ||
return require(info.file); | ||
} | ||
function register(modules, info) { | ||
if (filter.length <= 1) { | ||
var m = filter(info); | ||
if (!!m) modules[info.name] = m; | ||
} else { | ||
filter(modules, info); | ||
} | ||
function register(modules, info) { | ||
if (filter.length <= 1) { | ||
var m = filter(info); | ||
if (!!m) modules[info.name] = m; | ||
} else { | ||
filter(modules, info); | ||
} | ||
} | ||
function read(dir, options) { | ||
function read(dir, options) { | ||
var files = fs.readdirSync(dir); | ||
var files = fs.readdirSync(dir); | ||
files.forEach(function (filename) { | ||
if (match(filename, options.excludes)) return; | ||
files.forEach(function (filename) { | ||
if (match(filename, options.excludes)) return; | ||
var file = dir + '/' + filename; | ||
var ext = path.extname(filename); | ||
var stat = fs.statSync(file); | ||
if (stat.isDirectory()) { | ||
var target = 'index.js'; | ||
if (options.module) { | ||
if (typeof options.module === 'string') { | ||
target = options.module; | ||
} else { | ||
var pf = path.join(file, 'package.json'); | ||
if (existsSync(pf)) { | ||
target = require(pf).main || target; | ||
} | ||
} | ||
} | ||
var file = dir + '/' + filename; | ||
var ext = path.extname(filename); | ||
var stat = fs.statSync(file); | ||
if (stat.isDirectory()) { | ||
var target = 'index.js'; | ||
if (options.module) { | ||
if (typeof options.module === 'string') { | ||
target = options.module; | ||
} else { | ||
var pf = path.join(file, 'package.json'); | ||
if (existsSync(pf)) { | ||
target = require(pf).main || target; | ||
} | ||
} | ||
} | ||
target = path.join(file, target); | ||
if (existsSync(target)) { | ||
register(modules, { | ||
name: filename, | ||
file: target, | ||
stat: stat | ||
}); | ||
} else { | ||
read(file, options); | ||
} | ||
target = path.join(file, target); | ||
if (existsSync(target)) { | ||
register(modules, { | ||
name: filename, | ||
file: target, | ||
stat: stat | ||
}); | ||
} else { | ||
read(file, options); | ||
} | ||
} else if (!options.module) { | ||
if (!match(filename, options.patterns)) return; | ||
var name = options.prefix + filename.replace(ext, ''); | ||
register(modules, { | ||
name: name, | ||
file: path.normalize(file), | ||
stat: stat | ||
}); | ||
} | ||
} else if (!options.module) { | ||
if (!match(filename, options.patterns)) return; | ||
var name = options.prefix + filename.replace(ext, ''); | ||
register(modules, { | ||
name: name, | ||
file: path.normalize(file), | ||
stat: stat | ||
}); | ||
} | ||
} | ||
} | ||
}); | ||
} | ||
} |
{ | ||
"name": "needs", | ||
"version": "0.1.9", | ||
"version": "1.0.0", | ||
"description": "Require multiple modules in node.js.", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "node_modules/mocha/bin/mocha test/*.test.js" | ||
"test": "gulp" | ||
}, | ||
@@ -27,10 +27,21 @@ "repository": { | ||
"homepage": "https://github.com/taoyuan/needs", | ||
"dependencies": { | ||
"lodash": ">=3.x.x", | ||
"minimatch": ">=2.x.x" | ||
}, | ||
"devDependencies": { | ||
"chai": "~3.1.0", | ||
"chai": "~3.2.0", | ||
"gulp": "^3.9.0", | ||
"gulp-babel": "^5.2.0", | ||
"gulp-coveralls": "^0.1.4", | ||
"gulp-exclude-gitignore": "^1.0.0", | ||
"gulp-istanbul": "^0.10.0", | ||
"gulp-jscs": "^2.0.0", | ||
"gulp-jshint": "^1.11.2", | ||
"gulp-mocha": "^2.1.3", | ||
"gulp-nsp": "^0.4.5", | ||
"gulp-plumber": "^1.0.1", | ||
"jshint-stylish": "^2.0.1", | ||
"mocha": "~2.2.5" | ||
}, | ||
"dependencies": { | ||
"lodash": "~3.10.0", | ||
"minimatch": "~2.0.8" | ||
} | ||
} |
@@ -5,2 +5,4 @@ Needs | ||
[![Build Status](http://img.shields.io/travis/taoyuan/needs.svg?style=flat)](https://travis-ci.org/taoyuan/needs) | ||
[![Coverage](https://coveralls.io/repos/taoyuan/needs/badge.svg?branch=master)](https://coveralls.io/r/taoyuan/needs) | ||
[![Quality](https://codeclimate.com/github/taoyuan/needs/badges/gpa.svg)](https://codeclimate.com/github/taoyuan/needs) | ||
[![Dependencies](https://img.shields.io/david/taoyuan/needs.svg?style=flat)](https://david-dm.org/taoyuan/needs) | ||
@@ -16,6 +18,10 @@ | ||
##Usage | ||
## Usage | ||
### RegExp pattern | ||
```js | ||
var controllers = require('needs')(__dirname, 'controllers', { | ||
var needs = require('needs'); | ||
needs(__dirname, 'controllers', { | ||
includes: /(.+Controller)\.js$/, | ||
@@ -28,12 +34,39 @@ excludes: /^\.(git|svn)$/ | ||
// { HomeController: function HomeController() {...}, ...} | ||
``` | ||
or: | ||
### Minimatch string pattern | ||
```js | ||
var libs = require('needs')(__dirname, 'libs'); | ||
// or using minimatch string | ||
needs(__dirname, 'controllers', { | ||
includes: '+(*.js|*.json)', | ||
excludes: '+(*.git|*.svn)' | ||
}); | ||
``` | ||
or: | ||
### Array includes and excludes | ||
```js | ||
var libs = require('needs')(__dirname + '/libs'); | ||
needs(__dirname, 'controllers', { | ||
includes: ['*.js', '*.json'], | ||
excludes: ['*.git', '*.svn'] | ||
}); | ||
``` | ||
### Array pattern | ||
```js | ||
needs(__dirname, 'controllers', ['*.js', '*.json']); | ||
``` | ||
### Simplest way to include and exclude | ||
```js | ||
needs(__dirname, 'controllers', ['*.js', '*.json', '!*.git', '!*.svn']); | ||
// or default includes ['*.js', '*.json'] and excludes ['!*.git', '!*.svn'] | ||
needs(__dirname, 'controllers'); | ||
``` | ||
##Links | ||
@@ -46,2 +79,2 @@ | ||
Copyright (c) 2014 Tao Yuan | ||
Licensed under the MIT license. | ||
Licensed under the MIT license. |
exports.index = 1; | ||
exports.show = 2; | ||
exports.add = 3; | ||
exports.edit = 4; | ||
exports.show = 2; | ||
exports.add = 3; | ||
exports.edit = 4; |
@@ -1,1 +0,1 @@ | ||
module.exports = { guten: 'tag' }; | ||
module.exports = {guten: 'tag'}; |
@@ -1,1 +0,1 @@ | ||
module.exports = { guten: 'abend' }; | ||
module.exports = {guten: 'abend'}; |
{ | ||
"name": "foo", | ||
"version": "0.0.1" | ||
"name": "foo", | ||
"version": "0.0.1" | ||
} |
{ | ||
"name": "hello", | ||
"version": "0.0.1", | ||
"main": "hello.js" | ||
} | ||
"name": "hello", | ||
"version": "0.0.1", | ||
"main": "hello.js" | ||
} |
@@ -0,3 +1,5 @@ | ||
'use strict'; | ||
var chai = require('chai'); | ||
chai.Assertion.includeStack = true; | ||
chai.config.includeStack = true; | ||
var t = chai.assert; | ||
@@ -9,123 +11,205 @@ var needs = require('..'); | ||
describe('needs', function () { | ||
it('requiring flatten directory', function () { | ||
var controllers = needs(root, 'controllers', { | ||
includes: '*Controller.js' | ||
}); | ||
t.deepEqual(controllers, { | ||
'main-Controller': { | ||
index: 1, | ||
show: 2, | ||
add: 3, | ||
edit: 4 | ||
}, | ||
it('requiring flatten directory', function () { | ||
var controllers = needs(root, 'controllers', { | ||
includes: '*Controller.js' | ||
}); | ||
t.deepEqual(controllers, { | ||
'main-Controller': { | ||
index: 1, | ||
show: 2, | ||
add: 3, | ||
edit: 4 | ||
}, | ||
'other-Controller': { | ||
index: 1, | ||
show: 'nothing' | ||
} | ||
}); | ||
'other-Controller': { | ||
index: 1, | ||
show: 'nothing' | ||
} | ||
}); | ||
}); | ||
it('requiring json only became an option', function () { | ||
var mydir = needs(root, 'mydir', { | ||
includes: '+(*.js|*.json)' | ||
}); | ||
it('requiring regexp patterns', function () { | ||
var controllers = needs(root, 'controllers', { | ||
includes: /(.+Controller)\.js$/, | ||
excludes: /^\.(git|svn)$/ | ||
}); | ||
t.deepEqual(controllers, { | ||
'main-Controller': { | ||
index: 1, | ||
show: 2, | ||
add: 3, | ||
edit: 4 | ||
}, | ||
var mydir_contents = { | ||
foo: 'bar', | ||
hello: { | ||
world: true, | ||
universe: 42 | ||
}, | ||
config: { | ||
settingA: 'A', | ||
settingB: 'B' | ||
}, | ||
yes: true | ||
}; | ||
t.deepEqual(mydir, mydir_contents); | ||
'other-Controller': { | ||
index: 1, | ||
show: 'nothing' | ||
} | ||
}); | ||
}); | ||
var defaults = needs(root, 'mydir'); | ||
it('requiring json only became an option', function () { | ||
var mydir = needs(root, 'mydir', { | ||
includes: '+(*.js|*.json)' | ||
}); | ||
t.deepEqual(defaults, mydir_contents); | ||
var mydir_contents = { | ||
foo: 'bar', | ||
hello: { | ||
world: true, | ||
universe: 42 | ||
}, | ||
config: { | ||
settingA: 'A', | ||
settingB: 'B' | ||
}, | ||
yes: true | ||
}; | ||
t.deepEqual(mydir, mydir_contents); | ||
var defaults = needs(root, 'mydir'); | ||
t.deepEqual(defaults, mydir_contents); | ||
}); | ||
it('requiring with excludes', function () { | ||
var unfiltered = needs(root, 'filterdir', { | ||
includes: '*.js' | ||
}); | ||
it('requiring with excludes', function () { | ||
var unfiltered = needs(root, 'filterdir', { | ||
includes: '*.js' | ||
}); | ||
t.ok(unfiltered.root); | ||
t.ok(unfiltered.hello); | ||
t.ok(unfiltered.root); | ||
t.ok(unfiltered.hello); | ||
var excludedSub = needs(root, 'filterdir', { | ||
includes: '*.js', | ||
excludes: 'sub' | ||
}); | ||
var excludedSub = needs(root, 'filterdir', { | ||
includes: '*.js', | ||
excludes: 'sub' | ||
}); | ||
t.ok(excludedSub.root); | ||
t.equal(excludedSub.hello, undefined); | ||
}); | ||
t.ok(excludedSub.root); | ||
t.equal(excludedSub.hello, undefined); | ||
it('requiring common module file', function () { | ||
var modules = needs(root, 'mydir', {module: 'config.json'}); | ||
t.deepEqual(modules, { | ||
sub: { | ||
settingA: 'A', | ||
settingB: 'B' | ||
} | ||
}); | ||
}); | ||
it('requiring common module file', function () { | ||
var modules = needs(root, 'mydir', { module: 'config.json' }); | ||
t.deepEqual(modules, { | ||
sub: { | ||
settingA: 'A', | ||
settingB: 'B' | ||
} | ||
}); | ||
it('requiring node modules', function () { | ||
var modules = needs(root, 'modules', {module: true}); | ||
t.deepEqual(modules, { | ||
foo: 'bar', | ||
hello: { | ||
world: true, | ||
universe: 42 | ||
} | ||
}); | ||
}); | ||
it('requiring node modules', function () { | ||
var modules = needs(root, 'modules', { module: true }); | ||
t.deepEqual(modules, { | ||
foo: 'bar', | ||
hello: { | ||
world: true, | ||
universe: 42 | ||
} | ||
}); | ||
it('requiring modules with one parameter filter', function () { | ||
var modules = needs(root, 'modules', { | ||
module: true, | ||
filter: function (info) { | ||
var mod = require(info.file); | ||
if (typeof mod === 'object') mod.moduleName = info.name; | ||
return mod; | ||
} | ||
}); | ||
it('requiring modules with one parameter filter', function () { | ||
var modules = needs(root, 'modules', { | ||
module: true, | ||
filter: function (info) { | ||
var mod = require(info.file); | ||
if (typeof mod === 'object') mod.moduleName = info.name; | ||
return mod; | ||
} | ||
}); | ||
t.deepEqual(modules, { | ||
foo: 'bar', | ||
hello: { | ||
world: true, | ||
universe: 42, | ||
moduleName: "hello" | ||
} | ||
}); | ||
}); | ||
t.deepEqual(modules, { | ||
foo: 'bar', | ||
hello: { | ||
world: true, | ||
universe: 42, | ||
moduleName: "hello" | ||
} | ||
}); | ||
it('requiring modules with two parameter filter', function () { | ||
var modules = needs(root, 'modules', { | ||
module: true, | ||
filter: function (result, info) { | ||
var mod = require(info.file); | ||
if (typeof mod === 'object') mod.moduleName = info.name; | ||
result[info.name] = mod; | ||
} | ||
}); | ||
it('requiring modules with two parameter filter', function () { | ||
var modules = needs(root, 'modules', { | ||
module: true, | ||
filter: function (result, info) { | ||
var mod = require(info.file); | ||
if (typeof mod === 'object') mod.moduleName = info.name; | ||
result[info.name] = mod; | ||
} | ||
}); | ||
t.deepEqual(modules, { | ||
foo: 'bar', | ||
hello: { | ||
world: true, | ||
universe: 42, | ||
moduleName: "hello" | ||
} | ||
}); | ||
}); | ||
t.deepEqual(modules, { | ||
foo: 'bar', | ||
hello: { | ||
world: true, | ||
universe: 42, | ||
moduleName: "hello" | ||
} | ||
}); | ||
it('should needs with many dir partials', function () { | ||
var unfiltered = needs(root + '/filterdir', { | ||
includes: '*.js' | ||
}); | ||
}); | ||
t.ok(unfiltered.root); | ||
t.ok(unfiltered.hello); | ||
unfiltered = needs(root, 'filterdir', { | ||
includes: '*.js' | ||
}); | ||
t.ok(unfiltered.root); | ||
t.ok(unfiltered.hello); | ||
unfiltered = needs(root + '/..', 'dirs', 'filterdir', { | ||
includes: '*.js' | ||
}); | ||
t.ok(unfiltered.root); | ||
t.ok(unfiltered.hello); | ||
unfiltered = needs(root + '/../..', 'test', 'dirs', 'filterdir', { | ||
includes: '*.js' | ||
}); | ||
t.ok(unfiltered.root); | ||
t.ok(unfiltered.hello); | ||
unfiltered = needs(root + '/../../..', 'needs', 'test', 'dirs', 'filterdir', { | ||
includes: '*.js' | ||
}); | ||
t.ok(unfiltered.root); | ||
t.ok(unfiltered.hello); | ||
}); | ||
it('should support `!` for exclusion in pattern', function () { | ||
var unfiltered = needs(root + '/filterdir', { | ||
includes: ['*.js', '!hello.js'] | ||
}); | ||
t.ok(unfiltered.root); | ||
t.notOk(unfiltered.hello); | ||
}); | ||
it('should support array string patterns', function () { | ||
var unfiltered = needs(root + '/filterdir', ['*.js', '!hello.js']); | ||
t.ok(unfiltered.root); | ||
t.notOk(unfiltered.hello); | ||
}); | ||
it('should throw error for invalid pattern', function () { | ||
t.throw(function () { | ||
needs(root + '/filterdir', { | ||
includes: {} | ||
}); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
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
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
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 v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
15183
25
375
0
77
13
6
+ Addedbrace-expansion@2.0.1(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedminimatch@10.0.1(transitive)
- Removedbrace-expansion@1.1.11(transitive)
- Removedconcat-map@0.0.1(transitive)
- Removedlodash@3.10.1(transitive)
- Removedminimatch@2.0.10(transitive)
Updatedlodash@>=3.x.x
Updatedminimatch@>=2.x.x