mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-11 18:32:50 +00:00
pushed new blog post
This commit is contained in:
23
node_modules/express/node_modules/vary/HISTORY.md
generated
vendored
Normal file
23
node_modules/express/node_modules/vary/HISTORY.md
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
1.0.1 / 2015-07-08
|
||||
==================
|
||||
|
||||
* Fix setting empty header from empty `field`
|
||||
* perf: enable strict mode
|
||||
* perf: remove argument reassignments
|
||||
|
||||
1.0.0 / 2014-08-10
|
||||
==================
|
||||
|
||||
* Accept valid `Vary` header string as `field`
|
||||
* Add `vary.append` for low-level string manipulation
|
||||
* Move to `jshttp` orgainzation
|
||||
|
||||
0.1.0 / 2014-06-05
|
||||
==================
|
||||
|
||||
* Support array of fields to set
|
||||
|
||||
0.0.0 / 2014-06-04
|
||||
==================
|
||||
|
||||
* Initial release
|
||||
3
node_modules/forever/.editorconfig
generated
vendored
Normal file
3
node_modules/forever/.editorconfig
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[*.js]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
1
node_modules/forever/node_modules/.bin/prettyjson
generated
vendored
Symbolic link
1
node_modules/forever/node_modules/.bin/prettyjson
generated
vendored
Symbolic link
@@ -0,0 +1 @@
|
||||
../prettyjson/bin/prettyjson
|
||||
1
node_modules/forever/node_modules/clone/.npmignore
generated
vendored
Normal file
1
node_modules/forever/node_modules/clone/.npmignore
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules/
|
||||
3
node_modules/forever/node_modules/clone/.travis.yml
generated
vendored
Normal file
3
node_modules/forever/node_modules/clone/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- 0.10
|
||||
18
node_modules/forever/node_modules/clone/LICENSE
generated
vendored
Normal file
18
node_modules/forever/node_modules/clone/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
Copyright © 2011-2015 Paul Vorbach <paul@vorba.ch>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the “Software”), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
126
node_modules/forever/node_modules/clone/README.md
generated
vendored
Normal file
126
node_modules/forever/node_modules/clone/README.md
generated
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
# clone
|
||||
|
||||
[](http://travis-ci.org/pvorb/node-clone)
|
||||
|
||||
[](http://npm-stat.com/charts.html?package=clone)
|
||||
|
||||
offers foolproof _deep cloning_ of objects, arrays, numbers, strings etc. in JavaScript.
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
npm install clone
|
||||
|
||||
(It also works with browserify, ender or standalone.)
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
~~~ javascript
|
||||
var clone = require('clone');
|
||||
|
||||
var a, b;
|
||||
|
||||
a = { foo: { bar: 'baz' } }; // initial value of a
|
||||
|
||||
b = clone(a); // clone a -> b
|
||||
a.foo.bar = 'foo'; // change a
|
||||
|
||||
console.log(a); // show a
|
||||
console.log(b); // show b
|
||||
~~~
|
||||
|
||||
This will print:
|
||||
|
||||
~~~ javascript
|
||||
{ foo: { bar: 'foo' } }
|
||||
{ foo: { bar: 'baz' } }
|
||||
~~~
|
||||
|
||||
**clone** masters cloning simple objects (even with custom prototype), arrays,
|
||||
Date objects, and RegExp objects. Everything is cloned recursively, so that you
|
||||
can clone dates in arrays in objects, for example.
|
||||
|
||||
|
||||
## API
|
||||
|
||||
`clone(val, circular, depth)`
|
||||
|
||||
* `val` -- the value that you want to clone, any type allowed
|
||||
* `circular` -- boolean
|
||||
|
||||
Call `clone` with `circular` set to `false` if you are certain that `obj`
|
||||
contains no circular references. This will give better performance if needed.
|
||||
There is no error if `undefined` or `null` is passed as `obj`.
|
||||
* `depth` -- depth to which the object is to be cloned (optional,
|
||||
defaults to infinity)
|
||||
|
||||
`clone.clonePrototype(obj)`
|
||||
|
||||
* `obj` -- the object that you want to clone
|
||||
|
||||
Does a prototype clone as
|
||||
[described by Oran Looney](http://oranlooney.com/functional-javascript/).
|
||||
|
||||
|
||||
## Circular References
|
||||
|
||||
~~~ javascript
|
||||
var a, b;
|
||||
|
||||
a = { hello: 'world' };
|
||||
|
||||
a.myself = a;
|
||||
b = clone(a);
|
||||
|
||||
console.log(b);
|
||||
~~~
|
||||
|
||||
This will print:
|
||||
|
||||
~~~ javascript
|
||||
{ hello: "world", myself: [Circular] }
|
||||
~~~
|
||||
|
||||
So, `b.myself` points to `b`, not `a`. Neat!
|
||||
|
||||
|
||||
## Test
|
||||
|
||||
npm test
|
||||
|
||||
|
||||
## Caveat
|
||||
|
||||
Some special objects like a socket or `process.stdout`/`stderr` are known to not
|
||||
be cloneable. If you find other objects that cannot be cloned, please [open an
|
||||
issue](https://github.com/pvorb/node-clone/issues/new).
|
||||
|
||||
|
||||
## Bugs and Issues
|
||||
|
||||
If you encounter any bugs or issues, feel free to [open an issue at
|
||||
github](https://github.com/pvorb/node-clone/issues) or send me an email to
|
||||
<paul@vorba.ch>. I also always like to hear from you, if you’re using my code.
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2011-2015 [Paul Vorbach](http://paul.vorba.ch/) and
|
||||
[contributors](https://github.com/pvorb/node-clone/graphs/contributors).
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the “Software”), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
160
node_modules/forever/node_modules/clone/clone.js
generated
vendored
Normal file
160
node_modules/forever/node_modules/clone/clone.js
generated
vendored
Normal file
@@ -0,0 +1,160 @@
|
||||
var clone = (function() {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Clones (copies) an Object using deep copying.
|
||||
*
|
||||
* This function supports circular references by default, but if you are certain
|
||||
* there are no circular references in your object, you can save some CPU time
|
||||
* by calling clone(obj, false).
|
||||
*
|
||||
* Caution: if `circular` is false and `parent` contains circular references,
|
||||
* your program may enter an infinite loop and crash.
|
||||
*
|
||||
* @param `parent` - the object to be cloned
|
||||
* @param `circular` - set to true if the object to be cloned may contain
|
||||
* circular references. (optional - true by default)
|
||||
* @param `depth` - set to a number if the object is only to be cloned to
|
||||
* a particular depth. (optional - defaults to Infinity)
|
||||
* @param `prototype` - sets the prototype to be used when cloning an object.
|
||||
* (optional - defaults to parent prototype).
|
||||
*/
|
||||
function clone(parent, circular, depth, prototype) {
|
||||
var filter;
|
||||
if (typeof circular === 'object') {
|
||||
depth = circular.depth;
|
||||
prototype = circular.prototype;
|
||||
filter = circular.filter;
|
||||
circular = circular.circular
|
||||
}
|
||||
// maintain two arrays for circular references, where corresponding parents
|
||||
// and children have the same index
|
||||
var allParents = [];
|
||||
var allChildren = [];
|
||||
|
||||
var useBuffer = typeof Buffer != 'undefined';
|
||||
|
||||
if (typeof circular == 'undefined')
|
||||
circular = true;
|
||||
|
||||
if (typeof depth == 'undefined')
|
||||
depth = Infinity;
|
||||
|
||||
// recurse this function so we don't reset allParents and allChildren
|
||||
function _clone(parent, depth) {
|
||||
// cloning null always returns null
|
||||
if (parent === null)
|
||||
return null;
|
||||
|
||||
if (depth == 0)
|
||||
return parent;
|
||||
|
||||
var child;
|
||||
var proto;
|
||||
if (typeof parent != 'object') {
|
||||
return parent;
|
||||
}
|
||||
|
||||
if (clone.__isArray(parent)) {
|
||||
child = [];
|
||||
} else if (clone.__isRegExp(parent)) {
|
||||
child = new RegExp(parent.source, __getRegExpFlags(parent));
|
||||
if (parent.lastIndex) child.lastIndex = parent.lastIndex;
|
||||
} else if (clone.__isDate(parent)) {
|
||||
child = new Date(parent.getTime());
|
||||
} else if (useBuffer && Buffer.isBuffer(parent)) {
|
||||
child = new Buffer(parent.length);
|
||||
parent.copy(child);
|
||||
return child;
|
||||
} else {
|
||||
if (typeof prototype == 'undefined') {
|
||||
proto = Object.getPrototypeOf(parent);
|
||||
child = Object.create(proto);
|
||||
}
|
||||
else {
|
||||
child = Object.create(prototype);
|
||||
proto = prototype;
|
||||
}
|
||||
}
|
||||
|
||||
if (circular) {
|
||||
var index = allParents.indexOf(parent);
|
||||
|
||||
if (index != -1) {
|
||||
return allChildren[index];
|
||||
}
|
||||
allParents.push(parent);
|
||||
allChildren.push(child);
|
||||
}
|
||||
|
||||
for (var i in parent) {
|
||||
var attrs;
|
||||
if (proto) {
|
||||
attrs = Object.getOwnPropertyDescriptor(proto, i);
|
||||
}
|
||||
|
||||
if (attrs && attrs.set == null) {
|
||||
continue;
|
||||
}
|
||||
child[i] = _clone(parent[i], depth - 1);
|
||||
}
|
||||
|
||||
return child;
|
||||
}
|
||||
|
||||
return _clone(parent, depth);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple flat clone using prototype, accepts only objects, usefull for property
|
||||
* override on FLAT configuration object (no nested props).
|
||||
*
|
||||
* USE WITH CAUTION! This may not behave as you wish if you do not know how this
|
||||
* works.
|
||||
*/
|
||||
clone.clonePrototype = function clonePrototype(parent) {
|
||||
if (parent === null)
|
||||
return null;
|
||||
|
||||
var c = function () {};
|
||||
c.prototype = parent;
|
||||
return new c();
|
||||
};
|
||||
|
||||
// private utility functions
|
||||
|
||||
function __objToStr(o) {
|
||||
return Object.prototype.toString.call(o);
|
||||
};
|
||||
clone.__objToStr = __objToStr;
|
||||
|
||||
function __isDate(o) {
|
||||
return typeof o === 'object' && __objToStr(o) === '[object Date]';
|
||||
};
|
||||
clone.__isDate = __isDate;
|
||||
|
||||
function __isArray(o) {
|
||||
return typeof o === 'object' && __objToStr(o) === '[object Array]';
|
||||
};
|
||||
clone.__isArray = __isArray;
|
||||
|
||||
function __isRegExp(o) {
|
||||
return typeof o === 'object' && __objToStr(o) === '[object RegExp]';
|
||||
};
|
||||
clone.__isRegExp = __isRegExp;
|
||||
|
||||
function __getRegExpFlags(re) {
|
||||
var flags = '';
|
||||
if (re.global) flags += 'g';
|
||||
if (re.ignoreCase) flags += 'i';
|
||||
if (re.multiline) flags += 'm';
|
||||
return flags;
|
||||
};
|
||||
clone.__getRegExpFlags = __getRegExpFlags;
|
||||
|
||||
return clone;
|
||||
})();
|
||||
|
||||
if (typeof module === 'object' && module.exports) {
|
||||
module.exports = clone;
|
||||
}
|
||||
133
node_modules/forever/node_modules/clone/package.json
generated
vendored
Normal file
133
node_modules/forever/node_modules/clone/package.json
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
{
|
||||
"name": "clone",
|
||||
"description": "deep cloning of objects and arrays",
|
||||
"tags": [
|
||||
"clone",
|
||||
"object",
|
||||
"array",
|
||||
"function",
|
||||
"date"
|
||||
],
|
||||
"version": "1.0.2",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/pvorb/node-clone.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/pvorb/node-clone/issues"
|
||||
},
|
||||
"main": "clone.js",
|
||||
"author": {
|
||||
"name": "Paul Vorbach",
|
||||
"email": "paul@vorba.ch",
|
||||
"url": "http://paul.vorba.ch/"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Blake Miner",
|
||||
"email": "miner.blake@gmail.com",
|
||||
"url": "http://www.blakeminer.com/"
|
||||
},
|
||||
{
|
||||
"name": "Tian You",
|
||||
"email": "axqd001@gmail.com",
|
||||
"url": "http://blog.axqd.net/"
|
||||
},
|
||||
{
|
||||
"name": "George Stagas",
|
||||
"email": "gstagas@gmail.com",
|
||||
"url": "http://stagas.com/"
|
||||
},
|
||||
{
|
||||
"name": "Tobiasz Cudnik",
|
||||
"email": "tobiasz.cudnik@gmail.com",
|
||||
"url": "https://github.com/TobiaszCudnik"
|
||||
},
|
||||
{
|
||||
"name": "Pavel Lang",
|
||||
"email": "langpavel@phpskelet.org",
|
||||
"url": "https://github.com/langpavel"
|
||||
},
|
||||
{
|
||||
"name": "Dan MacTough",
|
||||
"url": "http://yabfog.com/"
|
||||
},
|
||||
{
|
||||
"name": "w1nk",
|
||||
"url": "https://github.com/w1nk"
|
||||
},
|
||||
{
|
||||
"name": "Hugh Kennedy",
|
||||
"url": "http://twitter.com/hughskennedy"
|
||||
},
|
||||
{
|
||||
"name": "Dustin Diaz",
|
||||
"url": "http://dustindiaz.com"
|
||||
},
|
||||
{
|
||||
"name": "Ilya Shaisultanov",
|
||||
"url": "https://github.com/diversario"
|
||||
},
|
||||
{
|
||||
"name": "Nathan MacInnes",
|
||||
"email": "nathan@macinn.es",
|
||||
"url": "http://macinn.es/"
|
||||
},
|
||||
{
|
||||
"name": "Benjamin E. Coe",
|
||||
"email": "ben@npmjs.com",
|
||||
"url": "https://twitter.com/benjamincoe"
|
||||
},
|
||||
{
|
||||
"name": "Nathan Zadoks",
|
||||
"url": "https://github.com/nathan7"
|
||||
},
|
||||
{
|
||||
"name": "Róbert Oroszi",
|
||||
"email": "robert+gh@oroszi.net",
|
||||
"url": "https://github.com/oroce"
|
||||
},
|
||||
{
|
||||
"name": "Aurélio A. Heckert",
|
||||
"url": "http://softwarelivre.org/aurium"
|
||||
},
|
||||
{
|
||||
"name": "Guy Ellis",
|
||||
"url": "http://www.guyellisrocks.com/"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.8"
|
||||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"nodeunit": "~0.9.0"
|
||||
},
|
||||
"optionalDependencies": {},
|
||||
"scripts": {
|
||||
"test": "nodeunit test.js"
|
||||
},
|
||||
"gitHead": "0e8216efc672496b612fd7ab62159117d16ec4a0",
|
||||
"homepage": "https://github.com/pvorb/node-clone",
|
||||
"_id": "clone@1.0.2",
|
||||
"_shasum": "260b7a99ebb1edfe247538175f783243cb19d149",
|
||||
"_from": "clone@>=1.0.2 <2.0.0",
|
||||
"_npmVersion": "1.4.14",
|
||||
"_npmUser": {
|
||||
"name": "pvorb",
|
||||
"email": "paul@vorba.ch"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "pvorb",
|
||||
"email": "paul@vorb.de"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "260b7a99ebb1edfe247538175f783243cb19d149",
|
||||
"tarball": "http://registry.npmjs.org/clone/-/clone-1.0.2.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz"
|
||||
}
|
||||
22
node_modules/forever/node_modules/clone/test-apart-ctx.html
generated
vendored
Normal file
22
node_modules/forever/node_modules/clone/test-apart-ctx.html
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Clone Test-Suite (Browser)</title>
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
var data = document.location.search.substr(1).split('&');
|
||||
try {
|
||||
ctx = parent[data[0]];
|
||||
eval(decodeURIComponent(data[1]));
|
||||
window.results = results;
|
||||
} catch(e) {
|
||||
var extra = '';
|
||||
if (e.name == 'SecurityError')
|
||||
extra = 'This test suite needs to be run on an http server.';
|
||||
alert('Apart Context iFrame Error\n' + e + '\n\n' + extra);
|
||||
throw e;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
148
node_modules/forever/node_modules/clone/test.html
generated
vendored
Normal file
148
node_modules/forever/node_modules/clone/test.html
generated
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Clone Test-Suite (Browser)</title>
|
||||
<script>
|
||||
var module = {};
|
||||
var tests = exports = module.exports = {};
|
||||
|
||||
function require(moduleName) {
|
||||
if (moduleName == './') {
|
||||
return clone;
|
||||
}
|
||||
}
|
||||
|
||||
function log(str) {
|
||||
logList.innerHTML += '<li>' + str + '</li>';
|
||||
}
|
||||
</script>
|
||||
<script src="clone.js"></script>
|
||||
<script src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1 id="nodeunit-header">Clone Test-Suite (Browser)</h1>
|
||||
Tests started: <span id="testsStarted"></span>;
|
||||
Tests finished: <span id="testsFinished"></span>.
|
||||
<ul id="logList"></ul>
|
||||
<script>
|
||||
/* Methods copied from
|
||||
* https://github.com/caolan/nodeunit/blob/master/lib/assert.js
|
||||
*/
|
||||
function isUndefinedOrNull(value) {
|
||||
return value === null || value === undefined;
|
||||
}
|
||||
|
||||
function isArguments(object) {
|
||||
return Object.prototype.toString.call(object) == '[object Arguments]';
|
||||
}
|
||||
|
||||
var _keys = function (obj){
|
||||
if (Object.keys) return Object.keys(obj);
|
||||
if (typeof obj != 'object' && typeof obj != 'function') {
|
||||
throw new TypeError('-');
|
||||
}
|
||||
var keys = [];
|
||||
for(var k in obj) if(obj.hasOwnProperty(k)) keys.push(k);
|
||||
return keys;
|
||||
};
|
||||
|
||||
function objEquiv(a, b) {
|
||||
if (isUndefinedOrNull(a) || isUndefinedOrNull(b))
|
||||
return false;
|
||||
|
||||
if (a.prototype !== b.prototype)
|
||||
return false;
|
||||
|
||||
if (isArguments(a)) {
|
||||
if (!isArguments(b)) return false;
|
||||
a = pSlice.call(a);
|
||||
b = pSlice.call(b);
|
||||
return _deepEqual(a, b);
|
||||
}
|
||||
|
||||
try {
|
||||
var ka = _keys(a), kb = _keys(b), key, i;
|
||||
} catch (e) {
|
||||
return false
|
||||
}
|
||||
|
||||
if (ka.length != kb.length)
|
||||
return false;
|
||||
|
||||
ka.sort();
|
||||
kb.sort();
|
||||
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
if (ka[i] != kb[i]) return false;
|
||||
}
|
||||
|
||||
for (i = ka.length - 1; i >= 0; i--) {
|
||||
key = ka[i];
|
||||
if (!_deepEqual(a[key], b[key] ))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
function _deepEqual(actual, expected) {
|
||||
if (actual === expected) {
|
||||
return true;
|
||||
} else if (actual instanceof Date && expected instanceof Date) {
|
||||
return actual.getTime() === expected.getTime();
|
||||
} else if (actual instanceof RegExp && expected instanceof RegExp) {
|
||||
return actual.source === expected.source &&
|
||||
actual.global === expected.global &&
|
||||
actual.ignoreCase === expected.ignoreCase &&
|
||||
actual.multiline === expected.multiline;
|
||||
} else if (typeof actual != 'object' && typeof expected != 'object') {
|
||||
return actual == expected;
|
||||
} else {
|
||||
return objEquiv(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
for (var testName in tests) {
|
||||
setTimeout((function (testName) {
|
||||
try {
|
||||
testsStarted.innerHTML = (parseInt(testsStarted.innerHTML) || 0) + 1;
|
||||
function incFinished() {
|
||||
testsFinished.innerHTML = (parseInt(testsFinished.innerHTML) || 0) + 1;
|
||||
}
|
||||
|
||||
tests[testName]({
|
||||
expect: function (num) {
|
||||
this._expect = num
|
||||
},
|
||||
ok: function (val) {
|
||||
if(!val) throw new Error(val + ' is not ok.')
|
||||
},
|
||||
equal: function (a,b) {
|
||||
if (a != b) throw new Error(a + ' is not equal to ' + b)
|
||||
},
|
||||
notEqual: function (a,b) {
|
||||
if (a == b) throw new Error(a + ' is equal to ' + b)
|
||||
},
|
||||
strictEqual: function (a,b) {
|
||||
if (a !== b) throw new Error(a + ' is not strict equal to ' + b)
|
||||
},
|
||||
deepEqual: function (a,b) {
|
||||
if (!_deepEqual(a,b))
|
||||
throw new Error(JSON.stringify(a) + ' is not deep equal to ' +
|
||||
JSON.stringify(b))
|
||||
},
|
||||
done: function () {
|
||||
log(testName + ' <span style="color:blue">is ok</span>.');
|
||||
incFinished();
|
||||
}
|
||||
});
|
||||
} catch(e) {
|
||||
log(testName + ' <span style="color:red">FAIL.</span> <small>'+ e +'</small>');
|
||||
incFinished();
|
||||
console.log(e);
|
||||
}
|
||||
})(testName), 1);
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
372
node_modules/forever/node_modules/clone/test.js
generated
vendored
Normal file
372
node_modules/forever/node_modules/clone/test.js
generated
vendored
Normal file
@@ -0,0 +1,372 @@
|
||||
var clone = require('./');
|
||||
|
||||
function inspect(obj) {
|
||||
seen = [];
|
||||
return JSON.stringify(obj, function (key, val) {
|
||||
if (val != null && typeof val == "object") {
|
||||
if (seen.indexOf(val) >= 0) {
|
||||
return '[cyclic]';
|
||||
}
|
||||
|
||||
seen.push(val);
|
||||
}
|
||||
|
||||
return val;
|
||||
});
|
||||
}
|
||||
|
||||
// Creates a new VM in node, or an iframe in a browser in order to run the
|
||||
// script
|
||||
function apartContext(context, script, callback) {
|
||||
var vm = require('vm');
|
||||
|
||||
if (vm) {
|
||||
var ctx = vm.createContext({ ctx: context });
|
||||
callback(vm.runInContext(script, ctx));
|
||||
} else if (document && document.createElement) {
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.style.display = 'none';
|
||||
document.body.appendChild(iframe);
|
||||
|
||||
var myCtxId = 'tmpCtx' + Math.random();
|
||||
|
||||
window[myCtxId] = context;
|
||||
iframe.src = 'test-apart-ctx.html?' + myCtxId + '&' + encodeURIComponent(script);
|
||||
iframe.onload = function() {
|
||||
try {
|
||||
callback(iframe.contentWindow.results);
|
||||
} catch (e) {
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
console.log('WARNING: cannot create an apart context.');
|
||||
}
|
||||
}
|
||||
|
||||
exports["clone string"] = function (test) {
|
||||
test.expect(2); // how many tests?
|
||||
|
||||
var a = "foo";
|
||||
test.strictEqual(clone(a), a);
|
||||
a = "";
|
||||
test.strictEqual(clone(a), a);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["clone number"] = function (test) {
|
||||
test.expect(5); // how many tests?
|
||||
|
||||
var a = 0;
|
||||
test.strictEqual(clone(a), a);
|
||||
a = 1;
|
||||
test.strictEqual(clone(a), a);
|
||||
a = -1000;
|
||||
test.strictEqual(clone(a), a);
|
||||
a = 3.1415927;
|
||||
test.strictEqual(clone(a), a);
|
||||
a = -3.1415927;
|
||||
test.strictEqual(clone(a), a);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["clone date"] = function (test) {
|
||||
test.expect(3); // how many tests?
|
||||
|
||||
var a = new Date;
|
||||
var c = clone(a);
|
||||
test.ok(!!a.getUTCDate && !!a.toUTCString);
|
||||
test.ok(!!c.getUTCDate && !!c.toUTCString);
|
||||
test.equal(a.getTime(), c.getTime());
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["clone object"] = function (test) {
|
||||
test.expect(1); // how many tests?
|
||||
|
||||
var a = { foo: { bar: "baz" } };
|
||||
var b = clone(a);
|
||||
|
||||
test.deepEqual(b, a);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["clone array"] = function (test) {
|
||||
test.expect(2); // how many tests?
|
||||
|
||||
var a = [
|
||||
{ foo: "bar" },
|
||||
"baz"
|
||||
];
|
||||
var b = clone(a);
|
||||
|
||||
test.ok(b instanceof Array);
|
||||
test.deepEqual(b, a);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["clone buffer"] = function (test) {
|
||||
if (typeof Buffer == 'undefined') {
|
||||
return test.done();
|
||||
}
|
||||
|
||||
test.expect(1);
|
||||
|
||||
var a = new Buffer("this is a test buffer");
|
||||
var b = clone(a);
|
||||
|
||||
// no underscore equal since it has no concept of Buffers
|
||||
test.deepEqual(b, a);
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["clone regexp"] = function (test) {
|
||||
test.expect(5);
|
||||
|
||||
var a = /abc123/gi;
|
||||
var b = clone(a);
|
||||
test.deepEqual(b, a);
|
||||
|
||||
var c = /a/g;
|
||||
test.ok(c.lastIndex === 0);
|
||||
|
||||
c.exec('123a456a');
|
||||
test.ok(c.lastIndex === 4);
|
||||
|
||||
var d = clone(c);
|
||||
test.ok(d.global);
|
||||
test.ok(d.lastIndex === 4);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["clone object containing array"] = function (test) {
|
||||
test.expect(1); // how many tests?
|
||||
|
||||
var a = {
|
||||
arr1: [ { a: '1234', b: '2345' } ],
|
||||
arr2: [ { c: '345', d: '456' } ]
|
||||
};
|
||||
|
||||
var b = clone(a);
|
||||
|
||||
test.deepEqual(b, a);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["clone object with circular reference"] = function (test) {
|
||||
test.expect(8); // how many tests?
|
||||
|
||||
var c = [1, "foo", {'hello': 'bar'}, function () {}, false, [2]];
|
||||
var b = [c, 2, 3, 4];
|
||||
|
||||
var a = {'b': b, 'c': c};
|
||||
a.loop = a;
|
||||
a.loop2 = a;
|
||||
c.loop = c;
|
||||
c.aloop = a;
|
||||
|
||||
var aCopy = clone(a);
|
||||
test.ok(a != aCopy);
|
||||
test.ok(a.c != aCopy.c);
|
||||
test.ok(aCopy.c == aCopy.b[0]);
|
||||
test.ok(aCopy.c.loop.loop.aloop == aCopy);
|
||||
test.ok(aCopy.c[0] == a.c[0]);
|
||||
|
||||
test.ok(eq(a, aCopy));
|
||||
aCopy.c[0] = 2;
|
||||
test.ok(!eq(a, aCopy));
|
||||
aCopy.c = "2";
|
||||
test.ok(!eq(a, aCopy));
|
||||
|
||||
function eq(x, y) {
|
||||
return inspect(x) === inspect(y);
|
||||
}
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports['clone prototype'] = function (test) {
|
||||
test.expect(3); // how many tests?
|
||||
|
||||
var a = {
|
||||
a: "aaa",
|
||||
x: 123,
|
||||
y: 45.65
|
||||
};
|
||||
var b = clone.clonePrototype(a);
|
||||
|
||||
test.strictEqual(b.a, a.a);
|
||||
test.strictEqual(b.x, a.x);
|
||||
test.strictEqual(b.y, a.y);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports['clone within an apart context'] = function (test) {
|
||||
var results = apartContext({ clone: clone },
|
||||
"results = ctx.clone({ a: [1, 2, 3], d: new Date(), r: /^foo$/ig })",
|
||||
function (results) {
|
||||
test.ok(results.a.constructor.toString() === Array.toString());
|
||||
test.ok(results.d.constructor.toString() === Date.toString());
|
||||
test.ok(results.r.constructor.toString() === RegExp.toString());
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
exports['clone object with no constructor'] = function (test) {
|
||||
test.expect(3);
|
||||
|
||||
var n = null;
|
||||
|
||||
var a = { foo: 'bar' };
|
||||
a.__proto__ = n;
|
||||
test.ok(typeof a === 'object');
|
||||
test.ok(typeof a !== null);
|
||||
|
||||
var b = clone(a);
|
||||
test.ok(a.foo, b.foo);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports['clone object with depth argument'] = function (test) {
|
||||
test.expect(6);
|
||||
|
||||
var a = {
|
||||
foo: {
|
||||
bar : {
|
||||
baz : 'qux'
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var b = clone(a, false, 1);
|
||||
test.deepEqual(b, a);
|
||||
test.notEqual(b, a);
|
||||
test.strictEqual(b.foo, a.foo);
|
||||
|
||||
b = clone(a, true, 2);
|
||||
test.deepEqual(b, a);
|
||||
test.notEqual(b.foo, a.foo);
|
||||
test.strictEqual(b.foo.bar, a.foo.bar);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports['maintain prototype chain in clones'] = function (test) {
|
||||
test.expect(1);
|
||||
|
||||
function T() {}
|
||||
|
||||
var a = new T();
|
||||
var b = clone(a);
|
||||
test.strictEqual(Object.getPrototypeOf(a), Object.getPrototypeOf(b));
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports['parent prototype is overriden with prototype provided'] = function (test) {
|
||||
test.expect(1);
|
||||
|
||||
function T() {}
|
||||
|
||||
var a = new T();
|
||||
var b = clone(a, true, Infinity, null);
|
||||
test.strictEqual(b.__defineSetter__, undefined);
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports['clone object with null children'] = function (test) {
|
||||
test.expect(1);
|
||||
var a = {
|
||||
foo: {
|
||||
bar: null,
|
||||
baz: {
|
||||
qux: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var b = clone(a);
|
||||
|
||||
test.deepEqual(b, a);
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports['clone instance with getter'] = function (test) {
|
||||
test.expect(1);
|
||||
function Ctor() {};
|
||||
Object.defineProperty(Ctor.prototype, 'prop', {
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
get: function() {
|
||||
return 'value';
|
||||
}
|
||||
});
|
||||
|
||||
var a = new Ctor();
|
||||
var b = clone(a);
|
||||
|
||||
test.strictEqual(b.prop, 'value');
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports['get RegExp flags'] = function (test) {
|
||||
test.strictEqual(clone.__getRegExpFlags(/a/), '' );
|
||||
test.strictEqual(clone.__getRegExpFlags(/a/i), 'i' );
|
||||
test.strictEqual(clone.__getRegExpFlags(/a/g), 'g' );
|
||||
test.strictEqual(clone.__getRegExpFlags(/a/gi), 'gi');
|
||||
test.strictEqual(clone.__getRegExpFlags(/a/m), 'm' );
|
||||
|
||||
test.done();
|
||||
};
|
||||
|
||||
exports["recognize Array object"] = function (test) {
|
||||
var results = apartContext(null, "results = [1, 2, 3]", function(alien) {
|
||||
var local = [4, 5, 6];
|
||||
test.ok(clone.__isArray(alien)); // recognize in other context.
|
||||
test.ok(clone.__isArray(local)); // recognize in local context.
|
||||
test.ok(!clone.__isDate(alien));
|
||||
test.ok(!clone.__isDate(local));
|
||||
test.ok(!clone.__isRegExp(alien));
|
||||
test.ok(!clone.__isRegExp(local));
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
exports["recognize Date object"] = function (test) {
|
||||
var results = apartContext(null, "results = new Date()", function(alien) {
|
||||
var local = new Date();
|
||||
|
||||
test.ok(clone.__isDate(alien)); // recognize in other context.
|
||||
test.ok(clone.__isDate(local)); // recognize in local context.
|
||||
test.ok(!clone.__isArray(alien));
|
||||
test.ok(!clone.__isArray(local));
|
||||
test.ok(!clone.__isRegExp(alien));
|
||||
test.ok(!clone.__isRegExp(local));
|
||||
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
exports["recognize RegExp object"] = function (test) {
|
||||
var results = apartContext(null, "results = /foo/", function(alien) {
|
||||
var local = /bar/;
|
||||
|
||||
test.ok(clone.__isRegExp(alien)); // recognize in other context.
|
||||
test.ok(clone.__isRegExp(local)); // recognize in local context.
|
||||
test.ok(!clone.__isArray(alien));
|
||||
test.ok(!clone.__isArray(local));
|
||||
test.ok(!clone.__isDate(alien));
|
||||
test.ok(!clone.__isDate(local));
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
219
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/CHANGELOG.md
generated
vendored
Normal file
219
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/CHANGELOG.md
generated
vendored
Normal file
@@ -0,0 +1,219 @@
|
||||
# Chokidar 1.2.0 (1 October 2015)
|
||||
* Allow nested arrays of paths to be provided to `.watch()` and `.add()`
|
||||
* Add `awaitWriteFinish` option
|
||||
|
||||
# Chokidar 1.1.0 (23 September 2015)
|
||||
* Dependency updates including fsevents@1.0.0, improving installation
|
||||
|
||||
# Chokidar 1.0.6 (18 September 2015)
|
||||
* Fix issue with `.unwatch()` method and relative paths
|
||||
|
||||
# Chokidar 1.0.5 (20 July 2015)
|
||||
* Fix regression with regexes/fns using in `ignored`
|
||||
|
||||
# Chokidar 1.0.4 (15 July 2015)
|
||||
* Fix bug with `ignored` files/globs while `cwd` option is set
|
||||
|
||||
# Chokidar 1.0.3 (4 June 2015)
|
||||
* Fix race issue with `alwaysStat` option and removed files
|
||||
|
||||
# Chokidar 1.0.2 (30 May 2015)
|
||||
* Fix bug with absolute paths and ENAMETOOLONG error
|
||||
|
||||
# Chokidar 1.0.1 (8 April 2015)
|
||||
* Fix bug with `.close()` method in `fs.watch` mode with `persistent: false` option
|
||||
|
||||
# Chokidar 1.0.0 (7 April 2015)
|
||||
* Glob support! Use globs in `watch`, `add`, and `unwatch` methods
|
||||
* Comprehensive symlink support
|
||||
* New `unwatch` method to turn off watching of previously watched paths
|
||||
* More flexible `ignored` option allowing regex, function, glob, or array courtesy of [anymatch](https://github.com/es128/anymatch)
|
||||
* New `cwd` option to set base dir from which relative paths are derived
|
||||
* New `depth` option for limiting recursion
|
||||
* New `alwaysStat` option to ensure [`fs.Stats`](https://nodejs.org/api/fs.html#fs_class_fs_stats) gets passed with every add/change event
|
||||
* New `ready` event emitted when initial fs tree scan is done and watcher is ready for changes
|
||||
* New `raw` event exposing data and events from the lower-level watch modules
|
||||
* New `followSymlinks` option to impact whether symlinks' targets or the symlink files themselves are watched
|
||||
* New `atomic` option for normalizing artifacts from text editors that use atomic write methods
|
||||
* Ensured watcher's stability with lots of bugfixes.
|
||||
|
||||
# Chokidar 0.12.6 (6 January 2015)
|
||||
* Fix bug which breaks `persistent: false` mode when change events occur
|
||||
|
||||
# Chokidar 0.12.5 (17 December 2014)
|
||||
* Fix bug with matching parent path detection for fsevents instance sharing
|
||||
* Fix bug with ignored watch path in nodefs modes
|
||||
|
||||
# Chokidar 0.12.4 (14 December 2014)
|
||||
* Fix bug in `fs.watch` mode that caused watcher to leak into `cwd`
|
||||
* Fix bug preventing ready event when there are symlinks to ignored paths
|
||||
|
||||
# Chokidar 0.12.3 (13 December 2014)
|
||||
* Fix handling of special files such as named pipes and sockets
|
||||
|
||||
# Chokidar 0.12.2 (12 December 2014)
|
||||
* Fix recursive symlink handling and some other path resolution problems
|
||||
|
||||
# Chokidar 0.12.1 (10 December 2014)
|
||||
* Fix a case where file symlinks were not followed properly
|
||||
|
||||
# Chokidar 0.12.0 (8 December 2014)
|
||||
* Symlink support
|
||||
* Add `followSymlinks` option, which defaults to `true`
|
||||
* Change default watch mode on Linux to non-polling `fs.watch`
|
||||
* Add `atomic` option to normalize events from editors using atomic writes
|
||||
* Particularly Vim and Sublime
|
||||
* Add `raw` event which exposes data from the underlying watch method
|
||||
|
||||
# Chokidar 0.11.1 (19 November 2014)
|
||||
* Fix a bug where an error is thrown when `fs.watch` instantiation fails
|
||||
|
||||
# Chokidar 0.11.0 (16 November 2014)
|
||||
* Add a `ready` event, which is emitted after initial file scan completes
|
||||
* Fix issue with options keys passed in defined as `undefined`
|
||||
* Rename some internal `FSWatcher` properties to indicate they're private
|
||||
|
||||
# Chokidar 0.10.9 (15 November 2014)
|
||||
* Fix some leftover issues from adding watcher reuse
|
||||
|
||||
# Chokidar 0.10.8 (14 November 2014)
|
||||
* Remove accidentally committed/published `console.log` statement.
|
||||
* Sry 'bout that :crying_cat_face:
|
||||
|
||||
# Chokidar 0.10.7 (14 November 2014)
|
||||
* Apply watcher reuse methodology to `fs.watch` and `fs.watchFile` as well
|
||||
|
||||
# Chokidar 0.10.6 (12 November 2014)
|
||||
* More efficient creation/reuse of FSEvents instances to avoid system limits
|
||||
* Reduce simultaneous FSEvents instances allowed in a process
|
||||
* Handle errors thrown by `fs.watch` upon invocation
|
||||
|
||||
# Chokidar 0.10.5 (6 November 2014)
|
||||
* Limit number of simultaneous FSEvents instances (fall back to other methods)
|
||||
* Prevent some cases of EMFILE errors during initialization
|
||||
* Fix ignored files emitting events in some fsevents-mode circumstances
|
||||
|
||||
# Chokidar 0.10.4 (5 November 2014)
|
||||
* Bump fsevents dependency to ~0.3.1
|
||||
* Should resolve build warnings and `npm rebuild` on non-Macs
|
||||
|
||||
# Chokidar 0.10.3 (28 October 2014)
|
||||
* Fix removed dir emitting as `unlink` instead of `unlinkDir`
|
||||
* Fix issues with file changing to dir or vice versa (gh-165)
|
||||
* Fix handling of `ignored` option in fsevents mode
|
||||
|
||||
# Chokidar 0.10.2 (23 October 2014)
|
||||
* Improve individual file watching
|
||||
* Fix fsevents keeping process alive when `persistent: false`
|
||||
|
||||
# Chokidar 0.10.1 (19 October 2014)
|
||||
* Improve handling of text editor atomic writes
|
||||
|
||||
# Chokidar 0.10.0 (18 October 2014)
|
||||
* Many stability and consistency improvements
|
||||
* Resolve many cases of duplicate or wrong events
|
||||
* Correct for fsevents inconsistencies
|
||||
* Standardize handling of errors and relative paths
|
||||
* Fix issues with watching `./`
|
||||
|
||||
# Chokidar 0.9.0 (25 September 2014)
|
||||
* Updated fsevents to 0.3
|
||||
* Update per-system defaults
|
||||
* Fix issues with closing chokidar instance
|
||||
* Fix duplicate change events on win32
|
||||
|
||||
# Chokidar 0.8.2 (26 March 2014)
|
||||
* Fixed npm issues related to fsevents dep.
|
||||
* Updated fsevents to 0.2.
|
||||
|
||||
# Chokidar 0.8.1 (16 December 2013)
|
||||
* Optional deps are now truly optional on windows and
|
||||
linux.
|
||||
* Rewritten in JS, again.
|
||||
* Fixed some FSEvents-related bugs.
|
||||
|
||||
# Chokidar 0.8.0 (29 November 2013)
|
||||
* Added ultra-fast low-CPU OS X file watching with FSEvents.
|
||||
It is enabled by default.
|
||||
* Added `addDir` and `unlinkDir` events.
|
||||
* Polling is now disabled by default on all platforms.
|
||||
|
||||
# Chokidar 0.7.1 (18 November 2013)
|
||||
* `Watcher#close` now also removes all event listeners.
|
||||
|
||||
# Chokidar 0.7.0 (22 October 2013)
|
||||
* When `options.ignored` is two-argument function, it will
|
||||
also be called after stating the FS, with `stats` argument.
|
||||
* `unlink` is no longer emitted on directories.
|
||||
|
||||
# Chokidar 0.6.3 (12 August 2013)
|
||||
* Added `usePolling` option (default: `true`).
|
||||
When `false`, chokidar will use `fs.watch` as backend.
|
||||
`fs.watch` is much faster, but not like super reliable.
|
||||
|
||||
# Chokidar 0.6.2 (19 March 2013)
|
||||
* Fixed watching initially empty directories with `ignoreInitial` option.
|
||||
|
||||
# Chokidar 0.6.1 (19 March 2013)
|
||||
* Added node.js 0.10 support.
|
||||
|
||||
# Chokidar 0.6.0 (10 March 2013)
|
||||
* File attributes (stat()) are now passed to `add` and `change` events
|
||||
as second arguments.
|
||||
* Changed default polling interval for binary files to 300ms.
|
||||
|
||||
# Chokidar 0.5.3 (13 January 2013)
|
||||
* Removed emitting of `change` events before `unlink`.
|
||||
|
||||
# Chokidar 0.5.2 (13 January 2013)
|
||||
* Removed postinstall script to prevent various npm bugs.
|
||||
|
||||
# Chokidar 0.5.1 (6 January 2013)
|
||||
* When starting to watch non-existing paths, chokidar will no longer throw
|
||||
ENOENT error.
|
||||
* Fixed bug with absolute path.
|
||||
|
||||
# Chokidar 0.5.0 (9 December 2012)
|
||||
* Added a bunch of new options:
|
||||
* `ignoreInitial` that allows to ignore initial `add` events.
|
||||
* `ignorePermissionErrors` that allows to ignore ENOENT etc perm errors.
|
||||
* `interval` and `binaryInterval` that allow to change default
|
||||
fs polling intervals.
|
||||
|
||||
# Chokidar 0.4.0 (26 July 2012)
|
||||
* Added `all` event that receives two args (event name and path) that
|
||||
combines `add`, `change` and `unlink` events.
|
||||
* Switched to `fs.watchFile` on node.js 0.8 on windows.
|
||||
* Files are now correctly unwatched after unlink.
|
||||
|
||||
# Chokidar 0.3.0 (24 June 2012)
|
||||
* `unlink` event are no longer emitted for directories, for consistency
|
||||
with `add`.
|
||||
|
||||
# Chokidar 0.2.6 (8 June 2012)
|
||||
* Prevented creating of duplicate 'add' events.
|
||||
|
||||
# Chokidar 0.2.5 (8 June 2012)
|
||||
* Fixed a bug when new files in new directories hadn't been added.
|
||||
|
||||
# Chokidar 0.2.4 (7 June 2012)
|
||||
* Fixed a bug when unlinked files emitted events after unlink.
|
||||
|
||||
# Chokidar 0.2.3 (12 May 2012)
|
||||
* Fixed watching of files on windows.
|
||||
|
||||
# Chokidar 0.2.2 (4 May 2012)
|
||||
* Fixed watcher signature.
|
||||
|
||||
# Chokidar 0.2.1 (4 May 2012)
|
||||
* Fixed invalid API bug when using `watch()`.
|
||||
|
||||
# Chokidar 0.2.0 (4 May 2012)
|
||||
* Rewritten in js.
|
||||
|
||||
# Chokidar 0.1.1 (26 April 2012)
|
||||
* Changed api to `chokidar.watch()`.
|
||||
* Fixed compilation on windows.
|
||||
|
||||
# Chokidar 0.1.0 (20 April 2012)
|
||||
* Initial release.
|
||||
272
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/README.md
generated
vendored
Normal file
272
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/README.md
generated
vendored
Normal file
@@ -0,0 +1,272 @@
|
||||
# Chokidar [](https://travis-ci.org/paulmillr/chokidar) [](https://ci.appveyor.com/project/es128/chokidar/branch/master) [](https://coveralls.io/r/paulmillr/chokidar) [](https://gitter.im/paulmillr/chokidar?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
A neat wrapper around node.js fs.watch / fs.watchFile / fsevents.
|
||||
|
||||
[](https://nodei.co/npm/chokidar/)
|
||||
[](https://nodei.co/npm/chokidar/)
|
||||
|
||||
#### [See what's new in v1.0](https://github.com/paulmillr/chokidar/blob/master/CHANGELOG.md#chokidar-100-7-april-2015)
|
||||
|
||||
## Why?
|
||||
Node.js `fs.watch`:
|
||||
|
||||
* Doesn't report filenames on OS X.
|
||||
* Doesn't report events at all when using editors like Sublime on OS X.
|
||||
* Often reports events twice.
|
||||
* Emits most changes as `rename`.
|
||||
* Has [a lot of other issues](https://github.com/joyent/node/search?q=fs.watch&type=Issues)
|
||||
* Does not provide an easy way to recursively watch file trees.
|
||||
|
||||
Node.js `fs.watchFile`:
|
||||
|
||||
* Almost as bad at event handling.
|
||||
* Also does not provide any recursive watching.
|
||||
* Results in high CPU utilization.
|
||||
|
||||
Chokidar resolves these problems.
|
||||
|
||||
It is used in
|
||||
[brunch](http://brunch.io),
|
||||
[karma](http://karma-runner.github.io),
|
||||
[PM2](https://github.com/Unitech/PM2),
|
||||
[browserify](http://browserify.org/),
|
||||
[webpack](http://webpack.github.io/),
|
||||
[BrowserSync](http://www.browsersync.io/),
|
||||
[socketstream](http://www.socketstream.org),
|
||||
[derby](http://derbyjs.com/),
|
||||
and [many others](https://www.npmjs.org/browse/depended/chokidar/).
|
||||
It has proven itself in production environments.
|
||||
|
||||
## How?
|
||||
Chokidar does still rely on the Node.js core `fs` module, but when using
|
||||
`fs.watch` and `fs.watchFile` for watching, it normalizes the events it
|
||||
receives, often checking for truth by getting file stats and/or dir contents.
|
||||
|
||||
On Mac OS X, chokidar by default uses a native extension exposing the Darwin
|
||||
`FSEvents` API. This provides very efficient recursive watching compared with
|
||||
implementations like `kqueue` available on most \*nix platforms. Chokidar still
|
||||
does have to do some work to normalize the events received that way as well.
|
||||
|
||||
On other platforms, the `fs.watch`-based implementation is the default, which
|
||||
avoids polling and keeps CPU usage down. Be advised that chokidar will initiate
|
||||
watchers recursively for everything within scope of the paths that have been
|
||||
specified, so be judicious about not wasting system resources by watching much
|
||||
more than needed.
|
||||
|
||||
## Getting started
|
||||
Install with npm:
|
||||
|
||||
npm install chokidar --save
|
||||
|
||||
Then `require` and use it in your code:
|
||||
|
||||
```javascript
|
||||
var chokidar = require('chokidar');
|
||||
|
||||
// One-liner for current directory, ignores .dotfiles
|
||||
chokidar.watch('.', {ignored: /[\/\\]\./}).on('all', function(event, path) {
|
||||
console.log(event, path);
|
||||
});
|
||||
|
||||
|
||||
// Example of a more typical implementation structure:
|
||||
|
||||
// Initialize watcher
|
||||
var watcher = chokidar.watch('file, dir, or glob', {
|
||||
ignored: /[\/\\]\./,
|
||||
persistent: true
|
||||
});
|
||||
|
||||
// something to use when events are received
|
||||
var log = console.log.bind(console);
|
||||
|
||||
// Add event listeners
|
||||
watcher
|
||||
.on('add', function(path) { log('File', path, 'has been added'); })
|
||||
.on('change', function(path) { log('File', path, 'has been changed'); })
|
||||
.on('unlink', function(path) { log('File', path, 'has been removed'); })
|
||||
// More events.
|
||||
.on('addDir', function(path) { log('Directory', path, 'has been added'); })
|
||||
.on('unlinkDir', function(path) { log('Directory', path, 'has been removed'); })
|
||||
.on('error', function(error) { log('Error happened', error); })
|
||||
.on('ready', function() { log('Initial scan complete. Ready for changes.'); })
|
||||
.on('raw', function(event, path, details) { log('Raw event info:', event, path, details); })
|
||||
|
||||
// 'add', 'addDir' and 'change' events also receive stat() results as second
|
||||
// argument when available: http://nodejs.org/api/fs.html#fs_class_fs_stats
|
||||
watcher.on('change', function(path, stats) {
|
||||
if (stats) console.log('File', path, 'changed size to', stats.size);
|
||||
});
|
||||
|
||||
// Watch new files.
|
||||
watcher.add('new-file');
|
||||
watcher.add(['new-file-2', 'new-file-3', '**/other-file*']);
|
||||
|
||||
// Un-watch some files.
|
||||
watcher.unwatch('new-file*');
|
||||
|
||||
// Only needed if watching is `persistent: true`.
|
||||
watcher.close();
|
||||
|
||||
// Full list of options. See below for descriptions. (do not use this example)
|
||||
chokidar.watch('file', {
|
||||
persistent: true,
|
||||
|
||||
ignored: '*.txt',
|
||||
ignoreInitial: false,
|
||||
followSymlinks: true,
|
||||
cwd: '.',
|
||||
|
||||
usePolling: true,
|
||||
interval: 100,
|
||||
binaryInterval: 300,
|
||||
alwaysStat: false,
|
||||
depth: 99,
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 2000,
|
||||
pollInterval: 100
|
||||
},
|
||||
|
||||
ignorePermissionErrors: false,
|
||||
atomic: true
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
`chokidar.watch(paths, options)` — takes one or more paths (which may be paths
|
||||
to files, dirs to be watched recursively, or glob patterns) and options:
|
||||
|
||||
#### Persistence
|
||||
|
||||
* `persistent` (default: `true`). Indicates whether the process
|
||||
should continue to run as long as files are being watched. If set to
|
||||
`false` when using `fsevents` to watch, no more events will be emitted
|
||||
after `ready`, even if the process continues to run.
|
||||
|
||||
#### Path filtering
|
||||
|
||||
* `ignored` ([anymatch](https://github.com/es128/anymatch)-compatible definition)
|
||||
Defines files/paths to be ignored. The whole relative or absolute path is
|
||||
tested, not just filename. If a function with two arguments is provided, it
|
||||
gets called twice per path - once with a single argument (the path), second
|
||||
time with two arguments (the path and the
|
||||
[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||||
object of that path).
|
||||
* `ignoreInitial` (default: `false`). Indicates whether chokidar
|
||||
should ignore the initial `add` events or not.
|
||||
* `followSymlinks` (default: `true`). When `false`, only the
|
||||
symlinks themselves will be watched for changes instead of following
|
||||
the link references and bubbling events through the link's path.
|
||||
* `cwd` (no default). The base directory from which watch `paths` are to be
|
||||
derived. Paths emitted with events will be relative to this.
|
||||
|
||||
#### Performance
|
||||
|
||||
* `usePolling` (default: `false`).
|
||||
Whether to use fs.watchFile (backed by polling), or fs.watch. If polling
|
||||
leads to high CPU utilization, consider setting this to `false`. It is
|
||||
typically necessary to **set this to `true` to successfully watch files over
|
||||
a network**, and it may be necessary to successfully watch files in other
|
||||
non-standard situations. Setting to `true` explicitly on OS X overrides the
|
||||
`useFsEvents` default.
|
||||
* _Polling-specific settings_ (effective when `usePolling: true`)
|
||||
* `interval` (default: `100`). Interval of file system polling.
|
||||
* `binaryInterval` (default: `300`). Interval of file system
|
||||
polling for binary files.
|
||||
([see list of binary extensions](https://github.com/sindresorhus/binary-extensions/blob/master/binary-extensions.json))
|
||||
* `useFsEvents` (default: `true` on OS X). Whether to use the
|
||||
`fsevents` watching interface if available. When set to `true` explicitly
|
||||
and `fsevents` is available this supercedes the `usePolling` setting. When
|
||||
set to `false` on OS X, `usePolling: true` becomes the default.
|
||||
* `alwaysStat` (default: `false`). If relying upon the
|
||||
[`fs.Stats`](http://nodejs.org/api/fs.html#fs_class_fs_stats)
|
||||
object that may get passed with `add`, `addDir`, and `change` events, set
|
||||
this to `true` to ensure it is provided even in cases where it wasn't
|
||||
already available from the underlying watch events.
|
||||
* `depth` (default: `undefined`). If set, limits how many levels of
|
||||
subdirectories will be traversed.
|
||||
* `awaitWriteFinish` (default: `false`).
|
||||
By default, the `add` event will fire when a file first appear on disk, before
|
||||
the entire file has been written. Furthermore, in some cases some `change`
|
||||
events will be emitted while the file is being written.
|
||||
In some cases, especially when watching for large files there will be a need to
|
||||
wait for the write operation to finish before responding to the file creation.
|
||||
Setting `awaitWriteFinish` to `true` (or a truthy value) will poll a newly
|
||||
created file size, holding its `add` and `change` events until the size does not
|
||||
change for a configurable amount of time. The appropriate duration setting is
|
||||
heavily dependent on the OS and hardware. For accurate detection this parameter
|
||||
should be relatively high, making file watching much less responsive.
|
||||
Use with caution.
|
||||
* *`options.awaitWriteFinish` can be set to an object in order to adjust
|
||||
timing params:*
|
||||
* `awaitWriteFinish.stabilityThreshold` (default: 2000). Amount of time in
|
||||
milliseconds for a file size to remain constant before emitting its event.
|
||||
* `awaitWriteFinish.pollInterval` (default: 100). File size polling interval.
|
||||
|
||||
#### Errors
|
||||
* `ignorePermissionErrors` (default: `false`). Indicates whether to watch files
|
||||
that don't have read permissions if possible. If watching fails due to `EPERM`
|
||||
or `EACCES` with this set to `true`, the errors will be suppressed silently.
|
||||
* `atomic` (default: `true` if `useFsEvents` and `usePolling` are `false`).
|
||||
Automatically filters out artifacts that occur when using editors that use
|
||||
"atomic writes" instead of writing directly to the source file.
|
||||
|
||||
### Methods & Events
|
||||
|
||||
`chokidar.watch()` produces an instance of `FSWatcher`. Methods of `FSWatcher`:
|
||||
|
||||
* `.add(path / paths)`: Add files, directories, or glob patterns for tracking.
|
||||
Takes an array of strings or just one string.
|
||||
* `.on(event, callback)`: Listen for an FS event.
|
||||
Available events: `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `ready`,
|
||||
`raw`, `error`.
|
||||
Additionally `all` is available which gets emitted with the underlying event
|
||||
name and path for every event other than `ready`, `raw`, and `error`.
|
||||
* `.unwatch(path / paths)`: Stop watching files, directories, or glob patterns.
|
||||
Takes an array of strings or just one string.
|
||||
* `.close()`: Removes all listeners from watched files.
|
||||
|
||||
## CLI
|
||||
|
||||
If you need a CLI interface for your file watching, check out
|
||||
[chokidar-cli](https://github.com/kimmobrunfeldt/chokidar-cli), allowing you to
|
||||
execute a command on each change, or get a stdio stream of change events.
|
||||
|
||||
## Install Troubleshooting
|
||||
|
||||
* `npm WARN optional dep failed, continuing fsevents@n.n.n`
|
||||
* This message is normal part of how `npm` handles optional dependencies and is
|
||||
not indicative of a problem. Even if accompanied by other related error messages,
|
||||
Chokidar should function properly.
|
||||
|
||||
* `ERR! stack Error: Python executable "python" is v3.4.1, which is not supported by gyp.`
|
||||
* You should be able to resolve this by installing python 2.7 and running:
|
||||
`npm config set python python2.7`
|
||||
|
||||
* `gyp ERR! stack Error: not found: make`
|
||||
* On Mac, install the XCode command-line tools
|
||||
|
||||
## License
|
||||
The MIT license.
|
||||
|
||||
Copyright (c) 2012 - 2015 Paul Miller (http://paulmillr.com) & Elan Shanker
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
603
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/index.js
generated
vendored
Executable file
603
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/index.js
generated
vendored
Executable file
@@ -0,0 +1,603 @@
|
||||
'use strict';
|
||||
var EventEmitter = require('events').EventEmitter;
|
||||
var fs = require('fs');
|
||||
var sysPath = require('path');
|
||||
var each = require('async-each');
|
||||
var anymatch = require('anymatch');
|
||||
var globparent = require('glob-parent');
|
||||
var isglob = require('is-glob');
|
||||
var arrify = require('arrify');
|
||||
var isAbsolute = require('path-is-absolute');
|
||||
var flatten = require('lodash.flatten');
|
||||
|
||||
var NodeFsHandler = require('./lib/nodefs-handler');
|
||||
var FsEventsHandler = require('./lib/fsevents-handler');
|
||||
|
||||
// Public: Main class.
|
||||
// Watches files & directories for changes.
|
||||
//
|
||||
// * _opts - object, chokidar options hash
|
||||
//
|
||||
// Emitted events:
|
||||
// `add`, `addDir`, `change`, `unlink`, `unlinkDir`, `all`, `error`
|
||||
//
|
||||
// Examples
|
||||
//
|
||||
// var watcher = new FSWatcher()
|
||||
// .add(directories)
|
||||
// .on('add', function(path) {console.log('File', path, 'was added');})
|
||||
// .on('change', function(path) {console.log('File', path, 'was changed');})
|
||||
// .on('unlink', function(path) {console.log('File', path, 'was removed');})
|
||||
// .on('all', function(event, path) {console.log(path, ' emitted ', event);})
|
||||
//
|
||||
function FSWatcher(_opts) {
|
||||
var opts = {};
|
||||
// in case _opts that is passed in is a frozen object
|
||||
if (_opts) for (var opt in _opts) opts[opt] = _opts[opt];
|
||||
this._watched = Object.create(null);
|
||||
this._closers = Object.create(null);
|
||||
this._ignoredPaths = Object.create(null);
|
||||
Object.defineProperty(this, '_globIgnored', {
|
||||
get: function() { return Object.keys(this._ignoredPaths); }
|
||||
});
|
||||
this.closed = false;
|
||||
this._throttled = Object.create(null);
|
||||
this._symlinkPaths = Object.create(null);
|
||||
|
||||
function undef(key) {
|
||||
return opts[key] === undefined;
|
||||
}
|
||||
|
||||
// Set up default options.
|
||||
if (undef('persistent')) opts.persistent = true;
|
||||
if (undef('ignoreInitial')) opts.ignoreInitial = false;
|
||||
if (undef('ignorePermissionErrors')) opts.ignorePermissionErrors = false;
|
||||
if (undef('interval')) opts.interval = 100;
|
||||
if (undef('binaryInterval')) opts.binaryInterval = 300;
|
||||
this.enableBinaryInterval = opts.binaryInterval !== opts.interval;
|
||||
|
||||
// Enable fsevents on OS X when polling isn't explicitly enabled.
|
||||
if (undef('useFsEvents')) opts.useFsEvents = !opts.usePolling;
|
||||
|
||||
// If we can't use fsevents, ensure the options reflect it's disabled.
|
||||
if (!FsEventsHandler.canUse()) opts.useFsEvents = false;
|
||||
|
||||
// Use polling on Mac if not using fsevents.
|
||||
// Other platforms use non-polling fs.watch.
|
||||
if (undef('usePolling') && !opts.useFsEvents) {
|
||||
opts.usePolling = process.platform === 'darwin';
|
||||
}
|
||||
|
||||
// Editor atomic write normalization enabled by default with fs.watch
|
||||
if (undef('atomic')) opts.atomic = !opts.usePolling && !opts.useFsEvents;
|
||||
if (opts.atomic) this._pendingUnlinks = Object.create(null);
|
||||
|
||||
if (undef('followSymlinks')) opts.followSymlinks = true;
|
||||
|
||||
if (undef('awaitWriteFinish')) opts.awaitWriteFinish = false;
|
||||
if (opts.awaitWriteFinish === true) opts.awaitWriteFinish = {};
|
||||
var awf = opts.awaitWriteFinish;
|
||||
if (awf) {
|
||||
if (!awf.stabilityThreshold) awf.stabilityThreshold = 2000;
|
||||
if (!awf.pollInterval) awf.pollInterval = 100;
|
||||
|
||||
this._pendingWrites = Object.create(null);
|
||||
}
|
||||
|
||||
this._isntIgnored = function(path, stat) {
|
||||
return !this._isIgnored(path, stat);
|
||||
}.bind(this);
|
||||
|
||||
var readyCalls = 0;
|
||||
this._emitReady = function() {
|
||||
if (++readyCalls >= this._readyCount) {
|
||||
this._emitReady = Function.prototype;
|
||||
// use process.nextTick to allow time for listener to be bound
|
||||
process.nextTick(this.emit.bind(this, 'ready'));
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
this.options = opts;
|
||||
|
||||
// You’re frozen when your heart’s not open.
|
||||
Object.freeze(opts);
|
||||
}
|
||||
|
||||
FSWatcher.prototype = Object.create(EventEmitter.prototype);
|
||||
|
||||
// Common helpers
|
||||
// --------------
|
||||
|
||||
// Private method: Normalize and emit events
|
||||
//
|
||||
// * event - string, type of event
|
||||
// * path - string, file or directory path
|
||||
// * val[1..3] - arguments to be passed with event
|
||||
//
|
||||
// Returns the error if defined, otherwise the value of the
|
||||
// FSWatcher instance's `closed` flag
|
||||
FSWatcher.prototype._emit = function(event, path, val1, val2, val3) {
|
||||
if (this.options.cwd) path = sysPath.relative(this.options.cwd, path);
|
||||
var args = [event, path];
|
||||
if (val3 !== undefined) args.push(val1, val2, val3);
|
||||
else if (val2 !== undefined) args.push(val1, val2);
|
||||
else if (val1 !== undefined) args.push(val1);
|
||||
|
||||
var awf = this.options.awaitWriteFinish;
|
||||
if (awf && this._pendingWrites[path]) return this;
|
||||
|
||||
if (this.options.atomic) {
|
||||
if (event === 'unlink') {
|
||||
this._pendingUnlinks[path] = args;
|
||||
setTimeout(function() {
|
||||
Object.keys(this._pendingUnlinks).forEach(function(path) {
|
||||
this.emit.apply(this, this._pendingUnlinks[path]);
|
||||
this.emit.apply(this, ['all'].concat(this._pendingUnlinks[path]));
|
||||
delete this._pendingUnlinks[path];
|
||||
}.bind(this));
|
||||
}.bind(this), 100);
|
||||
return this;
|
||||
} else if (event === 'add' && this._pendingUnlinks[path]) {
|
||||
event = args[0] = 'change';
|
||||
delete this._pendingUnlinks[path];
|
||||
}
|
||||
}
|
||||
|
||||
if (event === 'change') {
|
||||
if (!this._throttle('change', path, 50)) return this;
|
||||
}
|
||||
|
||||
var emitEvent = function() {
|
||||
this.emit.apply(this, args);
|
||||
if (event !== 'error') this.emit.apply(this, ['all'].concat(args));
|
||||
}.bind(this);
|
||||
|
||||
if (awf && event === 'add') {
|
||||
this._awaitWriteFinish(path, awf.stabilityThreshold, function(err, stats) {
|
||||
if (err) {
|
||||
event = args[0] = 'error';
|
||||
args[1] = err;
|
||||
emitEvent();
|
||||
} else if (stats) {
|
||||
// if stats doesn't exist the file must have been deleted
|
||||
args.push(stats);
|
||||
emitEvent();
|
||||
}
|
||||
});
|
||||
} else if (
|
||||
this.options.alwaysStat && val1 === undefined &&
|
||||
(event === 'add' || event === 'addDir' || event === 'change')
|
||||
) {
|
||||
fs.stat(path, function(error, stats) {
|
||||
// Suppress event when fs.stat fails, to avoid sending undefined 'stat'
|
||||
if (error || !stats) return;
|
||||
|
||||
args.push(stats);
|
||||
emitEvent();
|
||||
});
|
||||
} else {
|
||||
emitEvent();
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Private method: Common handler for errors
|
||||
//
|
||||
// * error - object, Error instance
|
||||
//
|
||||
// Returns the error if defined, otherwise the value of the
|
||||
// FSWatcher instance's `closed` flag
|
||||
FSWatcher.prototype._handleError = function(error) {
|
||||
var code = error && error.code;
|
||||
var ipe = this.options.ignorePermissionErrors;
|
||||
if (error &&
|
||||
code !== 'ENOENT' &&
|
||||
code !== 'ENOTDIR' &&
|
||||
(!ipe || (code !== 'EPERM' && code !== 'EACCES'))
|
||||
) this.emit('error', error);
|
||||
return error || this.closed;
|
||||
};
|
||||
|
||||
// Private method: Helper utility for throttling
|
||||
//
|
||||
// * action - string, type of action being throttled
|
||||
// * path - string, path being acted upon
|
||||
// * timeout - int, duration of time to suppress duplicate actions
|
||||
//
|
||||
// Returns throttle tracking object or false if action should be suppressed
|
||||
FSWatcher.prototype._throttle = function(action, path, timeout) {
|
||||
if (!(action in this._throttled)) {
|
||||
this._throttled[action] = Object.create(null);
|
||||
}
|
||||
var throttled = this._throttled[action];
|
||||
if (path in throttled) return false;
|
||||
function clear() {
|
||||
delete throttled[path];
|
||||
clearTimeout(timeoutObject);
|
||||
}
|
||||
var timeoutObject = setTimeout(clear, timeout);
|
||||
throttled[path] = {timeoutObject: timeoutObject, clear: clear};
|
||||
return throttled[path];
|
||||
};
|
||||
|
||||
// Private method: Awaits write operation to finish
|
||||
//
|
||||
// * path - string, path being acted upon
|
||||
// * threshold - int, time in milliseconds a file size must be fixed before
|
||||
// acknowledgeing write operation is finished
|
||||
// * callback - function, callback to call when write operation is finished
|
||||
// Polls a newly created file for size variations. When files size does not
|
||||
// change for 'threshold' milliseconds calls callback.
|
||||
FSWatcher.prototype._awaitWriteFinish = function(path, threshold, callback) {
|
||||
var timeoutHandler;
|
||||
|
||||
(function awaitWriteFinish (prevStat) {
|
||||
fs.stat(path, function(err, curStat) {
|
||||
if (err) {
|
||||
// if the file have been erased, the file entry in _pendingWrites will
|
||||
// be deleted in the unlink event.
|
||||
if (err.code == 'ENOENT') return;
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
var now = new Date();
|
||||
if (this._pendingWrites[path] === undefined) {
|
||||
this._pendingWrites[path] = {
|
||||
creationTime: now,
|
||||
cancelWait: function() {
|
||||
delete this._pendingWrites[path];
|
||||
clearTimeout(timeoutHandler);
|
||||
return callback();
|
||||
}.bind(this)
|
||||
}
|
||||
return timeoutHandler = setTimeout(
|
||||
awaitWriteFinish.bind(this, curStat),
|
||||
this.options.awaitWriteFinish.pollInterval
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
curStat.size == prevStat.size &&
|
||||
now - this._pendingWrites[path].creationTime > threshold
|
||||
) {
|
||||
delete this._pendingWrites[path];
|
||||
callback(null, curStat);
|
||||
} else {
|
||||
return timeoutHandler = setTimeout(
|
||||
awaitWriteFinish.bind(this, curStat),
|
||||
this.options.awaitWriteFinish.pollInterval
|
||||
);
|
||||
}
|
||||
}.bind(this));
|
||||
}.bind(this))();
|
||||
}
|
||||
|
||||
// Private method: Determines whether user has asked to ignore this path
|
||||
//
|
||||
// * path - string, path to file or directory
|
||||
// * stats - object, result of fs.stat
|
||||
//
|
||||
// Returns boolean
|
||||
FSWatcher.prototype._isIgnored = function(path, stats) {
|
||||
if (
|
||||
this.options.atomic &&
|
||||
/\..*\.(sw[px])$|\~$|\.subl.*\.tmp/.test(path)
|
||||
) return true;
|
||||
|
||||
if (!this._userIgnored) {
|
||||
var cwd = this.options.cwd;
|
||||
var ignored = this.options.ignored;
|
||||
if (cwd && ignored) {
|
||||
ignored = arrify(ignored).map(function (path) {
|
||||
if (typeof path !== 'string') return path;
|
||||
return isAbsolute(path) ? path : sysPath.join(cwd, path);
|
||||
});
|
||||
}
|
||||
this._userIgnored = anymatch(this._globIgnored
|
||||
.concat(ignored)
|
||||
.concat(arrify(ignored)
|
||||
.filter(function(path) {
|
||||
return typeof path === 'string' && !isglob(path);
|
||||
}).map(function(path) {
|
||||
return path + '/**/*';
|
||||
})
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return this._userIgnored([path, stats]);
|
||||
};
|
||||
|
||||
// Private method: Provides a set of common helpers and properties relating to
|
||||
// symlink and glob handling
|
||||
//
|
||||
// * path - string, file, directory, or glob pattern being watched
|
||||
// * depth - int, at any depth > 0, this isn't a glob
|
||||
//
|
||||
// Returns object containing helpers for this path
|
||||
FSWatcher.prototype._getWatchHelpers = function(path, depth) {
|
||||
path = path.replace(/^\.[\/\\]/, '');
|
||||
var watchPath = depth || !isglob(path) ? path : globparent(path);
|
||||
var hasGlob = watchPath !== path;
|
||||
var globFilter = hasGlob ? anymatch(path) : false;
|
||||
|
||||
var entryPath = function(entry) {
|
||||
return sysPath.join(watchPath, sysPath.relative(watchPath, entry.fullPath));
|
||||
}
|
||||
|
||||
var filterPath = function(entry) {
|
||||
return (!hasGlob || globFilter(entryPath(entry))) &&
|
||||
this._isntIgnored(entryPath(entry), entry.stat) &&
|
||||
(this.options.ignorePermissionErrors ||
|
||||
this._hasReadPermissions(entry.stat));
|
||||
}.bind(this);
|
||||
|
||||
var getDirParts = function(path) {
|
||||
if (!hasGlob) return false;
|
||||
var parts = sysPath.relative(watchPath, path).split(/[\/\\]/);
|
||||
return parts;
|
||||
}
|
||||
var dirParts = getDirParts(path);
|
||||
if (dirParts && dirParts.length > 1) dirParts.pop();
|
||||
|
||||
var filterDir = function(entry) {
|
||||
if (hasGlob) {
|
||||
var entryParts = getDirParts(entry.fullPath);
|
||||
var globstar = false;
|
||||
var unmatchedGlob = !dirParts.every(function(part, i) {
|
||||
if (part === '**') globstar = true;
|
||||
return globstar || !entryParts[i] || anymatch(part, entryParts[i]);
|
||||
});
|
||||
}
|
||||
return !unmatchedGlob && this._isntIgnored(entryPath(entry), entry.stat);
|
||||
}.bind(this);
|
||||
|
||||
return {
|
||||
followSymlinks: this.options.followSymlinks,
|
||||
statMethod: this.options.followSymlinks ? 'stat' : 'lstat',
|
||||
path: path,
|
||||
watchPath: watchPath,
|
||||
entryPath: entryPath,
|
||||
hasGlob: hasGlob,
|
||||
globFilter: globFilter,
|
||||
filterPath: filterPath,
|
||||
filterDir: filterDir
|
||||
};
|
||||
}
|
||||
|
||||
// Directory helpers
|
||||
// -----------------
|
||||
|
||||
// Private method: Provides directory tracking objects
|
||||
//
|
||||
// * directory - string, path of the directory
|
||||
//
|
||||
// Returns the directory's tracking object
|
||||
FSWatcher.prototype._getWatchedDir = function(directory) {
|
||||
var dir = sysPath.resolve(directory);
|
||||
var watcherRemove = this._remove.bind(this);
|
||||
if (!(dir in this._watched)) this._watched[dir] = {
|
||||
_items: Object.create(null),
|
||||
add: function(item) {this._items[item] = true;},
|
||||
remove: function(item) {
|
||||
delete this._items[item];
|
||||
if (!this.children().length) {
|
||||
fs.readdir(dir, function(err) {
|
||||
if (err) watcherRemove(sysPath.dirname(dir), sysPath.basename(dir));
|
||||
});
|
||||
}
|
||||
},
|
||||
has: function(item) {return item in this._items;},
|
||||
children: function() {return Object.keys(this._items);}
|
||||
};
|
||||
return this._watched[dir];
|
||||
};
|
||||
|
||||
// File helpers
|
||||
// ------------
|
||||
|
||||
// Private method: Check for read permissions
|
||||
// Based on this answer on SO: http://stackoverflow.com/a/11781404/1358405
|
||||
//
|
||||
// * stats - object, result of fs.stat
|
||||
//
|
||||
// Returns boolean
|
||||
FSWatcher.prototype._hasReadPermissions = function(stats) {
|
||||
return Boolean(4 & parseInt(((stats && stats.mode) & 0x1ff).toString(8)[0], 10));
|
||||
};
|
||||
|
||||
// Private method: Handles emitting unlink events for
|
||||
// files and directories, and via recursion, for
|
||||
// files and directories within directories that are unlinked
|
||||
//
|
||||
// * directory - string, directory within which the following item is located
|
||||
// * item - string, base path of item/directory
|
||||
//
|
||||
// Returns nothing
|
||||
FSWatcher.prototype._remove = function(directory, item) {
|
||||
// if what is being deleted is a directory, get that directory's paths
|
||||
// for recursive deleting and cleaning of watched object
|
||||
// if it is not a directory, nestedDirectoryChildren will be empty array
|
||||
var path = sysPath.join(directory, item);
|
||||
var fullPath = sysPath.resolve(path);
|
||||
var isDirectory = this._watched[path] || this._watched[fullPath];
|
||||
|
||||
// prevent duplicate handling in case of arriving here nearly simultaneously
|
||||
// via multiple paths (such as _handleFile and _handleDir)
|
||||
if (!this._throttle('remove', path, 100)) return;
|
||||
|
||||
// if the only watched file is removed, watch for its return
|
||||
var watchedDirs = Object.keys(this._watched);
|
||||
if (!isDirectory && !this.options.useFsEvents && watchedDirs.length === 1) {
|
||||
this.add(directory, item, true);
|
||||
}
|
||||
|
||||
// This will create a new entry in the watched object in either case
|
||||
// so we got to do the directory check beforehand
|
||||
var nestedDirectoryChildren = this._getWatchedDir(path).children();
|
||||
|
||||
// Recursively remove children directories / files.
|
||||
nestedDirectoryChildren.forEach(function(nestedItem) {
|
||||
this._remove(path, nestedItem);
|
||||
}, this);
|
||||
|
||||
// Check if item was on the watched list and remove it
|
||||
var parent = this._getWatchedDir(directory);
|
||||
var wasTracked = parent.has(item);
|
||||
parent.remove(item);
|
||||
|
||||
// If we wait for this file to be fully written, cancel the wait.
|
||||
if (this.options.awaitWriteFinish && this._pendingWrites[path]) {
|
||||
this._pendingWrites[path].cancelWait();
|
||||
return;
|
||||
}
|
||||
|
||||
// The Entry will either be a directory that just got removed
|
||||
// or a bogus entry to a file, in either case we have to remove it
|
||||
delete this._watched[path];
|
||||
delete this._watched[fullPath];
|
||||
var eventName = isDirectory ? 'unlinkDir' : 'unlink';
|
||||
if (wasTracked && !this._isIgnored(path)) this._emit(eventName, path);
|
||||
};
|
||||
|
||||
// Public method: Adds paths to be watched on an existing FSWatcher instance
|
||||
|
||||
// * paths - string or array of strings, file/directory paths and/or globs
|
||||
// * _origAdd - private boolean, for handling non-existent paths to be watched
|
||||
// * _internal - private boolean, indicates a non-user add
|
||||
|
||||
// Returns an instance of FSWatcher for chaining.
|
||||
FSWatcher.prototype.add = function(paths, _origAdd, _internal) {
|
||||
var cwd = this.options.cwd;
|
||||
this.closed = false;
|
||||
paths = flatten(arrify(paths));
|
||||
|
||||
if (!paths.every(isString)) {
|
||||
throw new TypeError('Non-string provided as watch path');
|
||||
}
|
||||
|
||||
if (cwd) paths = paths.map(function(path) {
|
||||
if (isAbsolute(path)) {
|
||||
return path;
|
||||
} else if (path[0] === '!') {
|
||||
return '!' + sysPath.join(cwd, path.substring(1));
|
||||
} else {
|
||||
return sysPath.join(cwd, path);
|
||||
}
|
||||
});
|
||||
|
||||
// set aside negated glob strings
|
||||
paths = paths.filter(function(path) {
|
||||
if (path[0] === '!') this._ignoredPaths[path.substring(1)] = true;
|
||||
else {
|
||||
// if a path is being added that was previously ignored, stop ignoring it
|
||||
delete this._ignoredPaths[path];
|
||||
delete this._ignoredPaths[path + '/**/*'];
|
||||
|
||||
// reset the cached userIgnored anymatch fn
|
||||
// to make ignoredPaths changes effective
|
||||
this._userIgnored = null;
|
||||
|
||||
return true;
|
||||
}
|
||||
}, this);
|
||||
|
||||
if (this.options.useFsEvents && FsEventsHandler.canUse()) {
|
||||
if (!this._readyCount) this._readyCount = paths.length;
|
||||
if (this.options.persistent) this._readyCount *= 2;
|
||||
paths.forEach(this._addToFsEvents, this);
|
||||
} else {
|
||||
if (!this._readyCount) this._readyCount = 0;
|
||||
this._readyCount += paths.length;
|
||||
each(paths, function(path, next) {
|
||||
this._addToNodeFs(path, !_internal, 0, 0, _origAdd, function(err, res) {
|
||||
if (res) this._emitReady();
|
||||
next(err, res);
|
||||
}.bind(this));
|
||||
}.bind(this), function(error, results) {
|
||||
results.forEach(function(item) {
|
||||
if (!item) return;
|
||||
this.add(sysPath.dirname(item), sysPath.basename(_origAdd || item));
|
||||
}, this);
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Public method: Close watchers or start ignoring events from specified paths.
|
||||
|
||||
// * paths - string or array of strings, file/directory paths and/or globs
|
||||
|
||||
// Returns instance of FSWatcher for chaining.
|
||||
FSWatcher.prototype.unwatch = function(paths) {
|
||||
if (this.closed) return this;
|
||||
paths = flatten(arrify(paths));
|
||||
|
||||
paths.forEach(function(path) {
|
||||
if (this._closers[path]) {
|
||||
this._closers[path]();
|
||||
delete this._closers[path];
|
||||
this._getWatchedDir(sysPath.dirname(path)).remove(sysPath.basename(path));
|
||||
} else {
|
||||
//convert to absolute path
|
||||
path = sysPath.resolve(path);
|
||||
|
||||
this._ignoredPaths[path] = true;
|
||||
if (path in this._watched) {
|
||||
this._ignoredPaths[path + '/**/*'] = true;
|
||||
}
|
||||
|
||||
// reset the cached userIgnored anymatch fn
|
||||
// to make ignoredPaths changes effective
|
||||
this._userIgnored = null;
|
||||
}
|
||||
}, this);
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
// Public method: Close watchers and remove all listeners from watched paths.
|
||||
|
||||
// Returns instance of FSWatcher for chaining.
|
||||
FSWatcher.prototype.close = function() {
|
||||
if (this.closed) return this;
|
||||
|
||||
this.closed = true;
|
||||
Object.keys(this._closers).forEach(function(watchPath) {
|
||||
this._closers[watchPath]();
|
||||
delete this._closers[watchPath];
|
||||
}, this);
|
||||
this._watched = Object.create(null);
|
||||
|
||||
this.removeAllListeners();
|
||||
return this;
|
||||
};
|
||||
|
||||
// Attach watch handler prototype methods
|
||||
function importHandler(handler) {
|
||||
Object.keys(handler.prototype).forEach(function(method) {
|
||||
FSWatcher.prototype[method] = handler.prototype[method];
|
||||
});
|
||||
}
|
||||
importHandler(NodeFsHandler);
|
||||
if (FsEventsHandler.canUse()) importHandler(FsEventsHandler);
|
||||
|
||||
// little isString util for use in Array.prototype.every
|
||||
function isString(maybeString) {
|
||||
return typeof maybeString === 'string'
|
||||
}
|
||||
|
||||
// Export FSWatcher class
|
||||
exports.FSWatcher = FSWatcher;
|
||||
|
||||
// Public function: Instantiates watcher with paths to be tracked.
|
||||
|
||||
// * paths - string or array of strings, file/directory paths and/or globs
|
||||
// * options - object, chokidar options
|
||||
|
||||
// Returns an instance of FSWatcher for chaining.
|
||||
exports.watch = function(paths, options) {
|
||||
return new FSWatcher(options).add(paths);
|
||||
};
|
||||
361
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/lib/fsevents-handler.js
generated
vendored
Normal file
361
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/lib/fsevents-handler.js
generated
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var sysPath = require('path');
|
||||
var readdirp = require('readdirp');
|
||||
var fsevents;
|
||||
try { fsevents = require('fsevents'); } catch (error) {}
|
||||
|
||||
// fsevents instance helper functions
|
||||
|
||||
// object to hold per-process fsevents instances
|
||||
// (may be shared across chokidar FSWatcher instances)
|
||||
var FSEventsWatchers = Object.create(null);
|
||||
|
||||
// Private function: Instantiates the fsevents interface
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * callback - function, called when fsevents is bound and ready
|
||||
|
||||
// Returns new fsevents instance
|
||||
function createFSEventsInstance(path, callback) {
|
||||
return (new fsevents(path)).on('fsevent', callback).start();
|
||||
}
|
||||
|
||||
// Private function: Instantiates the fsevents interface or binds listeners
|
||||
// to an existing one covering the same file tree
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * realPath - string, real path (in case of symlinks)
|
||||
// * listener - function, called when fsevents emits events
|
||||
// * rawEmitter - function, passes data to listeners of the 'raw' event
|
||||
|
||||
// Returns close function
|
||||
function setFSEventsListener(path, realPath, listener, rawEmitter) {
|
||||
var watchPath = sysPath.extname(path) ? sysPath.dirname(path) : path;
|
||||
var watchContainer;
|
||||
|
||||
var resolvedPath = sysPath.resolve(path);
|
||||
var hasSymlink = resolvedPath !== realPath;
|
||||
function filteredListener(fullPath, flags, info) {
|
||||
if (hasSymlink) fullPath = fullPath.replace(realPath, resolvedPath);
|
||||
if (
|
||||
fullPath === resolvedPath ||
|
||||
!fullPath.indexOf(resolvedPath + sysPath.sep)
|
||||
) listener(fullPath, flags, info);
|
||||
}
|
||||
|
||||
// check if there is already a watcher on a parent path
|
||||
// modifies `watchPath` to the parent path when it finds a match
|
||||
function watchedParent() {
|
||||
return Object.keys(FSEventsWatchers).some(function(watchedPath) {
|
||||
// condition is met when indexOf returns 0
|
||||
if (!realPath.indexOf(sysPath.resolve(watchedPath) + sysPath.sep)) {
|
||||
watchPath = watchedPath;
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (watchPath in FSEventsWatchers || watchedParent()) {
|
||||
watchContainer = FSEventsWatchers[watchPath];
|
||||
watchContainer.listeners.push(filteredListener);
|
||||
} else {
|
||||
watchContainer = FSEventsWatchers[watchPath] = {
|
||||
listeners: [filteredListener],
|
||||
rawEmitters: [rawEmitter],
|
||||
watcher: createFSEventsInstance(watchPath, function(fullPath, flags) {
|
||||
var info = fsevents.getInfo(fullPath, flags);
|
||||
watchContainer.listeners.forEach(function(listener) {
|
||||
listener(fullPath, flags, info);
|
||||
});
|
||||
watchContainer.rawEmitters.forEach(function(emitter) {
|
||||
emitter(info.event, fullPath, info);
|
||||
});
|
||||
})
|
||||
};
|
||||
}
|
||||
var listenerIndex = watchContainer.listeners.length - 1;
|
||||
|
||||
// removes this instance's listeners and closes the underlying fsevents
|
||||
// instance if there are no more listeners left
|
||||
return function close() {
|
||||
delete watchContainer.listeners[listenerIndex];
|
||||
delete watchContainer.rawEmitters[listenerIndex];
|
||||
if (!Object.keys(watchContainer.listeners).length) {
|
||||
watchContainer.watcher.stop();
|
||||
delete FSEventsWatchers[watchPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// returns boolean indicating whether fsevents can be used
|
||||
function canUse() {
|
||||
return fsevents && Object.keys(FSEventsWatchers).length < 128;
|
||||
}
|
||||
|
||||
// determines subdirectory traversal levels from root to path
|
||||
function depth(path, root) {
|
||||
var i = 0;
|
||||
while (!path.indexOf(root) && (path = sysPath.dirname(path)) !== root) i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
// fake constructor for attaching fsevents-specific prototype methods that
|
||||
// will be copied to FSWatcher's prototype
|
||||
function FsEventsHandler() {}
|
||||
|
||||
// Private method: Handle symlinks encountered during directory scan
|
||||
|
||||
// * wathPath - string, file/dir path to be watched with fsevents
|
||||
// * realPath - string, real path (in case of symlinks)
|
||||
// * transform - function, path transformer
|
||||
// * globFilter - function, path filter in case a glob pattern was provided
|
||||
|
||||
// Returns close function for the watcher instance
|
||||
FsEventsHandler.prototype._watchWithFsEvents =
|
||||
function(watchPath, realPath, transform, globFilter) {
|
||||
if (this._isIgnored(watchPath)) return;
|
||||
var watchCallback = function(fullPath, flags, info) {
|
||||
if (
|
||||
this.options.depth !== undefined &&
|
||||
depth(fullPath, realPath) > this.options.depth
|
||||
) return;
|
||||
var path = transform(sysPath.join(
|
||||
watchPath, sysPath.relative(watchPath, fullPath)
|
||||
));
|
||||
if (globFilter && !globFilter(path)) return;
|
||||
// ensure directories are tracked
|
||||
var parent = sysPath.dirname(path);
|
||||
var item = sysPath.basename(path);
|
||||
var watchedDir = this._getWatchedDir(
|
||||
info.type === 'directory' ? path : parent
|
||||
);
|
||||
var checkIgnored = function(stats) {
|
||||
if (this._isIgnored(path, stats)) {
|
||||
this._ignoredPaths[path] = true;
|
||||
if (stats && stats.isDirectory()) {
|
||||
this._ignoredPaths[path + '/**/*'] = true;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
delete this._ignoredPaths[path];
|
||||
delete this._ignoredPaths[path + '/**/*'];
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
var handleEvent = function(event) {
|
||||
if (checkIgnored()) return;
|
||||
|
||||
if (event === 'unlink') {
|
||||
// suppress unlink events on never before seen files
|
||||
if (info.type === 'directory' || watchedDir.has(item)) {
|
||||
this._remove(parent, item);
|
||||
}
|
||||
} else {
|
||||
if (event === 'add') {
|
||||
// track new directories
|
||||
if (info.type === 'directory') this._getWatchedDir(path);
|
||||
|
||||
if (info.type === 'symlink' && this.options.followSymlinks) {
|
||||
// push symlinks back to the top of the stack to get handled
|
||||
var curDepth = this.options.depth === undefined ?
|
||||
undefined : depth(fullPath, realPath) + 1;
|
||||
return this._addToFsEvents(path, false, true, curDepth);
|
||||
} else {
|
||||
// track new paths
|
||||
// (other than symlinks being followed, which will be tracked soon)
|
||||
this._getWatchedDir(parent).add(item);
|
||||
}
|
||||
}
|
||||
var eventName = info.type === 'directory' ? event + 'Dir' : event;
|
||||
this._emit(eventName, path);
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
function addOrChange() {
|
||||
handleEvent(watchedDir.has(item) ? 'change' : 'add');
|
||||
}
|
||||
function checkFd() {
|
||||
fs.open(path, 'r', function(error, fd) {
|
||||
if (fd) fs.close(fd);
|
||||
error && error.code !== 'EACCES' ?
|
||||
handleEvent('unlink') : addOrChange();
|
||||
});
|
||||
}
|
||||
// correct for wrong events emitted
|
||||
var wrongEventFlags = [
|
||||
69888, 70400, 71424, 72704, 73472, 131328, 131840, 262912
|
||||
];
|
||||
if (wrongEventFlags.indexOf(flags) !== -1 || info.event === 'unknown') {
|
||||
if (typeof this.options.ignored === 'function') {
|
||||
fs.stat(path, function(error, stats) {
|
||||
if (checkIgnored(stats)) return;
|
||||
stats ? addOrChange() : handleEvent('unlink');
|
||||
});
|
||||
} else {
|
||||
checkFd();
|
||||
}
|
||||
} else {
|
||||
switch (info.event) {
|
||||
case 'created':
|
||||
case 'modified':
|
||||
return addOrChange();
|
||||
case 'deleted':
|
||||
case 'moved':
|
||||
return checkFd();
|
||||
}
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
var closer = setFSEventsListener(
|
||||
watchPath,
|
||||
realPath,
|
||||
watchCallback,
|
||||
this.emit.bind(this, 'raw')
|
||||
);
|
||||
|
||||
this._emitReady();
|
||||
return closer;
|
||||
};
|
||||
|
||||
// Private method: Handle symlinks encountered during directory scan
|
||||
|
||||
// * linkPath - string, path to symlink
|
||||
// * fullPath - string, absolute path to the symlink
|
||||
// * transform - function, pre-existing path transformer
|
||||
// * curDepth - int, level of subdirectories traversed to where symlink is
|
||||
|
||||
// Returns nothing
|
||||
FsEventsHandler.prototype._fsEventsSymlink =
|
||||
function(linkPath, fullPath, transform, curDepth) {
|
||||
// don't follow the same symlink more than once
|
||||
if (this._symlinkPaths[fullPath]) return;
|
||||
else this._symlinkPaths[fullPath] = true;
|
||||
|
||||
this._readyCount++;
|
||||
|
||||
fs.realpath(linkPath, function(error, linkTarget) {
|
||||
if (this._handleError(error) || this._isIgnored(linkTarget)) {
|
||||
return this._emitReady();
|
||||
}
|
||||
|
||||
this._readyCount++;
|
||||
|
||||
// add the linkTarget for watching with a wrapper for transform
|
||||
// that causes emitted paths to incorporate the link's path
|
||||
this._addToFsEvents(linkTarget || linkPath, function(path) {
|
||||
var dotSlash = '.' + sysPath.sep;
|
||||
var aliasedPath = linkPath;
|
||||
if (linkTarget && linkTarget !== dotSlash) {
|
||||
aliasedPath = path.replace(linkTarget, linkPath);
|
||||
} else if (path !== dotSlash) {
|
||||
aliasedPath = sysPath.join(linkPath, path);
|
||||
}
|
||||
return transform(aliasedPath);
|
||||
}, false, curDepth);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
// Private method: Handle added path with fsevents
|
||||
|
||||
// * path - string, file/directory path or glob pattern
|
||||
// * transform - function, converts working path to what the user expects
|
||||
// * forceAdd - boolean, ensure add is emitted
|
||||
// * priorDepth - int, level of subdirectories already traversed
|
||||
|
||||
// Returns nothing
|
||||
FsEventsHandler.prototype._addToFsEvents =
|
||||
function(path, transform, forceAdd, priorDepth) {
|
||||
|
||||
// applies transform if provided, otherwise returns same value
|
||||
var processPath = typeof transform === 'function' ?
|
||||
transform : function(val) { return val; };
|
||||
|
||||
var emitAdd = function(newPath, stats) {
|
||||
var pp = processPath(newPath);
|
||||
var isDir = stats.isDirectory();
|
||||
var dirObj = this._getWatchedDir(sysPath.dirname(pp));
|
||||
var base = sysPath.basename(pp);
|
||||
|
||||
// ensure empty dirs get tracked
|
||||
if (isDir) this._getWatchedDir(pp);
|
||||
|
||||
if (dirObj.has(base)) return;
|
||||
dirObj.add(base);
|
||||
|
||||
if (!this.options.ignoreInitial || forceAdd === true) {
|
||||
this._emit(isDir ? 'addDir' : 'add', pp, stats);
|
||||
}
|
||||
}.bind(this);
|
||||
|
||||
var wh = this._getWatchHelpers(path);
|
||||
|
||||
// evaluate what is at the path we're being asked to watch
|
||||
fs[wh.statMethod](wh.watchPath, function(error, stats) {
|
||||
if (this._handleError(error) || this._isIgnored(wh.watchPath, stats)) {
|
||||
this._emitReady();
|
||||
return this._emitReady();
|
||||
}
|
||||
|
||||
if (stats.isDirectory()) {
|
||||
// emit addDir unless this is a glob parent
|
||||
if (!wh.globFilter) emitAdd(processPath(path), stats);
|
||||
|
||||
// don't recurse further if it would exceed depth setting
|
||||
if (priorDepth && priorDepth > this.options.depth) return;
|
||||
|
||||
// scan the contents of the dir
|
||||
readdirp({
|
||||
root: wh.watchPath,
|
||||
entryType: 'all',
|
||||
fileFilter: wh.filterPath,
|
||||
directoryFilter: wh.filterDir,
|
||||
lstat: true,
|
||||
depth: this.options.depth - (priorDepth || 0)
|
||||
}).on('data', function(entry) {
|
||||
// need to check filterPath on dirs b/c filterDir is less restrictive
|
||||
if (entry.stat.isDirectory() && !wh.filterPath(entry)) return;
|
||||
|
||||
var joinedPath = sysPath.join(wh.watchPath, entry.path);
|
||||
var fullPath = entry.fullPath;
|
||||
|
||||
if (wh.followSymlinks && entry.stat.isSymbolicLink()) {
|
||||
// preserve the current depth here since it can't be derived from
|
||||
// real paths past the symlink
|
||||
var curDepth = this.options.depth === undefined ?
|
||||
undefined : depth(joinedPath, sysPath.resolve(wh.watchPath)) + 1;
|
||||
|
||||
this._fsEventsSymlink(joinedPath, fullPath, processPath, curDepth);
|
||||
} else {
|
||||
emitAdd(joinedPath, entry.stat);
|
||||
}
|
||||
}.bind(this)).on('end', this._emitReady);
|
||||
} else {
|
||||
emitAdd(wh.watchPath, stats);
|
||||
this._emitReady();
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
if (this.options.persistent) {
|
||||
var initWatch = function(error, realPath) {
|
||||
var closer = this._watchWithFsEvents(
|
||||
wh.watchPath,
|
||||
sysPath.resolve(realPath || wh.watchPath),
|
||||
processPath,
|
||||
wh.globFilter
|
||||
);
|
||||
if (closer) this._closers[path] = closer;
|
||||
}.bind(this);
|
||||
|
||||
if (typeof transform === 'function') {
|
||||
// realpath has already been resolved
|
||||
initWatch();
|
||||
} else {
|
||||
fs.realpath(wh.watchPath, initWatch);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = FsEventsHandler;
|
||||
module.exports.canUse = canUse;
|
||||
476
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/lib/nodefs-handler.js
generated
vendored
Normal file
476
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/lib/nodefs-handler.js
generated
vendored
Normal file
@@ -0,0 +1,476 @@
|
||||
'use strict';
|
||||
|
||||
var fs = require('fs');
|
||||
var sysPath = require('path');
|
||||
var readdirp = require('readdirp');
|
||||
var isBinaryPath = require('is-binary-path');
|
||||
|
||||
// fs.watch helpers
|
||||
|
||||
// object to hold per-process fs.watch instances
|
||||
// (may be shared across chokidar FSWatcher instances)
|
||||
var FsWatchInstances = Object.create(null);
|
||||
|
||||
// Private function: Instantiates the fs.watch interface
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * options - object, options to be passed to fs.watch
|
||||
// * listener - function, main event handler
|
||||
// * errHandler - function, handler which emits info about errors
|
||||
// * emitRaw - function, handler which emits raw event data
|
||||
|
||||
// Returns new fsevents instance
|
||||
function createFsWatchInstance(path, options, listener, errHandler, emitRaw) {
|
||||
var handleEvent = function(rawEvent, evPath) {
|
||||
listener(path);
|
||||
emitRaw(rawEvent, evPath, {watchedPath: path});
|
||||
|
||||
// emit based on events occuring for files from a directory's watcher in
|
||||
// case the file's watcher misses it (and rely on throttling to de-dupe)
|
||||
if (evPath && path !== evPath) {
|
||||
fsWatchBroadcast(
|
||||
sysPath.resolve(path, evPath), 'listeners', sysPath.join(path, evPath)
|
||||
);
|
||||
}
|
||||
};
|
||||
try {
|
||||
return fs.watch(path, options, handleEvent);
|
||||
} catch (error) {
|
||||
errHandler(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Private function: Helper for passing fs.watch event data to a
|
||||
// collection of listeners
|
||||
|
||||
// * fullPath - string, absolute path bound to the fs.watch instance
|
||||
// * type - string, listener type
|
||||
// * val[1..3] - arguments to be passed to listeners
|
||||
|
||||
// Returns nothing
|
||||
function fsWatchBroadcast(fullPath, type, val1, val2, val3) {
|
||||
if (!FsWatchInstances[fullPath]) return;
|
||||
FsWatchInstances[fullPath][type].forEach(function(listener) {
|
||||
listener(val1, val2, val3);
|
||||
});
|
||||
}
|
||||
|
||||
// Private function: Instantiates the fs.watch interface or binds listeners
|
||||
// to an existing one covering the same file system entry
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * fullPath - string, absolute path
|
||||
// * options - object, options to be passed to fs.watch
|
||||
// * handlers - object, container for event listener functions
|
||||
|
||||
// Returns close function
|
||||
function setFsWatchListener(path, fullPath, options, handlers) {
|
||||
var listener = handlers.listener;
|
||||
var errHandler = handlers.errHandler;
|
||||
var rawEmitter = handlers.rawEmitter;
|
||||
var container = FsWatchInstances[fullPath];
|
||||
var watcher;
|
||||
if (!options.persistent) {
|
||||
watcher = createFsWatchInstance(
|
||||
path, options, listener, errHandler, rawEmitter
|
||||
);
|
||||
return watcher.close.bind(watcher);
|
||||
}
|
||||
if (!container) {
|
||||
watcher = createFsWatchInstance(
|
||||
path,
|
||||
options,
|
||||
fsWatchBroadcast.bind(null, fullPath, 'listeners'),
|
||||
errHandler, // no need to use broadcast here
|
||||
fsWatchBroadcast.bind(null, fullPath, 'rawEmitters')
|
||||
);
|
||||
if (!watcher) return;
|
||||
var broadcastErr = fsWatchBroadcast.bind(null, fullPath, 'errHandlers');
|
||||
watcher.on('error', function(error) {
|
||||
// Workaround for https://github.com/joyent/node/issues/4337
|
||||
if (process.platform === 'win32' && error.code === 'EPERM') {
|
||||
fs.open(path, 'r', function(err, fd) {
|
||||
if (fd) fs.close(fd);
|
||||
if (!err) broadcastErr(error);
|
||||
});
|
||||
} else {
|
||||
broadcastErr(error);
|
||||
}
|
||||
});
|
||||
container = FsWatchInstances[fullPath] = {
|
||||
listeners: [listener],
|
||||
errHandlers: [errHandler],
|
||||
rawEmitters: [rawEmitter],
|
||||
watcher: watcher
|
||||
};
|
||||
} else {
|
||||
container.listeners.push(listener);
|
||||
container.errHandlers.push(errHandler);
|
||||
container.rawEmitters.push(rawEmitter);
|
||||
}
|
||||
var listenerIndex = container.listeners.length - 1;
|
||||
|
||||
// removes this instance's listeners and closes the underlying fs.watch
|
||||
// instance if there are no more listeners left
|
||||
return function close() {
|
||||
delete container.listeners[listenerIndex];
|
||||
delete container.errHandlers[listenerIndex];
|
||||
delete container.rawEmitters[listenerIndex];
|
||||
if (!Object.keys(container.listeners).length) {
|
||||
container.watcher.close();
|
||||
delete FsWatchInstances[fullPath];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// fs.watchFile helpers
|
||||
|
||||
// object to hold per-process fs.watchFile instances
|
||||
// (may be shared across chokidar FSWatcher instances)
|
||||
var FsWatchFileInstances = Object.create(null);
|
||||
|
||||
// Private function: Instantiates the fs.watchFile interface or binds listeners
|
||||
// to an existing one covering the same file system entry
|
||||
|
||||
// * path - string, path to be watched
|
||||
// * fullPath - string, absolute path
|
||||
// * options - object, options to be passed to fs.watchFile
|
||||
// * handlers - object, container for event listener functions
|
||||
|
||||
// Returns close function
|
||||
function setFsWatchFileListener(path, fullPath, options, handlers) {
|
||||
var listener = handlers.listener;
|
||||
var rawEmitter = handlers.rawEmitter;
|
||||
var container = FsWatchFileInstances[fullPath];
|
||||
var listeners = [];
|
||||
var rawEmitters = [];
|
||||
if (
|
||||
container && (
|
||||
container.options.persistent < options.persistent ||
|
||||
container.options.interval > options.interval
|
||||
)
|
||||
) {
|
||||
// "Upgrade" the watcher to persistence or a quicker interval.
|
||||
// This creates some unlikely edge case issues if the user mixes
|
||||
// settings in a very weird way, but solving for those cases
|
||||
// doesn't seem worthwhile for the added complexity.
|
||||
listeners = container.listeners;
|
||||
rawEmitters = container.rawEmitters;
|
||||
fs.unwatchFile(fullPath);
|
||||
container = false;
|
||||
}
|
||||
if (!container) {
|
||||
listeners.push(listener);
|
||||
rawEmitters.push(rawEmitter);
|
||||
container = FsWatchFileInstances[fullPath] = {
|
||||
listeners: listeners,
|
||||
rawEmitters: rawEmitters,
|
||||
options: options,
|
||||
watcher: fs.watchFile(fullPath, options, function(curr, prev) {
|
||||
container.rawEmitters.forEach(function(rawEmitter) {
|
||||
rawEmitter('change', fullPath, {curr: curr, prev: prev});
|
||||
});
|
||||
var currmtime = curr.mtime.getTime();
|
||||
if (curr.size !== prev.size || currmtime > prev.mtime.getTime() || currmtime === 0) {
|
||||
container.listeners.forEach(function(listener) {
|
||||
listener(path, curr);
|
||||
});
|
||||
}
|
||||
})
|
||||
};
|
||||
} else {
|
||||
container.listeners.push(listener);
|
||||
container.rawEmitters.push(rawEmitter);
|
||||
}
|
||||
var listenerIndex = container.listeners.length - 1;
|
||||
|
||||
// removes this instance's listeners and closes the underlying fs.watchFile
|
||||
// instance if there are no more listeners left
|
||||
return function close() {
|
||||
delete container.listeners[listenerIndex];
|
||||
delete container.rawEmitters[listenerIndex];
|
||||
if (!Object.keys(container.listeners).length) {
|
||||
fs.unwatchFile(fullPath);
|
||||
delete FsWatchFileInstances[fullPath];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fake constructor for attaching nodefs-specific prototype methods that
|
||||
// will be copied to FSWatcher's prototype
|
||||
function NodeFsHandler() {}
|
||||
|
||||
// Private method: Watch file for changes with fs.watchFile or fs.watch.
|
||||
|
||||
// * path - string, path to file or directory.
|
||||
// * listener - function, to be executed on fs change.
|
||||
|
||||
// Returns close function for the watcher instance
|
||||
NodeFsHandler.prototype._watchWithNodeFs =
|
||||
function(path, listener) {
|
||||
var directory = sysPath.dirname(path);
|
||||
var basename = sysPath.basename(path);
|
||||
var parent = this._getWatchedDir(directory);
|
||||
parent.add(basename);
|
||||
var absolutePath = sysPath.resolve(path);
|
||||
var options = {persistent: this.options.persistent};
|
||||
if (!listener) listener = Function.prototype; // empty function
|
||||
|
||||
var closer;
|
||||
if (this.options.usePolling) {
|
||||
options.interval = this.enableBinaryInterval && isBinaryPath(basename) ?
|
||||
this.options.binaryInterval : this.options.interval;
|
||||
closer = setFsWatchFileListener(path, absolutePath, options, {
|
||||
listener: listener,
|
||||
rawEmitter: this.emit.bind(this, 'raw')
|
||||
});
|
||||
} else {
|
||||
closer = setFsWatchListener(path, absolutePath, options, {
|
||||
listener: listener,
|
||||
errHandler: this._handleError.bind(this),
|
||||
rawEmitter: this.emit.bind(this, 'raw')
|
||||
});
|
||||
}
|
||||
return closer;
|
||||
};
|
||||
|
||||
// Private method: Watch a file and emit add event if warranted
|
||||
|
||||
// * file - string, the file's path
|
||||
// * stats - object, result of fs.stat
|
||||
// * initialAdd - boolean, was the file added at watch instantiation?
|
||||
// * callback - function, called when done processing as a newly seen file
|
||||
|
||||
// Returns close function for the watcher instance
|
||||
NodeFsHandler.prototype._handleFile =
|
||||
function(file, stats, initialAdd, callback) {
|
||||
var dirname = sysPath.dirname(file);
|
||||
var basename = sysPath.basename(file);
|
||||
var parent = this._getWatchedDir(dirname);
|
||||
|
||||
// if the file is already being watched, do nothing
|
||||
if (parent.has(basename)) return callback();
|
||||
|
||||
// kick off the watcher
|
||||
var closer = this._watchWithNodeFs(file, function(path, newStats) {
|
||||
if (!this._throttle('watch', file, 5)) return;
|
||||
if (!newStats || newStats && newStats.mtime.getTime() === 0) {
|
||||
fs.stat(file, function(error, newStats) {
|
||||
// Fix issues where mtime is null but file is still present
|
||||
if (error) {
|
||||
this._remove(dirname, basename);
|
||||
} else {
|
||||
this._emit('change', file, newStats);
|
||||
}
|
||||
}.bind(this));
|
||||
// add is about to be emitted if file not already tracked in parent
|
||||
} else if (parent.has(basename)) {
|
||||
this._emit('change', file, newStats);
|
||||
}
|
||||
}.bind(this));
|
||||
|
||||
// emit an add event if we're supposed to
|
||||
if (!(initialAdd && this.options.ignoreInitial)) {
|
||||
if (!this._throttle('add', file, 0)) return;
|
||||
this._emit('add', file, stats);
|
||||
}
|
||||
|
||||
if (callback) callback();
|
||||
return closer;
|
||||
};
|
||||
|
||||
// Private method: Handle symlinks encountered while reading a dir
|
||||
|
||||
// * entry - object, entry object returned by readdirp
|
||||
// * directory - string, path of the directory being read
|
||||
// * path - string, path of this item
|
||||
// * item - string, basename of this item
|
||||
|
||||
// Returns true if no more processing is needed for this entry.
|
||||
NodeFsHandler.prototype._handleSymlink =
|
||||
function(entry, directory, path, item) {
|
||||
var full = entry.fullPath;
|
||||
var dir = this._getWatchedDir(directory);
|
||||
|
||||
if (!this.options.followSymlinks) {
|
||||
// watch symlink directly (don't follow) and detect changes
|
||||
this._readyCount++;
|
||||
fs.realpath(path, function(error, linkPath) {
|
||||
if (dir.has(item)) {
|
||||
if (this._symlinkPaths[full] !== linkPath) {
|
||||
this._symlinkPaths[full] = linkPath;
|
||||
this._emit('change', path, entry.stat);
|
||||
}
|
||||
} else {
|
||||
dir.add(item);
|
||||
this._symlinkPaths[full] = linkPath;
|
||||
this._emit('add', path, entry.stat);
|
||||
}
|
||||
this._emitReady();
|
||||
}.bind(this));
|
||||
return true;
|
||||
}
|
||||
|
||||
// don't follow the same symlink more than once
|
||||
if (this._symlinkPaths[full]) return true;
|
||||
else this._symlinkPaths[full] = true;
|
||||
}
|
||||
|
||||
// Private method: Read directory to add / remove files from `@watched` list
|
||||
// and re-read it on change.
|
||||
|
||||
// * dir - string, fs path.
|
||||
// * stats - object, result of fs.stat
|
||||
// * initialAdd - boolean, was the file added at watch instantiation?
|
||||
// * depth - int, depth relative to user-supplied path
|
||||
// * target - string, child path actually targeted for watch
|
||||
// * wh - object, common watch helpers for this path
|
||||
// * callback - function, called when dir scan is complete
|
||||
|
||||
// Returns close function for the watcher instance
|
||||
NodeFsHandler.prototype._handleDir =
|
||||
function(dir, stats, initialAdd, depth, target, wh, callback) {
|
||||
if (!(initialAdd && this.options.ignoreInitial) && !target && !wh.hasGlob) {
|
||||
this._emit('addDir', dir, stats);
|
||||
}
|
||||
|
||||
// ensure dir is tracked
|
||||
this._getWatchedDir(sysPath.dirname(dir)).add(sysPath.basename(dir));
|
||||
this._getWatchedDir(dir);
|
||||
|
||||
var read = function(directory, initialAdd, done) {
|
||||
// Normalize the directory name on Windows
|
||||
directory = sysPath.join(directory, '');
|
||||
|
||||
if (!wh.hasGlob) {
|
||||
var throttler = this._throttle('readdir', directory, 1000);
|
||||
if (!throttler) return;
|
||||
}
|
||||
|
||||
var previous = this._getWatchedDir(wh.path);
|
||||
var current = [];
|
||||
|
||||
readdirp({
|
||||
root: directory,
|
||||
entryType: 'all',
|
||||
fileFilter: wh.filterPath,
|
||||
directoryFilter: wh.filterDir,
|
||||
depth: 0,
|
||||
lstat: true
|
||||
}).on('data', function(entry) {
|
||||
var item = entry.path;
|
||||
var path = sysPath.join(directory, item);
|
||||
current.push(item);
|
||||
|
||||
if (entry.stat.isSymbolicLink() &&
|
||||
this._handleSymlink(entry, directory, path, item)) return;
|
||||
|
||||
// Files that present in current directory snapshot
|
||||
// but absent in previous are added to watch list and
|
||||
// emit `add` event.
|
||||
if (item === target || !target && !previous.has(item)) {
|
||||
this._readyCount++;
|
||||
|
||||
// ensure relativeness of path is preserved in case of watcher reuse
|
||||
path = sysPath.join(dir, sysPath.relative(dir, path));
|
||||
|
||||
this._addToNodeFs(path, initialAdd, wh, depth + 1);
|
||||
}
|
||||
}.bind(this)).on('end', function() {
|
||||
if (throttler) throttler.clear();
|
||||
if (done) done();
|
||||
|
||||
// Files that absent in current directory snapshot
|
||||
// but present in previous emit `remove` event
|
||||
// and are removed from @watched[directory].
|
||||
previous.children().filter(function(item) {
|
||||
return item !== directory &&
|
||||
current.indexOf(item) === -1 &&
|
||||
// in case of intersecting globs;
|
||||
// a path may have been filtered out of this readdir, but
|
||||
// shouldn't be removed because it matches a different glob
|
||||
(!wh.hasGlob || wh.filterPath({
|
||||
fullPath: sysPath.resolve(directory, item)
|
||||
}));
|
||||
}).forEach(function(item) {
|
||||
this._remove(directory, item);
|
||||
}, this);
|
||||
}.bind(this)).on('error', this._handleError.bind(this));
|
||||
}.bind(this);
|
||||
|
||||
if (this.options.depth == null || depth <= this.options.depth) {
|
||||
if (!target) read(dir, initialAdd, callback);
|
||||
var closer = this._watchWithNodeFs(dir, function(dirPath, stats) {
|
||||
// if current directory is removed, do nothing
|
||||
if (stats && stats.mtime.getTime() === 0) return;
|
||||
|
||||
read(dirPath, false);
|
||||
});
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
return closer;
|
||||
};
|
||||
|
||||
// Private method: Handle added file, directory, or glob pattern.
|
||||
// Delegates call to _handleFile / _handleDir after checks.
|
||||
|
||||
// * path - string, path to file or directory.
|
||||
// * initialAdd - boolean, was the file added at watch instantiation?
|
||||
// * depth - int, depth relative to user-supplied path
|
||||
// * target - string, child path actually targeted for watch
|
||||
// * callback - function, indicates whether the path was found or not
|
||||
|
||||
// Returns nothing
|
||||
NodeFsHandler.prototype._addToNodeFs =
|
||||
function(path, initialAdd, priorWh, depth, target, callback) {
|
||||
if (!callback) callback = Function.prototype;
|
||||
var ready = this._emitReady;
|
||||
if (this._isIgnored(path) || this.closed) {
|
||||
ready();
|
||||
return callback(null, false);
|
||||
}
|
||||
|
||||
var wh = this._getWatchHelpers(path, depth);
|
||||
if (!wh.hasGlob && priorWh) {
|
||||
wh.hasGlob = priorWh.hasGlob;
|
||||
wh.filterPath = priorWh.filterPath;
|
||||
wh.filterDir = priorWh.filterDir;
|
||||
}
|
||||
|
||||
// evaluate what is at the path we're being asked to watch
|
||||
fs[wh.statMethod](wh.watchPath, function(error, stats) {
|
||||
if (this._handleError(error)) return callback(null, path);
|
||||
if (this._isIgnored(wh.watchPath, stats)) {
|
||||
ready();
|
||||
return callback(null, false);
|
||||
}
|
||||
|
||||
var initDir = function(dir, target) {
|
||||
return this._handleDir(dir, stats, initialAdd, depth, target, wh, ready);
|
||||
}.bind(this);
|
||||
|
||||
var closer;
|
||||
if (stats.isDirectory()) {
|
||||
closer = initDir(wh.watchPath, target);
|
||||
} else if (stats.isSymbolicLink()) {
|
||||
var parent = sysPath.dirname(wh.watchPath);
|
||||
this._getWatchedDir(parent).add(wh.watchPath);
|
||||
this._emit('add', wh.watchPath, stats);
|
||||
closer = initDir(parent, path);
|
||||
|
||||
// preserve this symlink's target path
|
||||
fs.realpath(path, function(error, targetPath) {
|
||||
this._symlinkPaths[sysPath.resolve(path)] = targetPath;
|
||||
ready();
|
||||
}.bind(this));
|
||||
} else {
|
||||
closer = this._handleFile(wh.watchPath, stats, initialAdd, ready);
|
||||
}
|
||||
|
||||
if (closer) this._closers[path] = closer;
|
||||
callback(null, false);
|
||||
}.bind(this));
|
||||
};
|
||||
|
||||
module.exports = NodeFsHandler;
|
||||
15
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/LICENSE
generated
vendored
Normal file
15
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
The ISC License
|
||||
|
||||
Copyright (c) 2014 Elan Shanker
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
|
||||
IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
91
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/README.md
generated
vendored
Normal file
91
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/README.md
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
anymatch [](https://travis-ci.org/es128/anymatch) [](https://coveralls.io/r/es128/anymatch?branch=master)
|
||||
======
|
||||
Javascript module to match a string against a regular expression, glob, string,
|
||||
or function that takes the string as an argument and returns a truthy or falsy
|
||||
value. The matcher can also be an array of any or all of these. Useful for
|
||||
allowing a very flexible user-defined config to define things like file paths.
|
||||
|
||||
[](https://nodei.co/npm/anymatch/)
|
||||
[](https://nodei.co/npm-dl/anymatch/)
|
||||
|
||||
Usage
|
||||
-----
|
||||
```sh
|
||||
npm install anymatch --save
|
||||
```
|
||||
|
||||
#### anymatch (matchers, testString, [returnIndex], [startIndex], [endIndex])
|
||||
* __matchers__: (_Array|String|RegExp|Function_)
|
||||
String to be directly matched, string with glob patterns, regular expression
|
||||
test, function that takes the testString as an argument and returns a truthy
|
||||
value if it should be matched, or an array of any number and mix of these types.
|
||||
* __testString__: (_String|Array_) The string to test against the matchers. If
|
||||
passed as an array, the first element of the array will be used as the
|
||||
`testString` for non-function matchers, while the entire array will be applied
|
||||
as the arguments for function matchers.
|
||||
* __returnIndex__: (_Boolean [optional]_) If true, return the array index of
|
||||
the first matcher that that testString matched, or -1 if no match, instead of a
|
||||
boolean result.
|
||||
* __startIndex, endIndex__: (_Integer [optional]_) Can be used to define a
|
||||
subset out of the array of provided matchers to test against. Can be useful
|
||||
with bound matcher functions (see below). When used with `returnIndex = true`
|
||||
preserves original indexing. Behaves the same as `Array.prototype.slice` (i.e.
|
||||
includes array members up to, but not including endIndex).
|
||||
|
||||
```js
|
||||
var anymatch = require('anymatch');
|
||||
|
||||
var matchers = [
|
||||
'path/to/file.js',
|
||||
'path/anyjs/**/*.js',
|
||||
/foo.js$/,
|
||||
function (string) {
|
||||
return string.indexOf('bar') !== -1 && string.length > 10
|
||||
}
|
||||
];
|
||||
|
||||
anymatch(matchers, 'path/to/file.js'); // true
|
||||
anymatch(matchers, 'path/anyjs/baz.js'); // true
|
||||
anymatch(matchers, 'path/to/foo.js'); // true
|
||||
anymatch(matchers, 'path/to/bar.js'); // true
|
||||
anymatch(matchers, 'bar.js'); // false
|
||||
|
||||
// returnIndex = true
|
||||
anymatch(matchers, 'foo.js', true); // 2
|
||||
anymatch(matchers, 'path/anyjs/foo.js', true); // 1
|
||||
|
||||
// skip matchers
|
||||
anymatch(matchers, 'path/to/file.js', false, 1); // false
|
||||
anymatch(matchers, 'path/anyjs/foo.js', true, 2, 3); // 2
|
||||
anymatch(matchers, 'path/to/bar.js', true, 0, 3); // -1
|
||||
```
|
||||
|
||||
#### anymatch (matchers)
|
||||
You can also pass in only your matcher(s) to get a curried function that has
|
||||
already been bound to the provided matching criteria. This can be used as an
|
||||
`Array.prototype.filter` callback.
|
||||
|
||||
```js
|
||||
var matcher = anymatch(matchers);
|
||||
|
||||
matcher('path/to/file.js'); // true
|
||||
matcher('path/anyjs/baz.js', true); // 1
|
||||
matcher('path/anyjs/baz.js', true, 2); // -1
|
||||
|
||||
['foo.js', 'bar.js'].filter(matcher); // ['foo.js']
|
||||
```
|
||||
|
||||
Change Log
|
||||
----------
|
||||
[See release notes page on GitHub](https://github.com/es128/anymatch/releases)
|
||||
|
||||
NOTE: As of v1.2.0, anymatch uses [micromatch](https://github.com/jonschlinkert/micromatch)
|
||||
for glob pattern matching. The glob matching behavior should be functionally
|
||||
equivalent to the commonly used [minimatch](https://github.com/isaacs/minimatch)
|
||||
library (aside from some fixed bugs and greater performance), so a major
|
||||
version bump wasn't merited. Issues with glob pattern matching should be
|
||||
reported directly to the [micromatch issue tracker](https://github.com/jonschlinkert/micromatch/issues).
|
||||
|
||||
License
|
||||
-------
|
||||
[ISC](https://raw.github.com/es128/anymatch/master/LICENSE)
|
||||
64
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/index.js
generated
vendored
Normal file
64
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/index.js
generated
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
var arrify = require('arrify');
|
||||
var micromatch = require('micromatch');
|
||||
var path = require('path');
|
||||
|
||||
var anymatch = function(criteria, value, returnIndex, startIndex, endIndex) {
|
||||
criteria = arrify(criteria);
|
||||
value = arrify(value);
|
||||
if (arguments.length === 1) {
|
||||
return anymatch.bind(null, criteria.map(function(criterion) {
|
||||
return typeof criterion === 'string' && criterion[0] !== '!' ?
|
||||
micromatch.matcher(criterion) : criterion;
|
||||
}));
|
||||
}
|
||||
startIndex = startIndex || 0;
|
||||
var string = value[0];
|
||||
var altString;
|
||||
var matched = false;
|
||||
var matchIndex = -1;
|
||||
function testCriteria (criterion, index) {
|
||||
var result;
|
||||
switch (toString.call(criterion)) {
|
||||
case '[object String]':
|
||||
result = string === criterion || altString && altString === criterion;
|
||||
result = result || micromatch.isMatch(string, criterion);
|
||||
break;
|
||||
case '[object RegExp]':
|
||||
result = criterion.test(string) || altString && criterion.test(altString);
|
||||
break;
|
||||
case '[object Function]':
|
||||
result = criterion.apply(null, value);
|
||||
break;
|
||||
default:
|
||||
result = false;
|
||||
}
|
||||
if (result) {
|
||||
matchIndex = index + startIndex;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
var crit = criteria;
|
||||
var negGlobs = crit.reduce(function(arr, criterion, index) {
|
||||
if (typeof criterion === 'string' && criterion[0] === '!') {
|
||||
if (crit === criteria) {
|
||||
// make a copy before modifying
|
||||
crit = crit.slice();
|
||||
}
|
||||
crit[index] = null;
|
||||
arr.push(criterion.substr(1));
|
||||
}
|
||||
return arr;
|
||||
}, []);
|
||||
if (!negGlobs.length || !micromatch.any(string, negGlobs)) {
|
||||
if (path.sep === '\\' && typeof string === 'string') {
|
||||
altString = string.split('\\').join('/');
|
||||
altString = altString === string ? null : altString;
|
||||
}
|
||||
matched = crit.slice(startIndex, endIndex).some(testCriteria);
|
||||
}
|
||||
return returnIndex === true ? matchIndex : matched;
|
||||
};
|
||||
|
||||
module.exports = anymatch;
|
||||
21
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/LICENSE
generated
vendored
Executable file
21
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/LICENSE
generated
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
616
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/README.md
generated
vendored
Executable file
616
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/README.md
generated
vendored
Executable file
@@ -0,0 +1,616 @@
|
||||
# micromatch [](http://badge.fury.io/js/micromatch) [](https://travis-ci.org/jonschlinkert/micromatch)
|
||||
|
||||
> Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just use `micromatch.isMatch()` instead of `minimatch()`, or use `micromatch()` instead of `multimatch()`.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i micromatch --save
|
||||
```
|
||||
|
||||
## Table of contents
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
* [Features](#features)
|
||||
* [Usage](#usage)
|
||||
* [Switch from minimatch](#switch-from-minimatch)
|
||||
* [Methods](#methods)
|
||||
- [.isMatch](#ismatch)
|
||||
- [.contains](#contains)
|
||||
- [.matcher](#matcher)
|
||||
- [.filter](#filter)
|
||||
- [.any](#any)
|
||||
- [.expand](#expand)
|
||||
- [.makeRe](#makere)
|
||||
* [Options](#options)
|
||||
- [options.unixify](#optionsunixify)
|
||||
- [options.dot](#optionsdot)
|
||||
- [options.unescape](#optionsunescape)
|
||||
- [options.nodupes](#optionsnodupes)
|
||||
- [options.matchBase](#optionsmatchbase)
|
||||
- [options.nobraces](#optionsnobraces)
|
||||
- [options.nobrackets](#optionsnobrackets)
|
||||
- [options.noextglob](#optionsnoextglob)
|
||||
- [options.nocase](#optionsnocase)
|
||||
- [options.nonull](#optionsnonull)
|
||||
- [options.cache](#optionscache)
|
||||
* [Other features](#other-features)
|
||||
- [Extended globbing](#extended-globbing)
|
||||
+ [extglobs](#extglobs)
|
||||
+ [brace expansion](#brace-expansion)
|
||||
+ [regex character classes](#regex-character-classes)
|
||||
+ [regex groups](#regex-groups)
|
||||
+ [POSIX bracket expressions](#posix-bracket-expressions)
|
||||
* [Notes](#notes)
|
||||
* [Benchmarks](#benchmarks)
|
||||
* [Run tests](#run-tests)
|
||||
* [Contributing](#contributing)
|
||||
* [Related](#related)
|
||||
* [Author](#author)
|
||||
* [License](#license)
|
||||
|
||||
_(Table of contents generated by [verb](https://github.com/assemble/verb))_
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Features
|
||||
|
||||
Micromatch is [10-55x faster](#benchmarks) than [minimatch](https://github.com/isaacs/minimatch#readme), resulting from a combination of caching, tokenization, parsing, runtime compilation and regex optimization strategies.
|
||||
|
||||
* [Drop-in replacement](#switch-from-minimatch) for [minimatch](https://github.com/isaacs/minimatch#readme) and [multimatch](https://github.com/sindresorhus/multimatch)
|
||||
* Built-in support for multiple glob patterns, like `['foo/*.js', '!bar.js']`
|
||||
* Better support for the Bash 4.3 specification, and less buggy
|
||||
* Extensive [unit tests](./test) (approx. 1,300 tests). Minimatch fails many of the tests.
|
||||
|
||||
**Mainstream glob features:**
|
||||
|
||||
* [Brace Expansion](https://github.com/jonschlinkert/braces) (`foo/bar-{1..5}.md`, `one/{two,three}/four.md`)
|
||||
* Typical glob patterns, like `**/*`, `a/b/*.js`, or `['foo/*.js', '!bar.js']`
|
||||
|
||||
**Extended globbing features:**
|
||||
|
||||
* Logical `OR` (`foo/bar/(abc|xyz).js`)
|
||||
* Regex character classes (`foo/bar/baz-[1-5].js`)
|
||||
* POSIX [bracket expressions](https://github.com/jonschlinkert/expand-brackets) (`**/[[:alpha:][:digit:]]/`)
|
||||
* [extglobs](https://github.com/jonschlinkert/extglob) (`**/+(x|y)`, `!(a|b)`, etc)
|
||||
|
||||
You can combine these to create whatever matching patterns you need.
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var mm = require('micromatch');
|
||||
mm(array, patterns);
|
||||
```
|
||||
|
||||
**Examples**
|
||||
|
||||
```js
|
||||
mm(['a.js', 'b.md', 'c.txt'], '*.{js,txt}');
|
||||
//=> ['a.js', 'c.txt']
|
||||
```
|
||||
|
||||
**Multiple patterns**
|
||||
|
||||
Multiple patterns can also be passed:
|
||||
|
||||
```js
|
||||
mm(['a.md', 'b.js', 'c.txt', 'd.json'], ['*.md', '*.txt']);
|
||||
//=> ['a.md', 'c.txt']
|
||||
```
|
||||
|
||||
**Negation patterns:**
|
||||
|
||||
Behavior;
|
||||
|
||||
* when the pattern is a string, [minimatch](https://github.com/isaacs/minimatch#readme) behavior is used, so patterns are **inclusive by default**.
|
||||
* when an array of patterns is passed, [multimatch](https://github.com/sindresorhus/multimatch) behavior is used, so patterns are **exclusive by default**
|
||||
|
||||
```js
|
||||
mm(['a.js', 'b.md', 'c.txt'], '!*.{js,txt}');
|
||||
//=> ['b.md']
|
||||
|
||||
mm(['a.md', 'b.js', 'c.txt', 'd.json'], ['*.*', '!*.{js,txt}']);
|
||||
//=> ['a.md', 'd.json']
|
||||
```
|
||||
|
||||
## Switch from minimatch
|
||||
|
||||
> Use `micromatch.isMatch()` instead of `minimatch()`
|
||||
|
||||
**Minimatch**
|
||||
|
||||
The main `minimatch()` function returns true/false for a single file path and pattern:
|
||||
|
||||
```js
|
||||
var minimatch = require('minimatch');
|
||||
minimatch('foo.js', '*.js');
|
||||
//=> 'true'
|
||||
```
|
||||
|
||||
**Micromatch**
|
||||
|
||||
With micromatch, `.isMatch()` to get the same result:
|
||||
|
||||
```js
|
||||
var mm = require('micromatch');
|
||||
mm.isMatch('foo.js', '*.js');
|
||||
//=> 'true'
|
||||
```
|
||||
|
||||
This implementation difference is necessary since the main `micromatch()` method supports matching on multiple globs, with behavior similar to [multimatch](https://github.com/sindresorhus/multimatch).
|
||||
|
||||
## Methods
|
||||
|
||||
```js
|
||||
var mm = require('micromatch');
|
||||
```
|
||||
|
||||
### .isMatch
|
||||
|
||||
```js
|
||||
mm.isMatch(filepath, globPattern);
|
||||
```
|
||||
|
||||
Returns true if a file path matches the given glob pattern.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
mm.isMatch('.verb.md', '*.md');
|
||||
//=> false
|
||||
|
||||
mm.isMatch('.verb.md', '*.md', {dot: true});
|
||||
//=> true
|
||||
```
|
||||
|
||||
### .contains
|
||||
|
||||
Returns true if any part of a file path matches the given glob pattern. Think of this is "has path" versus "is path".
|
||||
|
||||
**Example**
|
||||
|
||||
`.isMatch()` would return false for both of the following:
|
||||
|
||||
```js
|
||||
mm.contains('a/b/c', 'a/b');
|
||||
//=> true
|
||||
|
||||
mm.contains('a/b/c', 'a/*');
|
||||
//=> true
|
||||
```
|
||||
|
||||
### .matcher
|
||||
|
||||
Returns a function for matching using the supplied pattern. e.g. create your own "matcher". The advantage of this method is that the pattern can be compiled outside of a loop.
|
||||
|
||||
**Pattern**
|
||||
|
||||
Can be any of the following:
|
||||
|
||||
* `glob/string`
|
||||
* `regex`
|
||||
* `function`
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
var isMatch = mm.matcher('*.md');
|
||||
var files = [];
|
||||
|
||||
['a.md', 'b.txt', 'c.md'].forEach(function(fp) {
|
||||
if (isMatch(fp)) {
|
||||
files.push(fp);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
### .filter
|
||||
|
||||
Returns a function that can be passed to `Array#filter()`.
|
||||
|
||||
**Params**
|
||||
|
||||
* `patterns` **{String|Array}**:
|
||||
|
||||
**Examples**
|
||||
|
||||
Single glob:
|
||||
|
||||
```js
|
||||
var fn = mm.filter('*.md');
|
||||
['a.js', 'b.txt', 'c.md'].filter(fn);
|
||||
//=> ['c.md']
|
||||
|
||||
var fn = mm.filter('[a-c]');
|
||||
['a', 'b', 'c', 'd', 'e'].filter(fn);
|
||||
//=> ['a', 'b', 'c']
|
||||
```
|
||||
|
||||
Array of glob patterns:
|
||||
|
||||
```js
|
||||
var arr = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15];
|
||||
|
||||
var fn = mm.filter(['{1..10}', '![7-9]', '!{3..4}']);
|
||||
arr.filter(fn);
|
||||
//=> [1, 2, 5, 6, 10]
|
||||
```
|
||||
|
||||
_(Internally this function generates the matching function by using the [matcher](#matcher) method. You can use the [matcher](#matcher) method directly to create your own filter function)_
|
||||
|
||||
### .any
|
||||
|
||||
Returns true if a file path matches any of the given patterns.
|
||||
|
||||
```js
|
||||
mm.any(filepath, patterns, options);
|
||||
```
|
||||
|
||||
**Params**
|
||||
|
||||
* filepath `{String}`: The file path to test.
|
||||
* patterns `{String|Array}`: One or more glob patterns
|
||||
* options: `{Object}`: options to pass to the `.matcher()` method.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
mm.any('abc', ['!*z']);
|
||||
//=> true
|
||||
mm.any('abc', ['a*', 'z*']);
|
||||
//=> true
|
||||
mm.any('abc', 'a*');
|
||||
//=> true
|
||||
mm.any('abc', ['z*']);
|
||||
//=> false
|
||||
```
|
||||
|
||||
### .expand
|
||||
|
||||
Returns an object with a regex-compatible string and tokens.
|
||||
|
||||
```js
|
||||
mm.expand('*.js');
|
||||
|
||||
// when `track` is enabled (for debugging), the `history` array is used
|
||||
// to record each mutation to the glob pattern as it's converted to regex
|
||||
{ options: { track: false, dot: undefined, makeRe: true, negated: false },
|
||||
pattern: '(.*\\/|^)bar\\/(?:(?!(?:^|\\/)\\.).)*?',
|
||||
history: [],
|
||||
tokens:
|
||||
{ path:
|
||||
{ whole: '**/bar/**',
|
||||
dirname: '**/bar/',
|
||||
filename: '**',
|
||||
basename: '**',
|
||||
extname: '',
|
||||
ext: '' },
|
||||
is:
|
||||
{ glob: true,
|
||||
negated: false,
|
||||
globstar: true,
|
||||
dotfile: false,
|
||||
dotdir: false },
|
||||
match: {},
|
||||
original: '**/bar/**',
|
||||
pattern: '**/bar/**',
|
||||
base: '' } }
|
||||
```
|
||||
|
||||
### .makeRe
|
||||
|
||||
Create a regular expression for matching file paths based on the given pattern:
|
||||
|
||||
```js
|
||||
mm.makeRe('*.js');
|
||||
//=> /^(?:(?!\.)(?=.)[^/]*?\.js)$/
|
||||
```
|
||||
|
||||
## Options
|
||||
|
||||
### options.unixify
|
||||
|
||||
Normalize slashes in file paths and glob patterns to forward slashes.
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `undefined` on non-windows, `true` on windows.
|
||||
|
||||
### options.dot
|
||||
|
||||
Match dotfiles. Same behavior as [minimatch](https://github.com/isaacs/minimatch#readme).
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `false`
|
||||
|
||||
### options.unescape
|
||||
|
||||
Unescape slashes in glob patterns. Use cautiously, especially on windows.
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `undefined`
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
mm.isMatch('abc', '\\a\\b\\c', {unescape: true});
|
||||
//=> true
|
||||
```
|
||||
|
||||
### options.nodupes
|
||||
|
||||
Remove duplicate elements from the result array.
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `undefined`
|
||||
|
||||
**Example**
|
||||
|
||||
Example of using the `unescape` and `nodupes` options together:
|
||||
|
||||
```js
|
||||
mm.match(['abc', '\\a\\b\\c'], '\\a\\b\\c', {unescape: true});
|
||||
//=> ['abc', 'abc']
|
||||
|
||||
mm.match(['abc', '\\a\\b\\c'], '\\a\\b\\c', {unescape: true, nodupes: true});
|
||||
//=> ['abc']
|
||||
```
|
||||
|
||||
### options.matchBase
|
||||
|
||||
Allow glob patterns without slashes to match a file path based on its basename. . Same behavior as [minimatch](https://github.com/isaacs/minimatch#readme).
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `false`
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
mm(['a/b.js', 'a/c.md'], '*.js');
|
||||
//=> []
|
||||
|
||||
mm(['a/b.js', 'a/c.md'], '*.js', {matchBase: true});
|
||||
//=> ['a/b.js']
|
||||
```
|
||||
|
||||
### options.nobraces
|
||||
|
||||
Don't expand braces in glob patterns. Same behavior as [minimatch](https://github.com/isaacs/minimatch#readme) `nobrace`.
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `undefined`
|
||||
|
||||
See [braces](https://github.com/jonschlinkert/braces) for more information about extended brace expansion.
|
||||
|
||||
### options.nobrackets
|
||||
|
||||
Don't expand POSIX bracket expressions.
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `undefined`
|
||||
|
||||
See [expand-brackets](https://github.com/jonschlinkert/expand-brackets) for more information about extended bracket expressions.
|
||||
|
||||
### options.noextglob
|
||||
|
||||
Don't expand extended globs.
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `undefined`
|
||||
|
||||
See [extglob](https://github.com/jonschlinkert/extglob) for more information about extended globs.
|
||||
|
||||
### options.nocase
|
||||
|
||||
Use a case-insensitive regex for matching files. Same behavior as [minimatch](https://github.com/isaacs/minimatch#readme).
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `false`
|
||||
|
||||
### options.nonull
|
||||
|
||||
If `true`, when no matches are found the actual (array-ified) glob pattern is returned instead of an empty array. Same behavior as [minimatch](https://github.com/isaacs/minimatch#readme).
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `false`
|
||||
|
||||
### options.cache
|
||||
|
||||
Cache the platform (e.g. `win32`) to prevent this from being looked up for every filepath.
|
||||
|
||||
Type: `{Boolean}`
|
||||
|
||||
Default: `true`
|
||||
|
||||
## Other features
|
||||
|
||||
Micromatch also supports the following.
|
||||
|
||||
### Extended globbing
|
||||
|
||||
#### extglobs
|
||||
|
||||
Extended globbing, as described by the bash man page:
|
||||
|
||||
| **pattern** | **regex equivalent** | **description** |
|
||||
| --- | --- | --- |
|
||||
| `?(pattern-list)` | `(...|...)?` | Matches zero or one occurrence of the given patterns |
|
||||
| `*(pattern-list)` | `(...|...)*` | Matches zero or more occurrences of the given patterns |
|
||||
| `+(pattern-list)` | `(...|...)+` | Matches one or more occurrences of the given patterns |
|
||||
| `@(pattern-list)` | `(...|...)` <sup>*</sup> | Matches one of the given patterns |
|
||||
| `!(pattern-list)` | N/A | Matches anything except one of the given patterns |
|
||||
|
||||
<sup><strong>*</strong></sup> `@` isn't a RegEx character.
|
||||
|
||||
Powered by [extglob](https://github.com/jonschlinkert/extglob). Visit that library for the full range of options or to report extglob related issues.
|
||||
|
||||
See [extglob](https://github.com/jonschlinkert/extglob) for more information about extended globs.
|
||||
|
||||
#### brace expansion
|
||||
|
||||
In simple cases, brace expansion appears to work the same way as the logical `OR` operator. For example, `(a|b)` will achieve the same result as `{a,b}`.
|
||||
|
||||
Here are some powerful features unique to brace expansion (versus character classes):
|
||||
|
||||
* range expansion: `a{1..3}b/*.js` expands to: `['a1b/*.js', 'a2b/*.js', 'a3b/*.js']`
|
||||
* nesting: `a{c,{d,e}}b/*.js` expands to: `['acb/*.js', 'adb/*.js', 'aeb/*.js']`
|
||||
|
||||
Visit [braces](https://github.com/jonschlinkert/braces) to ask questions and create an issue related to brace-expansion, or to see the full range of features and options related to brace expansion.
|
||||
|
||||
#### regex character classes
|
||||
|
||||
With the exception of brace expansion (`{a,b}`, `{1..5}`, etc), most of the special characters convert directly to regex, so you can expect them to follow the same rules and produce the same results as regex.
|
||||
|
||||
For example, given the list: `['a.js', 'b.js', 'c.js', 'd.js', 'E.js']`:
|
||||
|
||||
* `[ac].js`: matches both `a` and `c`, returning `['a.js', 'c.js']`
|
||||
* `[b-d].js`: matches from `b` to `d`, returning `['b.js', 'c.js', 'd.js']`
|
||||
* `[b-d].js`: matches from `b` to `d`, returning `['b.js', 'c.js', 'd.js']`
|
||||
* `a/[A-Z].js`: matches and uppercase letter, returning `['a/E.md']`
|
||||
|
||||
Learn about [regex character classes](http://www.regular-expressions.info/charclass.html).
|
||||
|
||||
#### regex groups
|
||||
|
||||
Given `['a.js', 'b.js', 'c.js', 'd.js', 'E.js']`:
|
||||
|
||||
* `(a|c).js`: would match either `a` or `c`, returning `['a.js', 'c.js']`
|
||||
* `(b|d).js`: would match either `b` or `d`, returning `['b.js', 'd.js']`
|
||||
* `(b|[A-Z]).js`: would match either `b` or an uppercase letter, returning `['b.js', 'E.js']`
|
||||
|
||||
As with regex, parenthese can be nested, so patterns like `((a|b)|c)/b` will work. But it might be easier to achieve your goal using brace expansion.
|
||||
|
||||
#### POSIX bracket expressions
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
mm.isMatch('a1', '[[:alpha:][:digit:]]');
|
||||
//=> true
|
||||
```
|
||||
|
||||
See [expand-brackets](https://github.com/jonschlinkert/expand-brackets) for more information about extended bracket expressions.
|
||||
|
||||
## Notes
|
||||
|
||||
Whenever possible parsing behavior for patterns is based on globbing specifications in Bash 4.3. Patterns that aren't described by Bash follow wildmatch spec (used by git).
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Run the [benchmarks](./benchmark):
|
||||
|
||||
```bash
|
||||
node benchmark
|
||||
```
|
||||
|
||||
As of July 24, 2015:
|
||||
|
||||
```bash
|
||||
#1: basename-braces
|
||||
micromatch x 28,335 ops/sec ±0.49% (96 runs sampled)
|
||||
minimatch x 3,496 ops/sec ±0.76% (98 runs sampled)
|
||||
|
||||
#2: basename
|
||||
micromatch x 28,602 ops/sec ±0.46% (96 runs sampled)
|
||||
minimatch x 4,389 ops/sec ±0.38% (98 runs sampled)
|
||||
|
||||
#3: braces-no-glob
|
||||
micromatch x 405,445 ops/sec ±0.64% (91 runs sampled)
|
||||
minimatch x 31,078 ops/sec ±0.45% (95 runs sampled)
|
||||
|
||||
#4: braces
|
||||
micromatch x 81,977 ops/sec ±0.36% (99 runs sampled)
|
||||
minimatch x 2,986 ops/sec ±0.41% (100 runs sampled)
|
||||
|
||||
#5: immediate
|
||||
micromatch x 20,753 ops/sec ±0.36% (101 runs sampled)
|
||||
minimatch x 4,233 ops/sec ±0.34% (100 runs sampled)
|
||||
|
||||
#6: large
|
||||
micromatch x 755 ops/sec ±0.53% (97 runs sampled)
|
||||
minimatch x 17.06 ops/sec ±0.25% (46 runs sampled)
|
||||
|
||||
#7: long
|
||||
micromatch x 7,009 ops/sec ±0.33% (100 runs sampled)
|
||||
minimatch x 592 ops/sec ±0.39% (96 runs sampled)
|
||||
|
||||
#8: mid
|
||||
micromatch x 60,071 ops/sec ±0.48% (97 runs sampled)
|
||||
minimatch x 1,853 ops/sec ±0.72% (99 runs sampled)
|
||||
|
||||
#9: multi-patterns
|
||||
micromatch x 24,308 ops/sec ±0.67% (98 runs sampled)
|
||||
minimatch x 2,169 ops/sec ±0.62% (96 runs sampled)
|
||||
|
||||
#10: no-glob
|
||||
micromatch x 552,116 ops/sec ±0.35% (96 runs sampled)
|
||||
minimatch x 55,957 ops/sec ±0.32% (94 runs sampled)
|
||||
|
||||
#11: range
|
||||
micromatch x 321,030 ops/sec ±0.62% (95 runs sampled)
|
||||
minimatch x 14,247 ops/sec ±0.59% (100 runs sampled)
|
||||
|
||||
#12: shallow
|
||||
micromatch x 253,455 ops/sec ±0.52% (99 runs sampled)
|
||||
minimatch x 21,169 ops/sec ±0.54% (97 runs sampled)
|
||||
|
||||
#13: short
|
||||
micromatch x 661,874 ops/sec ±0.42% (96 runs sampled)
|
||||
minimatch x 60,228 ops/sec ±0.45% (97 runs sampled)
|
||||
```
|
||||
|
||||
## Run tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/micromatch/issues/new)
|
||||
|
||||
Please be sure to run the benchmarks before/after any code changes to judge the impact before you do a PR. thanks!
|
||||
|
||||
## Related
|
||||
|
||||
* [braces](https://github.com/jonschlinkert/braces): Fastest brace expansion for node.js, with the most complete… [more](https://github.com/jonschlinkert/braces)
|
||||
* [extglob](https://github.com/jonschlinkert/extglob): Convert extended globs to regex-compatible strings. Add (almost) the… [more](https://github.com/jonschlinkert/extglob)
|
||||
* [expand-brackets](https://github.com/jonschlinkert/expand-brackets): Expand POSIX bracket expressions (character classes) in glob patterns.
|
||||
* [expand-range](https://github.com/jonschlinkert/expand-range): Fast, bash-like range expansion. Expand a range of numbers… [more](https://github.com/jonschlinkert/expand-range)
|
||||
* [fill-range](https://github.com/jonschlinkert/fill-range): Fill in a range of numbers or letters, optionally… [more](https://github.com/jonschlinkert/fill-range)
|
||||
* [gulp-micromatch](https://github.com/tunnckoCore/gulp-micromatch#readme): micromatch as gulp plugin. Filtering vinyl files with glob… [more](https://github.com/tunnckoCore/gulp-micromatch#readme)
|
||||
* [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a… [more](https://github.com/jonschlinkert/is-glob)
|
||||
* [parse-glob](https://github.com/jonschlinkert/parse-glob): Parse a glob pattern into an object of tokens.
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2014-2015 [Jon Schlinkert](https://github.com/jonschlinkert)
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on July 24, 2015._
|
||||
|
||||
<!-- deps:mocha browserify -->
|
||||
415
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/index.js
generated
vendored
Executable file
415
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/index.js
generated
vendored
Executable file
@@ -0,0 +1,415 @@
|
||||
/*!
|
||||
* micromatch <https://github.com/jonschlinkert/micromatch>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var diff = require('arr-diff');
|
||||
var typeOf = require('kind-of');
|
||||
var omit = require('object.omit');
|
||||
var unique = require('array-unique');
|
||||
var cache = require('regex-cache');
|
||||
var isGlob = require('is-glob');
|
||||
var expand = require('./lib/expand');
|
||||
var utils = require('./lib/utils');
|
||||
|
||||
/**
|
||||
* The main function. Pass an array of filepaths,
|
||||
* and a string or array of glob patterns
|
||||
*
|
||||
* @param {Array|String} `files`
|
||||
* @param {Array|String} `patterns`
|
||||
* @param {Object} `opts`
|
||||
* @return {Array} Array of matches
|
||||
*/
|
||||
|
||||
function micromatch(files, patterns, opts) {
|
||||
if (!files || !patterns) return [];
|
||||
opts = opts || {};
|
||||
|
||||
if (typeof opts.cache === 'undefined') {
|
||||
opts.cache = true;
|
||||
}
|
||||
|
||||
if (!Array.isArray(patterns)) {
|
||||
return match(files, patterns, opts);
|
||||
}
|
||||
|
||||
var len = patterns.length, i = 0;
|
||||
var omit = [], keep = [];
|
||||
|
||||
while (len--) {
|
||||
var glob = patterns[i++];
|
||||
if (glob.charCodeAt(0) === 33 /* ! */) {
|
||||
omit.push.apply(omit, match(files, glob.slice(1), opts));
|
||||
} else {
|
||||
keep.push.apply(keep, match(files, glob, opts));
|
||||
}
|
||||
}
|
||||
return diff(keep, omit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pass an array of files and a glob pattern as a string.
|
||||
*
|
||||
* This function is called by the main `micromatch` function
|
||||
* If you only need to pass a single pattern you might get
|
||||
* very minor speed improvements using this function.
|
||||
*
|
||||
* @param {Array} `files`
|
||||
* @param {Array} `pattern`
|
||||
* @param {Object} `options`
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
function match(files, pattern, opts) {
|
||||
if (typeOf(files) !== 'string' && !Array.isArray(files)) {
|
||||
throw new Error(msg('match', 'files', 'a string or array'));
|
||||
}
|
||||
|
||||
files = utils.arrayify(files);
|
||||
opts = opts || {};
|
||||
|
||||
var negate = opts.negate || false;
|
||||
var orig = pattern;
|
||||
|
||||
if (typeof pattern === 'string' && opts.nonegate !== true) {
|
||||
negate = pattern.charAt(0) === '!';
|
||||
if (negate) {
|
||||
pattern = pattern.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
var _isMatch = matcher(pattern, opts);
|
||||
var len = files.length, i = 0;
|
||||
var res = [];
|
||||
|
||||
while (i < len) {
|
||||
var file = files[i++];
|
||||
var fp = utils.unixify(file, opts);
|
||||
|
||||
if (!_isMatch(fp)) { continue; }
|
||||
res.push(fp);
|
||||
}
|
||||
|
||||
if (res.length === 0) {
|
||||
if (opts.failglob === true) {
|
||||
throw new Error('micromatch.match() found no matches for: "' + orig + '".');
|
||||
}
|
||||
|
||||
if (opts.nonull || opts.nullglob) {
|
||||
res.push(utils.unescapeGlob(orig));
|
||||
}
|
||||
}
|
||||
|
||||
// if `negate` was defined, diff negated files
|
||||
if (negate) { res = diff(files, res); }
|
||||
|
||||
// if `ignore` was defined, diff ignored filed
|
||||
if (opts.ignore && opts.ignore.length) {
|
||||
pattern = opts.ignore;
|
||||
opts = omit(opts, ['ignore']);
|
||||
res = diff(res, micromatch(res, pattern, opts));
|
||||
}
|
||||
|
||||
if (opts.nodupes) {
|
||||
return unique(res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a function that takes a glob pattern or array of glob patterns
|
||||
* to be used with `Array#filter()`. (Internally this function generates
|
||||
* the matching function using the [matcher] method).
|
||||
*
|
||||
* ```js
|
||||
* var fn = mm.filter('[a-c]');
|
||||
* ['a', 'b', 'c', 'd', 'e'].filter(fn);
|
||||
* //=> ['a', 'b', 'c']
|
||||
* ```
|
||||
*
|
||||
* @param {String|Array} `patterns` Can be a glob or array of globs.
|
||||
* @param {Options} `opts` Options to pass to the [matcher] method.
|
||||
* @return {Function} Filter function to be passed to `Array#filter()`.
|
||||
*/
|
||||
|
||||
function filter(patterns, opts) {
|
||||
if (!Array.isArray(patterns) && typeof patterns !== 'string') {
|
||||
throw new TypeError(msg('filter', 'patterns', 'a string or array'));
|
||||
}
|
||||
|
||||
patterns = utils.arrayify(patterns);
|
||||
return function (fp) {
|
||||
if (fp == null) return [];
|
||||
var len = patterns.length, i = 0;
|
||||
var res = true;
|
||||
|
||||
fp = utils.unixify(fp, opts);
|
||||
while (i < len) {
|
||||
var fn = matcher(patterns[i++], opts);
|
||||
if (!fn(fp)) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the filepath contains the given
|
||||
* pattern. Can also return a function for matching.
|
||||
*
|
||||
* ```js
|
||||
* isMatch('foo.md', '*.md', {});
|
||||
* //=> true
|
||||
*
|
||||
* isMatch('*.md', {})('foo.md')
|
||||
* //=> true
|
||||
* ```
|
||||
*
|
||||
* @param {String} `fp`
|
||||
* @param {String} `pattern`
|
||||
* @param {Object} `opts`
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
function isMatch(fp, pattern, opts) {
|
||||
if (typeof fp !== 'string') {
|
||||
throw new TypeError(msg('isMatch', 'filepath', 'a string'));
|
||||
}
|
||||
|
||||
fp = utils.unixify(fp, opts);
|
||||
if (typeOf(pattern) === 'object') {
|
||||
return matcher(fp, pattern);
|
||||
}
|
||||
return matcher(pattern, opts)(fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the filepath matches the
|
||||
* given pattern.
|
||||
*/
|
||||
|
||||
function contains(fp, pattern, opts) {
|
||||
if (typeof fp !== 'string') {
|
||||
throw new TypeError(msg('contains', 'pattern', 'a string'));
|
||||
}
|
||||
|
||||
opts = opts || {};
|
||||
opts.contains = (pattern !== '');
|
||||
fp = utils.unixify(fp, opts);
|
||||
|
||||
if (opts.contains && !isGlob(pattern)) {
|
||||
return fp.indexOf(pattern) !== -1;
|
||||
}
|
||||
return matcher(pattern, opts)(fp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if a file path matches any of the
|
||||
* given patterns.
|
||||
*
|
||||
* @param {String} `fp` The filepath to test.
|
||||
* @param {String|Array} `patterns` Glob patterns to use.
|
||||
* @param {Object} `opts` Options to pass to the `matcher()` function.
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function any(fp, patterns, opts) {
|
||||
if (!Array.isArray(patterns) && typeof patterns !== 'string') {
|
||||
throw new TypeError(msg('any', 'patterns', 'a string or array'));
|
||||
}
|
||||
|
||||
patterns = utils.arrayify(patterns);
|
||||
var len = patterns.length;
|
||||
|
||||
fp = utils.unixify(fp, opts);
|
||||
while (len--) {
|
||||
var isMatch = matcher(patterns[len], opts);
|
||||
if (isMatch(fp)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter the keys of an object with the given `glob` pattern
|
||||
* and `options`
|
||||
*
|
||||
* @param {Object} `object`
|
||||
* @param {Pattern} `object`
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
function matchKeys(obj, glob, options) {
|
||||
if (typeOf(obj) !== 'object') {
|
||||
throw new TypeError(msg('matchKeys', 'first argument', 'an object'));
|
||||
}
|
||||
|
||||
var fn = matcher(glob, options);
|
||||
var res = {};
|
||||
|
||||
for (var key in obj) {
|
||||
if (obj.hasOwnProperty(key) && fn(key)) {
|
||||
res[key] = obj[key];
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a function for matching based on the
|
||||
* given `pattern` and `options`.
|
||||
*
|
||||
* @param {String} `pattern`
|
||||
* @param {Object} `options`
|
||||
* @return {Function}
|
||||
*/
|
||||
|
||||
function matcher(pattern, opts) {
|
||||
// pattern is a function
|
||||
if (typeof pattern === 'function') {
|
||||
return pattern;
|
||||
}
|
||||
// pattern is a regex
|
||||
if (pattern instanceof RegExp) {
|
||||
return function(fp) {
|
||||
return pattern.test(fp);
|
||||
};
|
||||
}
|
||||
|
||||
// strings, all the way down...
|
||||
pattern = utils.unixify(pattern, opts);
|
||||
|
||||
// pattern is a non-glob string
|
||||
if (!isGlob(pattern)) {
|
||||
return utils.matchPath(pattern, opts);
|
||||
}
|
||||
// pattern is a glob string
|
||||
var re = makeRe(pattern, opts);
|
||||
|
||||
// `matchBase` is defined
|
||||
if (opts && opts.matchBase) {
|
||||
return utils.hasFilename(re, opts);
|
||||
}
|
||||
// `matchBase` is not defined
|
||||
return function(fp) {
|
||||
fp = utils.unixify(fp, opts);
|
||||
return re.test(fp);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and cache a regular expression for matching
|
||||
* file paths.
|
||||
*
|
||||
* If the leading character in the `glob` is `!`, a negation
|
||||
* regex is returned.
|
||||
*
|
||||
* @param {String} `glob`
|
||||
* @param {Object} `options`
|
||||
* @return {RegExp}
|
||||
*/
|
||||
|
||||
function toRegex(glob, options) {
|
||||
if (typeOf(glob) !== 'string') {
|
||||
throw new Error(msg('toRegex', 'glob', 'a string'));
|
||||
}
|
||||
|
||||
// clone options to prevent mutating the original object
|
||||
var opts = Object.create(options || {});
|
||||
var flags = opts.flags || '';
|
||||
if (opts.nocase && flags.indexOf('i') === -1) {
|
||||
flags += 'i';
|
||||
}
|
||||
|
||||
var parsed = expand(glob, opts);
|
||||
|
||||
// pass in tokens to avoid parsing more than once
|
||||
opts.negated = opts.negated || parsed.negated;
|
||||
opts.negate = opts.negated;
|
||||
glob = wrapGlob(parsed.pattern, opts);
|
||||
var re;
|
||||
|
||||
try {
|
||||
re = new RegExp(glob, flags);
|
||||
return re;
|
||||
} catch (err) {
|
||||
var msg = 'micromatch invalid regex: (' + re + ')';
|
||||
if (opts.strict) throw new SyntaxError(msg + err);
|
||||
}
|
||||
return /$^/;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the regex to do the matching. If the leading
|
||||
* character in the `glob` is `!` a negation regex is returned.
|
||||
*
|
||||
* @param {String} `glob`
|
||||
* @param {Boolean} `negate`
|
||||
*/
|
||||
|
||||
function wrapGlob(glob, opts) {
|
||||
var prefix = (opts && !opts.contains) ? '^' : '';
|
||||
var after = (opts && !opts.contains) ? '$' : '';
|
||||
glob = ('(?:' + glob + ')' + after);
|
||||
if (opts && opts.negate) {
|
||||
return prefix + ('(?!^' + glob + ').*$');
|
||||
}
|
||||
return prefix + glob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap `toRegex` to memoize the generated regex
|
||||
* the string and options don't change
|
||||
*/
|
||||
|
||||
function makeRe(glob, opts) {
|
||||
return cache(toRegex, glob, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make error messages consistent. Follows this format:
|
||||
*
|
||||
* ```js
|
||||
* msg(methodName, argNumber, nativeType);
|
||||
* // example:
|
||||
* msg('matchKeys', 'first', 'an object');
|
||||
* ```
|
||||
*
|
||||
* @param {String} `method`
|
||||
* @param {String} `num`
|
||||
* @param {String} `type`
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function msg(method, what, type) {
|
||||
return 'micromatch.' + method + '(): ' + what + ' should be ' + type + '.';
|
||||
}
|
||||
|
||||
/**
|
||||
* Public methods
|
||||
*/
|
||||
|
||||
micromatch.any = any;
|
||||
micromatch.braces = micromatch.braceExpand = require('braces');
|
||||
micromatch.contains = contains;
|
||||
micromatch.expand = expand;
|
||||
micromatch.filter = filter;
|
||||
micromatch.isMatch = isMatch;
|
||||
micromatch.makeRe = makeRe;
|
||||
micromatch.match = match;
|
||||
micromatch.matcher = matcher;
|
||||
micromatch.matchKeys = matchKeys;
|
||||
|
||||
/**
|
||||
* Expose `micromatch`
|
||||
*/
|
||||
|
||||
module.exports = micromatch;
|
||||
67
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/lib/chars.js
generated
vendored
Normal file
67
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/lib/chars.js
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
'use strict';
|
||||
|
||||
var reverse = function(object, prepender) {
|
||||
return Object.keys(object).reduce(function(reversed, key) {
|
||||
var newKey = prepender ? prepender + key : key; // Optionally prepend a string to key.
|
||||
reversed[object[key]] = newKey; // Swap key and value.
|
||||
return reversed; // Return the result.
|
||||
}, {});
|
||||
};
|
||||
|
||||
var chars = {};
|
||||
|
||||
/**
|
||||
* Regex for common characters
|
||||
*/
|
||||
|
||||
chars.escapeRegex = {
|
||||
'?': /\?/g,
|
||||
'@': /\@/g,
|
||||
'!': /\!/g,
|
||||
'+': /\+/g,
|
||||
'*': /\*/g,
|
||||
'(': /\(/g,
|
||||
')': /\)/g,
|
||||
'[': /\[/g,
|
||||
']': /\]/g,
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape characters
|
||||
*/
|
||||
|
||||
chars.ESC = {
|
||||
'?': '__UNESC_QMRK__',
|
||||
'@': '__UNESC_AMPE__',
|
||||
'!': '__UNESC_EXCL__',
|
||||
'+': '__UNESC_PLUS__',
|
||||
'*': '__UNESC_STAR__',
|
||||
',': '__UNESC_COMMA__',
|
||||
'(': '__UNESC_LTPAREN__',
|
||||
')': '__UNESC_RTPAREN__',
|
||||
'[': '__UNESC_LTBRACK__',
|
||||
']': '__UNESC_RTBRACK__',
|
||||
};
|
||||
|
||||
/**
|
||||
* Unescape characters
|
||||
*/
|
||||
|
||||
chars.UNESC = reverse(chars.ESC, '\\');
|
||||
|
||||
chars.ESC_TEMP = {
|
||||
'?': '__TEMP_QMRK__',
|
||||
'@': '__TEMP_AMPE__',
|
||||
'!': '__TEMP_EXCL__',
|
||||
'*': '__TEMP_STAR__',
|
||||
'+': '__TEMP_PLUS__',
|
||||
',': '__TEMP_COMMA__',
|
||||
'(': '__TEMP_LTPAREN__',
|
||||
')': '__TEMP_RTPAREN__',
|
||||
'[': '__TEMP_LTBRACK__',
|
||||
']': '__TEMP_RTBRACK__',
|
||||
};
|
||||
|
||||
chars.TEMP = reverse(chars.ESC_TEMP);
|
||||
|
||||
module.exports = chars;
|
||||
328
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/lib/expand.js
generated
vendored
Normal file
328
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/lib/expand.js
generated
vendored
Normal file
@@ -0,0 +1,328 @@
|
||||
/*!
|
||||
* micromatch <https://github.com/jonschlinkert/micromatch>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var utils = require('./utils');
|
||||
var Glob = require('./glob');
|
||||
|
||||
/**
|
||||
* Expose `expand`
|
||||
*/
|
||||
|
||||
module.exports = expand;
|
||||
|
||||
/**
|
||||
* Expand a glob pattern to resolve braces and
|
||||
* similar patterns before converting to regex.
|
||||
*
|
||||
* @param {String|Array} `pattern`
|
||||
* @param {Array} `files`
|
||||
* @param {Options} `opts`
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
function expand(pattern, options) {
|
||||
if (typeof pattern !== 'string') {
|
||||
throw new TypeError('micromatch.expand(): argument should be a string.');
|
||||
}
|
||||
|
||||
var glob = new Glob(pattern, options || {});
|
||||
var opts = glob.options;
|
||||
|
||||
if (typeof opts.braces !== 'boolean' && typeof opts.nobraces !== 'boolean') {
|
||||
opts.braces = true;
|
||||
}
|
||||
|
||||
// return early if glob pattern matches special patterns
|
||||
if (specialCase(pattern) && opts.safemode) {
|
||||
return new RegExp(utils.escapeRe(pattern), 'g');
|
||||
}
|
||||
|
||||
if (glob.pattern === '.*') {
|
||||
return {
|
||||
pattern: '\\.' + star,
|
||||
tokens: tok,
|
||||
options: opts
|
||||
};
|
||||
}
|
||||
|
||||
if (glob.pattern === '.') {
|
||||
return {
|
||||
pattern: '\\.',
|
||||
tokens: tok,
|
||||
options: opts
|
||||
};
|
||||
}
|
||||
|
||||
if (glob.pattern === '*') {
|
||||
return {
|
||||
pattern: oneStar(opts.dot),
|
||||
tokens: tok,
|
||||
options: opts
|
||||
};
|
||||
}
|
||||
|
||||
// parse the glob pattern into tokens
|
||||
glob.parse();
|
||||
var tok = glob.tokens;
|
||||
tok.is.negated = opts.negated;
|
||||
|
||||
// dotfile handling
|
||||
if ((opts.dotfiles === true || tok.is.dotfile) && opts.dot !== false) {
|
||||
opts.dotfiles = true;
|
||||
opts.dot = true;
|
||||
}
|
||||
|
||||
if ((opts.dotdirs === true || tok.is.dotdir) && opts.dot !== false) {
|
||||
opts.dotdirs = true;
|
||||
opts.dot = true;
|
||||
}
|
||||
|
||||
// check for braces with a dotfile pattern
|
||||
if (/[{,]\./.test(glob.pattern)) {
|
||||
opts.makeRe = false;
|
||||
opts.dot = true;
|
||||
}
|
||||
|
||||
if (opts.nonegate !== true) {
|
||||
opts.negated = glob.negated;
|
||||
}
|
||||
|
||||
// if the leading character is a dot or a slash, escape it
|
||||
if (glob.pattern.charAt(0) === '.' && glob.pattern.charAt(1) !== '/') {
|
||||
glob.pattern = '\\' + glob.pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extended globs
|
||||
*/
|
||||
|
||||
// expand brackets, e.g `[[:alpha:]]`
|
||||
glob.track('before brackets');
|
||||
if (tok.is.brackets) {
|
||||
glob.brackets();
|
||||
}
|
||||
glob.track('after brackets');
|
||||
|
||||
// expand braces, e.g `{1..5}`
|
||||
glob.track('before braces');
|
||||
if (tok.is.braces) {
|
||||
glob.braces();
|
||||
}
|
||||
glob.track('after braces');
|
||||
|
||||
// expand extglobs, e.g `foo/!(a|b)`
|
||||
glob.track('before extglob');
|
||||
if (tok.is.extglob) {
|
||||
glob.extglob();
|
||||
}
|
||||
glob.track('after extglob');
|
||||
|
||||
// special patterns
|
||||
glob._replace('[!', '[^');
|
||||
glob._replace('(?', '(%~');
|
||||
glob._replace('[]', '\\[\\]');
|
||||
glob._replace('/[', '/' + (opts.dot ? dotfiles : nodot) + '[', true);
|
||||
glob._replace('/?', '/' + (opts.dot ? dotfiles : nodot) + '[^/]', true);
|
||||
glob._replace('/.', '/(?=.)\\.', true);
|
||||
|
||||
// windows drives
|
||||
glob._replace(/^(\w):([\\\/]+?)/gi, '(?=.)$1:$2', true);
|
||||
|
||||
// negate slashes in exclusion ranges
|
||||
if (glob.pattern.indexOf('[^') !== -1) {
|
||||
glob.pattern = negateSlash(glob.pattern);
|
||||
}
|
||||
|
||||
if (opts.globstar !== false && glob.pattern === '**') {
|
||||
glob.pattern = globstar(opts.dot);
|
||||
|
||||
} else {
|
||||
// '/*/*/*' => '(?:/*){3}'
|
||||
glob._replace(/(\/\*)+/g, function (match) {
|
||||
var len = match.length / 2;
|
||||
if (len === 1) { return match; }
|
||||
return '(?:\\/*){' + len + '}';
|
||||
});
|
||||
|
||||
glob.pattern = balance(glob.pattern, '[', ']');
|
||||
glob.escape(glob.pattern);
|
||||
|
||||
// if the pattern has `**`
|
||||
if (tok.is.globstar) {
|
||||
glob.pattern = collapse(glob.pattern, '/**');
|
||||
glob.pattern = collapse(glob.pattern, '**/');
|
||||
glob._replace(/\*{2,}/g, '**');
|
||||
|
||||
// 'foo/*'
|
||||
glob._replace(/(\w+)\*(?!\/)/g, '$1[^/]*?', true);
|
||||
glob._replace(/\*\*\/\*(\w)/g, globstar(opts.dot) + '\\/' + (opts.dot ? dotfiles : nodot) + '[^/]*?$1', true);
|
||||
|
||||
if (opts.dot !== true) {
|
||||
glob._replace(/\*\*\/(.)/g, '(?:**\\/|)$1');
|
||||
}
|
||||
|
||||
// 'foo/**' or '{**,*}', but not 'foo**'
|
||||
if (tok.path.dirname !== '' || /,\*\*|\*\*,/.test(glob.orig)) {
|
||||
glob._replace('**', globstar(opts.dot), true);
|
||||
}
|
||||
}
|
||||
|
||||
// ends with /*
|
||||
glob._replace(/\/\*$/, '\\/' + oneStar(opts.dot), true);
|
||||
// ends with *, no slashes
|
||||
glob._replace(/(?!\/)\*$/, star, true);
|
||||
// has 'n*.' (partial wildcard w/ file extension)
|
||||
glob._replace(/([^\/]+)\*/, '$1' + oneStar(true), true);
|
||||
// has '*'
|
||||
glob._replace('*', oneStar(opts.dot), true);
|
||||
glob._replace('?.', '?\\.', true);
|
||||
glob._replace('?:', '?:', true);
|
||||
|
||||
glob._replace(/\?+/g, function (match) {
|
||||
var len = match.length;
|
||||
if (len === 1) {
|
||||
return qmark;
|
||||
}
|
||||
return qmark + '{' + len + '}';
|
||||
});
|
||||
|
||||
// escape '.abc' => '\\.abc'
|
||||
glob._replace(/\.([*\w]+)/g, '\\.$1');
|
||||
// fix '[^\\\\/]'
|
||||
glob._replace(/\[\^[\\\/]+\]/g, qmark);
|
||||
// '///' => '\/'
|
||||
glob._replace(/\/+/g, '\\/');
|
||||
// '\\\\\\' => '\\'
|
||||
glob._replace(/\\{2,}/g, '\\');
|
||||
}
|
||||
|
||||
// unescape previously escaped patterns
|
||||
glob.unescape(glob.pattern);
|
||||
glob._replace('__UNESC_STAR__', '*');
|
||||
|
||||
// escape dots that follow qmarks
|
||||
glob._replace('?.', '?\\.');
|
||||
|
||||
// remove unnecessary slashes in character classes
|
||||
glob._replace('[^\\/]', qmark);
|
||||
|
||||
if (glob.pattern.length > 1) {
|
||||
if (glob.pattern.indexOf('\\/') === 0 && glob.pattern.indexOf('\\/' + nodot) !== 0) {
|
||||
glob.pattern = '\\/' + nodot + glob.pattern.slice(2);
|
||||
} else if (/^[\[?*]/.test(glob.pattern)) {
|
||||
// only prepend the string if we don't want to match dotfiles
|
||||
glob.pattern = (opts.dot ? dotfiles : nodot) + glob.pattern;
|
||||
}
|
||||
}
|
||||
|
||||
return glob;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special cases. This is somewhat of a placeholder
|
||||
* for more advanced logic.
|
||||
*/
|
||||
|
||||
function specialCase(glob) {
|
||||
if (glob === '\\') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapse repeated character sequences.
|
||||
*
|
||||
* ```js
|
||||
* collapse('a/../../../b', '../');
|
||||
* //=> 'a/../b'
|
||||
* ```
|
||||
*
|
||||
* @param {String} `str`
|
||||
* @param {String} `ch` Character sequence to collapse
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function collapse(str, ch) {
|
||||
var res = str.split(ch);
|
||||
var isFirst = res[0] === '';
|
||||
var isLast = res[res.length - 1] === '';
|
||||
res = res.filter(Boolean);
|
||||
if (isFirst) res.unshift('');
|
||||
if (isLast) res.push('');
|
||||
return res.join(ch);
|
||||
}
|
||||
|
||||
/**
|
||||
* Negate slashes in exclusion ranges, per glob spec:
|
||||
*
|
||||
* ```js
|
||||
* negateSlash('[^foo]');
|
||||
* //=> '[^\\/foo]'
|
||||
* ```
|
||||
*
|
||||
* @param {String} `str` glob pattern
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function negateSlash(str) {
|
||||
return str.replace(/\[\^([^\]]*?)\]/g, function (match, inner) {
|
||||
if (inner.indexOf('/') === -1) {
|
||||
inner = '\\/' + inner;
|
||||
}
|
||||
return '[^' + inner + ']';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape imbalanced braces/bracket. This is a very
|
||||
* basic, naive implementation that only does enough
|
||||
* to serve the purpose.
|
||||
*/
|
||||
|
||||
function balance(str, a, b) {
|
||||
var aarr = str.split(a);
|
||||
var alen = aarr.join('').length;
|
||||
var blen = str.split(b).join('').length;
|
||||
|
||||
if (alen !== blen) {
|
||||
str = aarr.join('\\' + a);
|
||||
return str.split(b).join('\\' + b);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* Special patterns to be converted to regex.
|
||||
* Heuristics are used to simplify patterns
|
||||
* and speed up processing.
|
||||
*/
|
||||
|
||||
var qmark = '[^/]';
|
||||
var star = qmark + '*?';
|
||||
var nodot = '(?!\\.)(?=.)';
|
||||
var dotfileGlob = '(?:\\/|^)\\.{1,2}($|\\/)';
|
||||
var dotfiles = '(?!' + dotfileGlob + ')(?=.)';
|
||||
var twoStarDot = '(?:(?!' + dotfileGlob + ').)*?';
|
||||
|
||||
/**
|
||||
* Create a regex for `*`.
|
||||
*
|
||||
* If `dot` is true, or the pattern does not begin with
|
||||
* a leading star, then return the simpler regex.
|
||||
*/
|
||||
|
||||
function oneStar(dotfile) {
|
||||
return dotfile ? '(?!' + dotfileGlob + ')(?=.)' + star : (nodot + star);
|
||||
}
|
||||
|
||||
function globstar(dotfile) {
|
||||
if (dotfile) { return twoStarDot; }
|
||||
return '(?:(?!(?:\\/|^)\\.).)*?';
|
||||
}
|
||||
210
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/lib/glob.js
generated
vendored
Normal file
210
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/lib/glob.js
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
'use strict';
|
||||
|
||||
var braces = require('braces');
|
||||
var brackets = require('expand-brackets');
|
||||
var extglob = require('extglob');
|
||||
var parse = require('parse-glob');
|
||||
var chars = require('./chars');
|
||||
|
||||
/**
|
||||
* Expose `Glob`
|
||||
*/
|
||||
|
||||
module.exports = Glob;
|
||||
|
||||
function Glob(pattern, options) {
|
||||
this.options = options || {};
|
||||
this.pattern = pattern;
|
||||
this.history = [];
|
||||
this.tokens = {};
|
||||
this.init(pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize defaults
|
||||
*/
|
||||
|
||||
Glob.prototype.init = function(pattern) {
|
||||
this.orig = pattern;
|
||||
this.negated = this.isNegated();
|
||||
this.options.track = this.options.track || false;
|
||||
this.options.makeRe = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Push a change into `glob.history`. Useful
|
||||
* for debugging.
|
||||
*/
|
||||
|
||||
Glob.prototype.track = function(msg) {
|
||||
if (this.options.track) {
|
||||
this.history.push({msg: msg, pattern: this.pattern});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true if the glob pattern has the given
|
||||
* `ch`aracter.
|
||||
*
|
||||
* @param {String} `pattern`
|
||||
* @param {String} `ch`
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
Glob.prototype.has = function(pattern, ch) {
|
||||
if (ch instanceof RegExp) {
|
||||
return ch.test(pattern);
|
||||
}
|
||||
return pattern.indexOf(ch) !== -1;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return true if `glob.pattern` was negated
|
||||
* with `!`. Also removes the `!` from the pattern.
|
||||
*
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
Glob.prototype.isNegated = function() {
|
||||
if (this.tokens.isNegated) return true;
|
||||
if (this.pattern.charCodeAt(0) === 33 /* '!' */) {
|
||||
this.pattern = this.pattern.slice(1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Expand braces in the given glob pattern.
|
||||
*
|
||||
* We only need to use the [braces] lib when
|
||||
* patterns are nested.
|
||||
*/
|
||||
|
||||
Glob.prototype.braces = function() {
|
||||
if (this.options.nobraces !== true && this.options.nobrace !== true) {
|
||||
// naive/fast check for imbalanced characters
|
||||
var a = this.pattern.match(/[\{\(\[]/g);
|
||||
var b = this.pattern.match(/[\}\)\]]/g);
|
||||
|
||||
// if imbalanced, don't optimize the pattern
|
||||
if (a && b && (a.length !== b.length)) {
|
||||
this.options.makeRe = false;
|
||||
}
|
||||
|
||||
// expand brace patterns and join the resulting array
|
||||
var expanded = braces(this.pattern, this.options);
|
||||
this.pattern = expanded.join('|');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Expand bracket expressions in `glob.pattern`
|
||||
*/
|
||||
|
||||
Glob.prototype.brackets = function() {
|
||||
if (this.options.nobrackets !== true) {
|
||||
this.pattern = brackets(this.pattern);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Expand bracket expressions in `glob.pattern`
|
||||
*/
|
||||
|
||||
Glob.prototype.extglob = function() {
|
||||
if (this.options.noextglob !== true) {
|
||||
this.pattern = extglob(this.pattern, {escape: true});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the given glob `pattern` or `glob.pattern`
|
||||
*/
|
||||
|
||||
Glob.prototype.parse = function(pattern) {
|
||||
this.tokens = parse(pattern || this.pattern, true);
|
||||
return this.tokens;
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace `a` with `b`. Also tracks the change before and
|
||||
* after each replacement. This is disabled by default, but
|
||||
* can be enabled by setting `options.track` to true.
|
||||
*
|
||||
* Also, when the pattern is a string, `.split()` is used,
|
||||
* because it's much faster than replace.
|
||||
*
|
||||
* @param {RegExp|String} `a`
|
||||
* @param {String} `b`
|
||||
* @param {Boolean} `escape` When `true`, escapes `*` and `?` in the replacement.
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
Glob.prototype._replace = function(a, b, escape) {
|
||||
this.track('before (find): "' + a + '" (replace with): "' + b + '"');
|
||||
if (escape) b = esc(b);
|
||||
if (a && b && typeof a === 'string') {
|
||||
this.pattern = this.pattern.split(a).join(b);
|
||||
} else if (a instanceof RegExp) {
|
||||
this.pattern = this.pattern.replace(a, b);
|
||||
}
|
||||
this.track('after');
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape special characters in the given string.
|
||||
*
|
||||
* @param {String} `str` Glob pattern
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
Glob.prototype.escape = function(str) {
|
||||
this.track('before escape: ');
|
||||
var re = /["\\](['"]?[^"'\\]['"]?)/g;
|
||||
|
||||
this.pattern = str.replace(re, function($0, $1) {
|
||||
var o = chars.ESC;
|
||||
var ch = o && o[$1];
|
||||
if (ch) {
|
||||
return ch;
|
||||
}
|
||||
if (/[a-z]/i.test($0)) {
|
||||
return $0.split('\\').join('');
|
||||
}
|
||||
return $0;
|
||||
});
|
||||
|
||||
this.track('after escape: ');
|
||||
};
|
||||
|
||||
/**
|
||||
* Unescape special characters in the given string.
|
||||
*
|
||||
* @param {String} `str`
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
Glob.prototype.unescape = function(str) {
|
||||
var re = /__([A-Z]+)_([A-Z]+)__/g;
|
||||
this.pattern = str.replace(re, function($0, $1) {
|
||||
return chars[$1][$0];
|
||||
});
|
||||
this.pattern = unesc(this.pattern);
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape/unescape utils
|
||||
*/
|
||||
|
||||
function esc(str) {
|
||||
str = str.split('?').join('%~');
|
||||
str = str.split('*').join('%%');
|
||||
return str;
|
||||
}
|
||||
|
||||
function unesc(str) {
|
||||
str = str.split('%~').join('?');
|
||||
str = str.split('%%').join('*');
|
||||
return str;
|
||||
}
|
||||
88
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/lib/utils.js
generated
vendored
Normal file
88
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/lib/utils.js
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
'use strict';
|
||||
|
||||
var path = require('path');
|
||||
var fileRe = require('filename-regex');
|
||||
var win32 = process && process.platform === 'win32';
|
||||
|
||||
/**
|
||||
* Expose `utils`
|
||||
*/
|
||||
|
||||
var utils = module.exports;
|
||||
|
||||
|
||||
utils.filename = function filename(fp) {
|
||||
var seg = fp.match(fileRe());
|
||||
return seg && seg[0];
|
||||
};
|
||||
|
||||
utils.isPath = function isPath(pattern, opts) {
|
||||
return function (fp) {
|
||||
return utils.unixify(fp, opts) === pattern;
|
||||
};
|
||||
};
|
||||
|
||||
utils.hasPath = function hasPath(pattern, opts) {
|
||||
return function (fp) {
|
||||
return utils.unixify(fp, opts).indexOf(pattern) !== -1;
|
||||
};
|
||||
};
|
||||
|
||||
utils.matchPath = function matchPath(pattern, opts) {
|
||||
var fn = (opts && opts.contains)
|
||||
? utils.hasPath(pattern, opts)
|
||||
: utils.isPath(pattern, opts);
|
||||
return fn;
|
||||
};
|
||||
|
||||
utils.hasFilename = function hasFilename(re) {
|
||||
return function (fp) {
|
||||
var name = utils.filename(fp);
|
||||
return name && re.test(name);
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Coerce `val` to an array
|
||||
*
|
||||
* @param {*} val
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
utils.arrayify = function arrayify(val) {
|
||||
return !Array.isArray(val)
|
||||
? [val]
|
||||
: val;
|
||||
};
|
||||
|
||||
/**
|
||||
* Normalize all slashes in a file path or glob pattern to
|
||||
* forward slashes.
|
||||
*/
|
||||
|
||||
utils.unixify = function unixify(fp, opts) {
|
||||
if (opts && opts.unixify === false) return fp;
|
||||
if (opts && opts.unixify === true || win32 || path.sep === '\\') {
|
||||
return fp.split('\\').join('/');
|
||||
}
|
||||
if (opts && opts.unescape === true) {
|
||||
return fp ? fp.toString().replace(/\\(\w)/g, '$1') : '';
|
||||
}
|
||||
return fp;
|
||||
};
|
||||
|
||||
/**
|
||||
* Escape/unescape utils
|
||||
*/
|
||||
|
||||
utils.escapePath = function escapePath(fp) {
|
||||
return fp.replace(/[\\.]/g, '\\$&');
|
||||
};
|
||||
|
||||
utils.unescapeGlob = function unescapeGlob(fp) {
|
||||
return fp.replace(/[\\"']/g, '');
|
||||
};
|
||||
|
||||
utils.escapeRe = function escapeRe(str) {
|
||||
return str.replace(/[-[\\$*+?.#^\s{}(|)\]]/g, '\\$&');
|
||||
};
|
||||
24
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/arr-diff/LICENSE
generated
vendored
Executable file
24
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/arr-diff/LICENSE
generated
vendored
Executable file
@@ -0,0 +1,24 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015 Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
75
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/arr-diff/README.md
generated
vendored
Executable file
75
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/arr-diff/README.md
generated
vendored
Executable file
@@ -0,0 +1,75 @@
|
||||
# arr-diff [](http://badge.fury.io/js/arr-diff) [](https://travis-ci.org/jonschlinkert/arr-diff)
|
||||
|
||||
> Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i arr-diff --save
|
||||
```
|
||||
|
||||
Install with [bower](http://bower.io/)
|
||||
|
||||
```sh
|
||||
$ bower install arr-diff --save
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### [diff](index.js#L33)
|
||||
|
||||
Return the difference between the first array and additional arrays.
|
||||
|
||||
**Params**
|
||||
|
||||
* `a` **{Array}**
|
||||
* `b` **{Array}**
|
||||
* `returns` **{Array}**
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
var diff = require('arr-diff');
|
||||
|
||||
var a = ['a', 'b', 'c', 'd'];
|
||||
var b = ['b', 'c'];
|
||||
|
||||
console.log(diff(a, b))
|
||||
//=> ['a', 'd']
|
||||
```
|
||||
|
||||
## Related projects
|
||||
|
||||
* [arr-flatten](https://www.npmjs.com/package/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten. | [homepage](https://github.com/jonschlinkert/arr-flatten)
|
||||
* [array-filter](https://www.npmjs.com/package/array-filter): Array#filter for older browsers. | [homepage](https://github.com/juliangruber/array-filter)
|
||||
* [array-intersection](https://www.npmjs.com/package/array-intersection): Return an array with the unique values present in _all_ given arrays using strict equality… [more](https://www.npmjs.com/package/array-intersection) | [homepage](https://github.com/jonschlinkert/array-intersection)
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/arr-diff/issues/new).
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2015 Jon Schlinkert
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on August 23, 2015._
|
||||
58
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/arr-diff/index.js
generated
vendored
Executable file
58
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/arr-diff/index.js
generated
vendored
Executable file
@@ -0,0 +1,58 @@
|
||||
/*!
|
||||
* arr-diff <https://github.com/jonschlinkert/arr-diff>
|
||||
*
|
||||
* Copyright (c) 2014 Jon Schlinkert, contributors.
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var flatten = require('arr-flatten');
|
||||
var slice = require('array-slice');
|
||||
|
||||
/**
|
||||
* Return the difference between the first array and
|
||||
* additional arrays.
|
||||
*
|
||||
* ```js
|
||||
* var diff = require('{%= name %}');
|
||||
*
|
||||
* var a = ['a', 'b', 'c', 'd'];
|
||||
* var b = ['b', 'c'];
|
||||
*
|
||||
* console.log(diff(a, b))
|
||||
* //=> ['a', 'd']
|
||||
* ```
|
||||
*
|
||||
* @param {Array} `a`
|
||||
* @param {Array} `b`
|
||||
* @return {Array}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function diff(arr, arrays) {
|
||||
var argsLen = arguments.length;
|
||||
var len = arr.length, i = -1;
|
||||
var res = [], arrays;
|
||||
|
||||
if (argsLen === 1) {
|
||||
return arr;
|
||||
}
|
||||
|
||||
if (argsLen > 2) {
|
||||
arrays = flatten(slice(arguments, 1));
|
||||
}
|
||||
|
||||
while (++i < len) {
|
||||
if (!~arrays.indexOf(arr[i])) {
|
||||
res.push(arr[i]);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose `diff`
|
||||
*/
|
||||
|
||||
module.exports = diff;
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,73 @@
|
||||
# arr-flatten [](http://badge.fury.io/js/arr-flatten) [](https://travis-ci.org/jonschlinkert/arr-flatten)
|
||||
|
||||
> Recursively flatten an array or arrays. This is the fastest implementation of array flatten.
|
||||
|
||||
Why another flatten utility? I wanted the fastest implementation I could find, with implementation choices that should work for 95% of use cases, but no cruft to cover the other 5%.
|
||||
|
||||
## Run benchmarks
|
||||
|
||||
```bash
|
||||
npm run benchmarks
|
||||
```
|
||||
|
||||
Benchmark results comparing this library to [array-flatten]:
|
||||
|
||||
```bash
|
||||
#1: large.js
|
||||
arr-flatten.js x 487,030 ops/sec ±0.67% (92 runs sampled)
|
||||
array-flatten.js x 347,020 ops/sec ±0.57% (98 runs sampled)
|
||||
|
||||
#2: medium.js
|
||||
arr-flatten.js x 1,914,516 ops/sec ±0.76% (94 runs sampled)
|
||||
array-flatten.js x 1,391,661 ops/sec ±0.63% (96 runs sampled)
|
||||
|
||||
#3: small.js
|
||||
arr-flatten.js x 5,158,980 ops/sec ±0.85% (94 runs sampled)
|
||||
array-flatten.js x 3,683,173 ops/sec ±0.79% (97 runs sampled)
|
||||
```
|
||||
|
||||
## Run tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i arr-flatten --save
|
||||
```
|
||||
### Install with [bower](https://github.com/bower/bower)
|
||||
|
||||
```bash
|
||||
bower install arr-flatten --save
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var flatten = require('arr-flatten');
|
||||
|
||||
flatten(['a', ['b', ['c']], 'd', ['e']]);
|
||||
//=> ['a', 'b', 'c', 'd', 'e']
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2014-2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 11, 2015._
|
||||
|
||||
[array-flatten]: https://github.com/blakeembrey/array-flatten
|
||||
@@ -0,0 +1,27 @@
|
||||
/*!
|
||||
* arr-flatten <https://github.com/jonschlinkert/arr-flatten>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function flatten(arr) {
|
||||
return flat(arr, []);
|
||||
};
|
||||
|
||||
function flat(arr, res) {
|
||||
var len = arr.length;
|
||||
var i = -1;
|
||||
|
||||
while (len--) {
|
||||
var cur = arr[++i];
|
||||
if (Array.isArray(cur)) {
|
||||
flat(cur, res);
|
||||
} else {
|
||||
res.push(cur);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"name": "arr-flatten",
|
||||
"description": "Recursively flatten an array or arrays. This is the fastest implementation of array flatten.",
|
||||
"version": "1.0.1",
|
||||
"homepage": "https://github.com/jonschlinkert/arr-flatten",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/arr-flatten.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/arr-flatten/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/arr-flatten/blob/master/LICENSE"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha",
|
||||
"benchmarks": "node benchmark"
|
||||
},
|
||||
"devDependencies": {
|
||||
"array-flatten": "^1.0.2",
|
||||
"array-slice": "^0.2.2",
|
||||
"benchmarked": "^0.1.3",
|
||||
"chalk": "^0.5.1",
|
||||
"glob": "^4.3.5",
|
||||
"kind-of": "^1.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
"arr",
|
||||
"array",
|
||||
"elements",
|
||||
"flat",
|
||||
"flatten",
|
||||
"nested",
|
||||
"recurse",
|
||||
"recursive",
|
||||
"recursively"
|
||||
],
|
||||
"gitHead": "7b3706eaa0093d8f5ba65af8ed590b6fcb3fe7cf",
|
||||
"_id": "arr-flatten@1.0.1",
|
||||
"_shasum": "e5ffe54d45e19f32f216e91eb99c8ce892bb604b",
|
||||
"_from": "arr-flatten@>=1.0.1 <2.0.0",
|
||||
"_npmVersion": "2.5.1",
|
||||
"_nodeVersion": "0.12.0",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "e5ffe54d45e19f32f216e91eb99c8ce892bb604b",
|
||||
"tarball": "http://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.0.1.tgz"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.Copyright (c) 2012-2015, The Dojo Foundation.copyright (c) 2009-2015, Jeremy Ashkenas.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,54 @@
|
||||
# array-slice [](http://badge.fury.io/js/array-slice) [](https://travis-ci.org/jonschlinkert/array-slice)
|
||||
|
||||
> Array-slice method. Slices `array` from the `start` index up to, but not including, the `end` index.
|
||||
|
||||
This function is used instead of `Array#slice` to support node lists in IE < 9 and to ensure dense arrays are returned.
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i array-slice --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var slice = require('array-slice');
|
||||
var arr = ['a', 'b', 'd', 'e', 'f', 'g', 'h', 'i', 'j'];
|
||||
|
||||
slice(arr, 3, 6);
|
||||
//=> ['e', 'f', 'g']
|
||||
```
|
||||
|
||||
## Useful array utils
|
||||
* [arr-diff](https://github.com/jonschlinkert/arr-diff): Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.
|
||||
* [arr-filter](https://github.com/jonschlinkert/arr-filter): Faster alternative to javascript's native filter method.
|
||||
* [arr-flatten](https://github.com/jonschlinkert/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten.
|
||||
* [arr-union](https://github.com/jonschlinkert/arr-union): Combines a list of arrays, returning a single array with unique values, using strict equality for comparisons.
|
||||
* [array-unique](https://github.com/jonschlinkert/array-unique): Return an array free of duplicate values. Fastest ES5 implementation.
|
||||
* [array-intersection](https://github.com/jonschlinkert/array-intersection): Return an array with the unique values present in _all_ given arrays using strict equality for comparisons.
|
||||
|
||||
## Running tests
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/array-slice/issues)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on April 07, 2015._
|
||||
@@ -0,0 +1,36 @@
|
||||
/*!
|
||||
* array-slice <https://github.com/jonschlinkert/array-slice>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function slice(arr, start, end) {
|
||||
var len = arr.length >>> 0;
|
||||
var range = [];
|
||||
|
||||
start = idx(arr, start);
|
||||
end = idx(arr, end, len);
|
||||
|
||||
while (start < end) {
|
||||
range.push(arr[start++]);
|
||||
}
|
||||
return range;
|
||||
};
|
||||
|
||||
|
||||
function idx(arr, pos, end) {
|
||||
var len = arr.length >>> 0;
|
||||
|
||||
if (pos == null) {
|
||||
pos = end || 0;
|
||||
} else if (pos < 0) {
|
||||
pos = Math.max(len + pos, 0);
|
||||
} else {
|
||||
pos = Math.min(pos, len);
|
||||
}
|
||||
|
||||
return pos;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "array-slice",
|
||||
"description": "Array-slice method. Slices `array` from the `start` index up to, but not including, the `end` index.",
|
||||
"version": "0.2.3",
|
||||
"homepage": "https://github.com/jonschlinkert/array-slice",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/array-slice.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/array-slice/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/array-slice/blob/master/LICENSE"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "*",
|
||||
"should": "^5.2.0"
|
||||
},
|
||||
"keywords": [
|
||||
"array",
|
||||
"javascript",
|
||||
"js",
|
||||
"slice",
|
||||
"util",
|
||||
"utils"
|
||||
],
|
||||
"gitHead": "15bcb1d3d2d5689a1f519207cecb3ab3a63b8654",
|
||||
"_id": "array-slice@0.2.3",
|
||||
"_shasum": "dd3cfb80ed7973a75117cdac69b0b99ec86186f5",
|
||||
"_from": "array-slice@>=0.2.3 <0.3.0",
|
||||
"_npmVersion": "2.5.1",
|
||||
"_nodeVersion": "0.12.0",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "dd3cfb80ed7973a75117cdac69b0b99ec86186f5",
|
||||
"tarball": "http://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz"
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"name": "arr-diff",
|
||||
"description": "Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.",
|
||||
"version": "1.1.0",
|
||||
"homepage": "https://github.com/jonschlinkert/arr-diff",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/arr-diff.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/arr-diff/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"dependencies": {
|
||||
"arr-flatten": "^1.0.1",
|
||||
"array-slice": "^0.2.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"array-differ": "^1.0.0",
|
||||
"benchmarked": "^0.1.4",
|
||||
"chalk": "^1.1.1",
|
||||
"mocha": "^2.2.5",
|
||||
"should": "^7.0.4"
|
||||
},
|
||||
"keywords": [
|
||||
"arr",
|
||||
"array",
|
||||
"diff",
|
||||
"differ",
|
||||
"difference"
|
||||
],
|
||||
"verb": {
|
||||
"related": {
|
||||
"list": [
|
||||
"arr-flatten",
|
||||
"array-filter",
|
||||
"array-intersection"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gitHead": "a749b8f9a21dae711050a14e580860abe7299a01",
|
||||
"_id": "arr-diff@1.1.0",
|
||||
"_shasum": "687c32758163588fef7de7b36fabe495eb1a399a",
|
||||
"_from": "arr-diff@>=1.0.1 <2.0.0",
|
||||
"_npmVersion": "2.10.1",
|
||||
"_nodeVersion": "0.12.4",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "687c32758163588fef7de7b36fabe495eb1a399a",
|
||||
"tarball": "http://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-1.1.0.tgz"
|
||||
}
|
||||
21
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/array-unique/LICENSE
generated
vendored
Executable file
21
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/array-unique/LICENSE
generated
vendored
Executable file
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,51 @@
|
||||
# array-unique [](http://badge.fury.io/js/array-unique) [](https://travis-ci.org/jonschlinkert/array-unique)
|
||||
|
||||
> Return an array free of duplicate values. Fastest ES5 implementation.
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i array-unique --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var unique = require('array-unique');
|
||||
|
||||
unique(['a', 'b', 'c', 'c']);
|
||||
//=> ['a', 'b', 'c']
|
||||
```
|
||||
|
||||
## Related
|
||||
* [arr-diff](https://github.com/jonschlinkert/arr-diff): Returns an array with only the unique values from the first array, by excluding all values from additional arrays using strict equality for comparisons.
|
||||
* [arr-union](https://github.com/jonschlinkert/arr-union): Returns an array of unique values using strict equality for comparisons.
|
||||
* [arr-flatten](https://github.com/jonschlinkert/arr-flatten): Recursively flatten an array or arrays. This is the fastest implementation of array flatten.
|
||||
* [arr-reduce](https://github.com/jonschlinkert/arr-reduce): Fast array reduce that also loops over sparse elements.
|
||||
* [arr-map](https://github.com/jonschlinkert/arr-map): Faster, node.js focused alternative to JavaScript's native array map.
|
||||
* [arr-pluck](https://github.com/jonschlinkert/arr-pluck): Retrieves the value of a specified property from all elements in the collection.
|
||||
|
||||
## Run tests
|
||||
Install dev dependencies.
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/array-unique/issues)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 24, 2015._
|
||||
28
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/array-unique/index.js
generated
vendored
Executable file
28
node_modules/forever/node_modules/forever-monitor/node_modules/chokidar/node_modules/anymatch/node_modules/micromatch/node_modules/array-unique/index.js
generated
vendored
Executable file
@@ -0,0 +1,28 @@
|
||||
/*!
|
||||
* array-unique <https://github.com/jonschlinkert/array-unique>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function unique(arr) {
|
||||
if (!Array.isArray(arr)) {
|
||||
throw new TypeError('array-unique expects an array.');
|
||||
}
|
||||
|
||||
var len = arr.length;
|
||||
var i = -1;
|
||||
|
||||
while (i++ < len) {
|
||||
var j = i + 1;
|
||||
|
||||
for (; j < arr.length; ++j) {
|
||||
if (arr[i] === arr[j]) {
|
||||
arr.splice(j--, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
};
|
||||
@@ -0,0 +1,59 @@
|
||||
{
|
||||
"name": "array-unique",
|
||||
"description": "Return an array free of duplicate values. Fastest ES5 implementation.",
|
||||
"version": "0.2.1",
|
||||
"homepage": "https://github.com/jonschlinkert/array-unique",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/array-unique.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/array-unique/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/array-unique/blob/master/LICENSE"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"array-uniq": "^1.0.2",
|
||||
"benchmarked": "^0.1.3",
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
},
|
||||
"gitHead": "36fde8e586fb7cf880b8b3aa6515df889e64ed85",
|
||||
"_id": "array-unique@0.2.1",
|
||||
"_shasum": "a1d97ccafcbc2625cc70fadceb36a50c58b01a53",
|
||||
"_from": "array-unique@>=0.2.1 <0.3.0",
|
||||
"_npmVersion": "2.7.1",
|
||||
"_nodeVersion": "1.6.2",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "a1d97ccafcbc2625cc70fadceb36a50c58b01a53",
|
||||
"tarball": "http://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,242 @@
|
||||
# braces [](http://badge.fury.io/js/braces)
|
||||
|
||||
> Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.
|
||||
|
||||
- Complete support for the braces part of the [Bash 4.3 specification][bash]. Braces passes [all of the relevant unit tests](#bash-4-3-support) from the spec.
|
||||
- Expands comma-separated values: `a/{b,c}/d` => `['a/b/d', 'a/c/d']`
|
||||
- Expands alphabetical or numerical ranges: `{1..3}` => `['1', '2', '3']`
|
||||
- [Very fast](#benchmarks)
|
||||
- [Special characters](./patterns.md) can be used to generate interesting patterns.
|
||||
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i braces --save
|
||||
```
|
||||
|
||||
|
||||
## Example usage
|
||||
|
||||
```js
|
||||
var braces = require('braces');
|
||||
|
||||
braces('a/{x,y}/c{d}e')
|
||||
//=> ['a/x/cde', 'a/y/cde']
|
||||
|
||||
braces('a/b/c/{x,y}')
|
||||
//=> ['a/b/c/x', 'a/b/c/y']
|
||||
|
||||
braces('a/{x,{1..5},y}/c{d}e')
|
||||
//=> ['a/x/cde', 'a/1/cde', 'a/y/cde', 'a/2/cde', 'a/3/cde', 'a/4/cde', 'a/5/cde']
|
||||
```
|
||||
|
||||
### Pro tip!
|
||||
|
||||
> Use braces to generate test fixtures!
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
var braces = require('./');
|
||||
var path = require('path');
|
||||
var fs = require('fs');
|
||||
|
||||
braces('blah/{a..z}.js').forEach(function(fp) {
|
||||
if (!fs.existsSync(path.dirname(fp))) {
|
||||
fs.mkdirSync(path.dirname(fp));
|
||||
}
|
||||
fs.writeFileSync(fp, '');
|
||||
});
|
||||
```
|
||||
|
||||
See the [tests](./test/test.js) for more examples and use cases (also see the [bash spec tests](./test/bash-mm-adjusted.js));
|
||||
|
||||
|
||||
### Range expansion
|
||||
|
||||
Uses [expand-range](https://github.com/jonschlinkert/expand-range) for range expansion.
|
||||
|
||||
```js
|
||||
braces('a{1..3}b')
|
||||
//=> ['a1b', 'a2b', 'a3b']
|
||||
|
||||
braces('a{5..8}b')
|
||||
//=> ['a5b', 'a6b', 'a7b', 'a8b']
|
||||
|
||||
braces('a{00..05}b')
|
||||
//=> ['a00b', 'a01b', 'a02b', 'a03b', 'a04b', 'a05b']
|
||||
|
||||
braces('a{01..03}b')
|
||||
//=> ['a01b', 'a02b', 'a03b']
|
||||
|
||||
braces('a{000..005}b')
|
||||
//=> ['a000b', 'a001b', 'a002b', 'a003b', 'a004b', 'a005b']
|
||||
|
||||
braces('a{a..e}b')
|
||||
//=> ['aab', 'abb', 'acb', 'adb', 'aeb']
|
||||
|
||||
braces('a{A..E}b')
|
||||
//=> ['aAb', 'aBb', 'aCb', 'aDb', 'aEb']
|
||||
```
|
||||
|
||||
Pass a function as the last argument to customize range expansions:
|
||||
|
||||
```js
|
||||
var range = braces('x{a..e}y', function (str, i) {
|
||||
return String.fromCharCode(str) + i;
|
||||
});
|
||||
|
||||
console.log(range);
|
||||
//=> ['xa0y', 'xb1y', 'xc2y', 'xd3y', 'xe4y']
|
||||
```
|
||||
|
||||
See [expand-range] for benchmarks, tests and the full list of range expansion features.
|
||||
|
||||
## Options
|
||||
|
||||
### options.makeRe
|
||||
|
||||
Type: `Boolean`
|
||||
|
||||
Deafault: `false`
|
||||
|
||||
Return a regex-optimal string. If you're using braces to generate regex, this will result in dramatically faster performance.
|
||||
|
||||
**Examples**
|
||||
|
||||
With the default settings (`{makeRe: false}`):
|
||||
|
||||
```js
|
||||
braces('{1..5}');
|
||||
//=> ['1', '2', '3', '4', '5']
|
||||
```
|
||||
|
||||
With `{makeRe: true}`:
|
||||
|
||||
```js
|
||||
braces('{1..5}', {makeRe: true});
|
||||
//=> ['[1-5]']
|
||||
|
||||
braces('{3..9..3}', {makeRe: true});
|
||||
//=> ['(3|6|9)']
|
||||
```
|
||||
|
||||
### options.bash
|
||||
|
||||
Type: `Boolean`
|
||||
|
||||
Default: `false`
|
||||
|
||||
Enables complete support for the Bash specification. The downside is a 20-25% speed decrease.
|
||||
|
||||
**Example**
|
||||
|
||||
Using the default setting (`{bash: false}`):
|
||||
|
||||
```js
|
||||
braces('a{b}c');
|
||||
//=> ['abc']
|
||||
```
|
||||
|
||||
In bash (and minimatch), braces with one item are not expanded. To get the same result with braces, set `{bash: true}`:
|
||||
|
||||
```js
|
||||
braces('a{b}c', {bash: true});
|
||||
//=> ['a{b}c']
|
||||
```
|
||||
|
||||
### options.nodupes
|
||||
|
||||
Type: `Boolean`
|
||||
|
||||
Deafault: `true`
|
||||
|
||||
Duplicates are removed by default. To keep duplicates, pass `{nodupes: false}` on the options
|
||||
|
||||
|
||||
|
||||
## Bash 4.3 Support
|
||||
|
||||
> Better support for Bash 4.3 than minimatch
|
||||
|
||||
This project has comprehensive unit tests, including tests coverted from [Bash 4.3][bash]. Currently only 8 of 102 unit tests fail, and
|
||||
|
||||
|
||||
## Run benchmarks
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm benchmark
|
||||
```
|
||||
|
||||
|
||||
```bash
|
||||
#1: escape.js
|
||||
brace-expansion.js x 114,934 ops/sec ±1.24% (93 runs sampled)
|
||||
braces.js x 342,254 ops/sec ±0.84% (90 runs sampled)
|
||||
|
||||
#2: exponent.js
|
||||
brace-expansion.js x 12,359 ops/sec ±0.86% (96 runs sampled)
|
||||
braces.js x 20,389 ops/sec ±0.71% (97 runs sampled)
|
||||
|
||||
#3: multiple.js
|
||||
brace-expansion.js x 114,469 ops/sec ±1.44% (94 runs sampled)
|
||||
braces.js x 401,621 ops/sec ±0.87% (91 runs sampled)
|
||||
|
||||
#4: nested.js
|
||||
brace-expansion.js x 102,769 ops/sec ±1.55% (92 runs sampled)
|
||||
braces.js x 314,088 ops/sec ±0.71% (98 runs sampled)
|
||||
|
||||
#5: normal.js
|
||||
brace-expansion.js x 157,577 ops/sec ±1.65% (91 runs sampled)
|
||||
braces.js x 1,115,950 ops/sec ±0.74% (94 runs sampled)
|
||||
|
||||
#6: range.js
|
||||
brace-expansion.js x 138,822 ops/sec ±1.71% (91 runs sampled)
|
||||
braces.js x 1,108,353 ops/sec ±0.85% (94 runs sampled)
|
||||
```
|
||||
|
||||
|
||||
## Run tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [micromatch]: wildcard/glob matcher for javascript. a faster alternative to minimatch.
|
||||
- [fill-range]: Fill in a range of numbers or letters, optionally passing an increment or multiplier to use
|
||||
- [expand-range]: Wraps fill-range for fast, bash-like range expansion in strings. Expand a range of numbers or letters, uppercase or lowercase
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/braces/issues).
|
||||
|
||||
Please run benchmarks before and after any code changes to what the impact of the code changes are before submitting a PR.
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2014-2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 18, 2015._
|
||||
|
||||
[bash]: www.gnu.org/software/bash/
|
||||
[braces]: https://github.com/jonschlinkert/braces
|
||||
[expand-range]: https://github.com/jonschlinkert/expand-range
|
||||
[fill-range]: https://github.com/jonschlinkert/fill-range
|
||||
[micromatch]: https://github.com/jonschlinkert/micromatch
|
||||
[minimatch]: https://github.com/isaacs/minimatch
|
||||
<!-- deps:mocha -->
|
||||
@@ -0,0 +1,400 @@
|
||||
/*!
|
||||
* braces <https://github.com/jonschlinkert/braces>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var lazy = require('lazy-cache')(require);
|
||||
lazy('expand-range', 'expand');
|
||||
lazy('repeat-element', 'repeat');
|
||||
lazy('preserve', 'tokens');
|
||||
|
||||
/**
|
||||
* Expose `braces`
|
||||
*/
|
||||
|
||||
module.exports = function (str, options) {
|
||||
if (typeof str !== 'string') {
|
||||
throw new Error('braces expects a string');
|
||||
}
|
||||
return braces(str, options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Expand `{foo,bar}` or `{1..5}` braces in the
|
||||
* given `string`.
|
||||
*
|
||||
* @param {String} `str`
|
||||
* @param {Array} `arr`
|
||||
* @param {Object} `options`
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
function braces(str, arr, options) {
|
||||
if (str === '') {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (!Array.isArray(arr)) {
|
||||
options = arr;
|
||||
arr = [];
|
||||
}
|
||||
|
||||
var opts = options || {};
|
||||
arr = arr || [];
|
||||
|
||||
if (typeof opts.nodupes === 'undefined') {
|
||||
opts.nodupes = true;
|
||||
}
|
||||
|
||||
var fn = opts.fn;
|
||||
var es6;
|
||||
|
||||
if (typeof opts === 'function') {
|
||||
fn = opts;
|
||||
opts = {};
|
||||
}
|
||||
|
||||
if (!(patternRe instanceof RegExp)) {
|
||||
patternRe = patternRegex();
|
||||
}
|
||||
|
||||
var matches = str.match(patternRe) || [];
|
||||
var m = matches[0];
|
||||
|
||||
switch(m) {
|
||||
case '\\,':
|
||||
return escapeCommas(str, arr, opts);
|
||||
case '\\.':
|
||||
return escapeDots(str, arr, opts);
|
||||
case '\/.':
|
||||
return escapePaths(str, arr, opts);
|
||||
case ' ':
|
||||
return splitWhitespace(str);
|
||||
case '{,}':
|
||||
return exponential(str, opts, braces);
|
||||
case '{}':
|
||||
return emptyBraces(str, arr, opts);
|
||||
case '\\{':
|
||||
case '\\}':
|
||||
return escapeBraces(str, arr, opts);
|
||||
case '${':
|
||||
if (!/\{[^{]+\{/.test(str)) {
|
||||
return arr.concat(str);
|
||||
} else {
|
||||
es6 = true;
|
||||
str = lazy.tokens.before(str, es6Regex());
|
||||
}
|
||||
}
|
||||
|
||||
if (!(braceRe instanceof RegExp)) {
|
||||
braceRe = braceRegex();
|
||||
}
|
||||
|
||||
var match = braceRe.exec(str);
|
||||
if (match == null) {
|
||||
return [str];
|
||||
}
|
||||
|
||||
var outter = match[1];
|
||||
var inner = match[2];
|
||||
if (inner === '') { return [str]; }
|
||||
|
||||
var segs, segsLength;
|
||||
|
||||
if (inner.indexOf('..') !== -1) {
|
||||
segs = lazy.expand(inner, opts, fn) || inner.split(',');
|
||||
segsLength = segs.length;
|
||||
|
||||
} else if (inner[0] === '"' || inner[0] === '\'') {
|
||||
return arr.concat(str.split(/['"]/).join(''));
|
||||
|
||||
} else {
|
||||
segs = inner.split(',');
|
||||
if (opts.makeRe) {
|
||||
return braces(str.replace(outter, wrap(segs, '|')), opts);
|
||||
}
|
||||
|
||||
segsLength = segs.length;
|
||||
if (segsLength === 1 && opts.bash) {
|
||||
segs[0] = wrap(segs[0], '\\');
|
||||
}
|
||||
}
|
||||
|
||||
var len = segs.length;
|
||||
var i = 0, val;
|
||||
|
||||
while (len--) {
|
||||
var path = segs[i++];
|
||||
|
||||
if (/(\.[^.\/])/.test(path)) {
|
||||
if (segsLength > 1) {
|
||||
return segs;
|
||||
} else {
|
||||
return [str];
|
||||
}
|
||||
}
|
||||
|
||||
val = splice(str, outter, path);
|
||||
|
||||
if (/\{[^{}]+?\}/.test(val)) {
|
||||
arr = braces(val, arr, opts);
|
||||
} else if (val !== '') {
|
||||
if (opts.nodupes && arr.indexOf(val) !== -1) { continue; }
|
||||
arr.push(es6 ? lazy.tokens.after(val) : val);
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.strict) { return filter(arr, filterEmpty); }
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand exponential ranges
|
||||
*
|
||||
* `a{,}{,}` => ['a', 'a', 'a', 'a']
|
||||
*/
|
||||
|
||||
function exponential(str, options, fn) {
|
||||
if (typeof options === 'function') {
|
||||
fn = options;
|
||||
options = null;
|
||||
}
|
||||
|
||||
var opts = options || {};
|
||||
var esc = '__ESC_EXP__';
|
||||
var exp = 0;
|
||||
var res;
|
||||
|
||||
var parts = str.split('{,}');
|
||||
if (opts.nodupes) {
|
||||
return fn(parts.join(''), opts);
|
||||
}
|
||||
|
||||
exp = parts.length - 1;
|
||||
res = fn(parts.join(esc), opts);
|
||||
var len = res.length;
|
||||
var arr = [];
|
||||
var i = 0;
|
||||
|
||||
while (len--) {
|
||||
var ele = res[i++];
|
||||
var idx = ele.indexOf(esc);
|
||||
|
||||
if (idx === -1) {
|
||||
arr.push(ele);
|
||||
|
||||
} else {
|
||||
ele = ele.split('__ESC_EXP__').join('');
|
||||
if (!!ele && opts.nodupes !== false) {
|
||||
arr.push(ele);
|
||||
|
||||
} else {
|
||||
var num = Math.pow(2, exp);
|
||||
arr.push.apply(arr, lazy.repeat(ele, num));
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a value with parens, brackets or braces,
|
||||
* based on the given character/separator.
|
||||
*
|
||||
* @param {String|Array} `val`
|
||||
* @param {String} `ch`
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function wrap(val, ch) {
|
||||
if (ch === '|') {
|
||||
return '(' + val.join(ch) + ')';
|
||||
}
|
||||
if (ch === ',') {
|
||||
return '{' + val.join(ch) + '}';
|
||||
}
|
||||
if (ch === '-') {
|
||||
return '[' + val.join(ch) + ']';
|
||||
}
|
||||
if (ch === '\\') {
|
||||
return '\\{' + val + '\\}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle empty braces: `{}`
|
||||
*/
|
||||
|
||||
function emptyBraces(str, arr, opts) {
|
||||
return braces(str.split('{}').join('\\{\\}'), arr, opts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out empty-ish values
|
||||
*/
|
||||
|
||||
function filterEmpty(ele) {
|
||||
return !!ele && ele !== '\\';
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle patterns with whitespace
|
||||
*/
|
||||
|
||||
function splitWhitespace(str) {
|
||||
var segs = str.split(' ');
|
||||
var len = segs.length;
|
||||
var res = [];
|
||||
var i = 0;
|
||||
|
||||
while (len--) {
|
||||
res.push.apply(res, braces(segs[i++]));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle escaped braces: `\\{foo,bar}`
|
||||
*/
|
||||
|
||||
function escapeBraces(str, arr, opts) {
|
||||
if (!/\{[^{]+\{/.test(str)) {
|
||||
return arr.concat(str.split('\\').join(''));
|
||||
} else {
|
||||
str = str.split('\\{').join('__LT_BRACE__');
|
||||
str = str.split('\\}').join('__RT_BRACE__');
|
||||
return map(braces(str, arr, opts), function (ele) {
|
||||
ele = ele.split('__LT_BRACE__').join('{');
|
||||
return ele.split('__RT_BRACE__').join('}');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle escaped dots: `{1\\.2}`
|
||||
*/
|
||||
|
||||
function escapeDots(str, arr, opts) {
|
||||
if (!/[^\\]\..+\\\./.test(str)) {
|
||||
return arr.concat(str.split('\\').join(''));
|
||||
} else {
|
||||
str = str.split('\\.').join('__ESC_DOT__');
|
||||
return map(braces(str, arr, opts), function (ele) {
|
||||
return ele.split('__ESC_DOT__').join('.');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle escaped dots: `{1\\.2}`
|
||||
*/
|
||||
|
||||
function escapePaths(str, arr, opts) {
|
||||
str = str.split('\/.').join('__ESC_PATH__');
|
||||
return map(braces(str, arr, opts), function (ele) {
|
||||
return ele.split('__ESC_PATH__').join('\/.');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle escaped commas: `{a\\,b}`
|
||||
*/
|
||||
|
||||
function escapeCommas(str, arr, opts) {
|
||||
if (!/\w,/.test(str)) {
|
||||
return arr.concat(str.split('\\').join(''));
|
||||
} else {
|
||||
str = str.split('\\,').join('__ESC_COMMA__');
|
||||
return map(braces(str, arr, opts), function (ele) {
|
||||
return ele.split('__ESC_COMMA__').join(',');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Regex for common patterns
|
||||
*/
|
||||
|
||||
function patternRegex() {
|
||||
return /\$\{|[ \t]|{}|{,}|\\,(?=.*[{}])|\/\.(?=.*[{}])|\\\.(?={)|\\{|\\}/;
|
||||
}
|
||||
|
||||
/**
|
||||
* Braces regex.
|
||||
*/
|
||||
|
||||
function braceRegex() {
|
||||
return /.*(\\?\{([^}]+)\})/;
|
||||
}
|
||||
|
||||
/**
|
||||
* es6 delimiter regex.
|
||||
*/
|
||||
|
||||
function es6Regex() {
|
||||
return /\$\{([^}]+)\}/;
|
||||
}
|
||||
|
||||
var braceRe;
|
||||
var patternRe;
|
||||
|
||||
/**
|
||||
* Faster alternative to `String.replace()` when the
|
||||
* index of the token to be replaces can't be supplied
|
||||
*/
|
||||
|
||||
function splice(str, token, replacement) {
|
||||
var i = str.indexOf(token);
|
||||
return str.substr(0, i) + replacement
|
||||
+ str.substr(i + token.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast array map
|
||||
*/
|
||||
|
||||
function map(arr, fn) {
|
||||
if (arr == null) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var len = arr.length;
|
||||
var res = new Array(len);
|
||||
var i = -1;
|
||||
|
||||
while (++i < len) {
|
||||
res[i] = fn(arr[i], i, arr);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fast array filter
|
||||
*/
|
||||
|
||||
function filter(arr, cb) {
|
||||
if (arr == null) return [];
|
||||
if (typeof cb !== 'function') {
|
||||
throw new TypeError('braces: filter expects a callback function.');
|
||||
}
|
||||
|
||||
var len = arr.length;
|
||||
var res = arr.slice();
|
||||
var i = 0;
|
||||
|
||||
while (len--) {
|
||||
if (!cb(arr[len], i++)) {
|
||||
res.splice(len, 1);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,107 @@
|
||||
# expand-range [](http://badge.fury.io/js/expand-range)
|
||||
|
||||
> Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch.
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i expand-range --save
|
||||
```
|
||||
|
||||
Wraps [fill-range] to do range expansion using `..` separated strings. See [fill-range] for the full list of options and features.
|
||||
|
||||
|
||||
## Example usage
|
||||
|
||||
```js
|
||||
var expand = require('expand-range');
|
||||
```
|
||||
|
||||
**Params**
|
||||
|
||||
```js
|
||||
expand(start, stop, increment);
|
||||
```
|
||||
|
||||
- `start`: the number or letter to start with
|
||||
- `end`: the number or letter to end with
|
||||
- `increment`: optionally pass the increment to use. works for letters or numbers
|
||||
|
||||
**Examples**
|
||||
|
||||
```js
|
||||
expand('a..e')
|
||||
//=> ['a', 'b', 'c', 'd', 'e']
|
||||
|
||||
expand('a..e..2')
|
||||
//=> ['a', 'c', 'e']
|
||||
|
||||
expand('A..E..2')
|
||||
//=> ['A', 'C', 'E']
|
||||
|
||||
expand('1..3')
|
||||
//=> ['1', '2', '3']
|
||||
|
||||
expand('0..-5')
|
||||
//=> [ '0', '-1', '-2', '-3', '-4', '-5' ]
|
||||
|
||||
expand('-9..9..3')
|
||||
//=> [ '-9', '-6', '-3', '0', '3', '6', '9' ])
|
||||
|
||||
expand('-1..-10..-2')
|
||||
//=> [ '-1', '-3', '-5', '-7', '-9' ]
|
||||
|
||||
expand('1..10..2')
|
||||
//=> [ '1', '3', '5', '7', '9' ]
|
||||
```
|
||||
|
||||
|
||||
### Custom function
|
||||
|
||||
Optionally pass a custom function as the second argument:
|
||||
|
||||
```js
|
||||
expand('a..e', function (val, isNumber, pad, i) {
|
||||
if (!isNumber) {
|
||||
return String.fromCharCode(val) + i;
|
||||
}
|
||||
return val;
|
||||
});
|
||||
//=> ['a0', 'b1', 'c2', 'd3', 'e4']
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
- [micromatch]: wildcard/glob matcher for javascript. a faster alternative to minimatch.
|
||||
- [fill-range]: the library this depends on for core functionality
|
||||
- [braces]: this library is used in braces, a fast Brash-like brace expansion lib.
|
||||
|
||||
## Run tests
|
||||
|
||||
Install dev dependencies
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/expand-range/issues).
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb](https://github.com/assemble/verb) on January 30, 2015._
|
||||
|
||||
[fill-range]: https://github.com/jonschlinkert/fill-range
|
||||
[micromatch]: https://github.com/jonschlinkert/micromatch
|
||||
[braces]: https://github.com/jonschlinkert/braces
|
||||
@@ -0,0 +1,43 @@
|
||||
/*!
|
||||
* expand-range <https://github.com/jonschlinkert/expand-range>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var fill = require('fill-range');
|
||||
|
||||
module.exports = function expandRange(str, options, fn) {
|
||||
if (typeof str !== 'string') {
|
||||
throw new TypeError('expand-range expects a string.');
|
||||
}
|
||||
|
||||
if (typeof options === 'function') {
|
||||
fn = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
if (typeof options === 'boolean') {
|
||||
options = {};
|
||||
options.makeRe = true;
|
||||
}
|
||||
|
||||
// create arguments to pass to fill-range
|
||||
var opts = options || {};
|
||||
var args = str.split('..');
|
||||
var len = args.length;
|
||||
if (len > 3) { return str; }
|
||||
|
||||
// if only one argument, it can't expand so return it
|
||||
if (len === 1) { return args; }
|
||||
|
||||
// if `true`, tell fill-range to regexify the string
|
||||
if (typeof fn === 'boolean' && fn === true) {
|
||||
opts.makeRe = true;
|
||||
}
|
||||
|
||||
args.push(opts);
|
||||
return fill.apply(fill, args.concat(fn));
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,290 @@
|
||||
# fill-range [](http://badge.fury.io/js/fill-range) [](https://travis-ci.org/jonschlinkert/fill-range)
|
||||
|
||||
> Fill in a range of numbers or letters, optionally passing an increment or multiplier to use.
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i fill-range --save
|
||||
```
|
||||
|
||||
<!-- toc -->
|
||||
|
||||
- [Usage](#usage)
|
||||
* [Invalid ranges](#invalid-ranges)
|
||||
* [Custom function](#custom-function)
|
||||
* [Special characters](#special-characters)
|
||||
+ [plus](#plus)
|
||||
+ [pipe and tilde](#pipe-and-tilde)
|
||||
+ [angle bracket](#angle-bracket)
|
||||
+ [question mark](#question-mark)
|
||||
- [Other useful libs](#other-useful-libs)
|
||||
- [Running tests](#running-tests)
|
||||
- [Contributing](#contributing)
|
||||
- [Author](#author)
|
||||
- [License](#license)
|
||||
|
||||
_(Table of contents generated by [verb])_
|
||||
|
||||
<!-- tocstop -->
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var range = require('fill-range');
|
||||
|
||||
range('a', 'e');
|
||||
//=> ['a', 'b', 'c', 'd', 'e']
|
||||
```
|
||||
|
||||
**Params**
|
||||
|
||||
```js
|
||||
range(start, stop, step, options, fn);
|
||||
```
|
||||
|
||||
- `start`: **{String|Number}** the number or letter to start with
|
||||
- `end`: **{String|Number}** the number or letter to end with
|
||||
- `step`: **{String|Number}** optionally pass the step to use. works for letters or numbers.
|
||||
- `options`: **{Object}**:
|
||||
+ `makeRe`: return a regex-compatible string (still returned as an array for consistency)
|
||||
+ `step`: pass the step on the options as an alternative to passing it as an argument
|
||||
+ `silent`: `true` by default, set to false to throw errors for invalid ranges.
|
||||
- `fn`: **{Function}** optionally [pass a function](#custom-function) to modify each character
|
||||
|
||||
|
||||
**Examples**
|
||||
|
||||
```js
|
||||
range(1, 3)
|
||||
//=> ['1', '2', '3']
|
||||
|
||||
range('1', '3')
|
||||
//=> ['1', '2', '3']
|
||||
|
||||
range('0', '-5')
|
||||
//=> [ '0', '-1', '-2', '-3', '-4', '-5' ]
|
||||
|
||||
range(-9, 9, 3)
|
||||
//=> [ '-9', '-6', '-3', '0', '3', '6', '9' ])
|
||||
|
||||
range('-1', '-10', '-2')
|
||||
//=> [ '-1', '-3', '-5', '-7', '-9' ]
|
||||
|
||||
range('1', '10', '2')
|
||||
//=> [ '1', '3', '5', '7', '9' ]
|
||||
|
||||
range('a', 'e')
|
||||
//=> ['a', 'b', 'c', 'd', 'e']
|
||||
|
||||
range('a', 'e', 2)
|
||||
//=> ['a', 'c', 'e']
|
||||
|
||||
range('A', 'E', 2)
|
||||
//=> ['A', 'C', 'E']
|
||||
```
|
||||
|
||||
### Invalid ranges
|
||||
|
||||
When an invalid range is passed, `null` is returned.
|
||||
|
||||
```js
|
||||
range('1.1', '2');
|
||||
//=> null
|
||||
|
||||
range('a', '2');
|
||||
//=> null
|
||||
|
||||
range(1, 10, 'foo');
|
||||
//=> null
|
||||
```
|
||||
|
||||
If you want errors to be throw, pass `silent: false` on the options:
|
||||
|
||||
|
||||
### Custom function
|
||||
|
||||
Optionally pass a custom function as the third or fourth argument:
|
||||
|
||||
```js
|
||||
range('a', 'e', function (val, isNumber, pad, i) {
|
||||
if (!isNumber) {
|
||||
return String.fromCharCode(val) + i;
|
||||
}
|
||||
return val;
|
||||
});
|
||||
//=> ['a0', 'b1', 'c2', 'd3', 'e4']
|
||||
```
|
||||
|
||||
### Special characters
|
||||
|
||||
A special character may be passed as the third arg instead of a step increment. These characters can be pretty useful for brace expansion, creating file paths, test fixtures and similar use case.
|
||||
|
||||
```js
|
||||
range('a', 'z', SPECIAL_CHARACTER_HERE);
|
||||
```
|
||||
|
||||
**Supported characters**
|
||||
|
||||
- `+`: repeat the given string `n` times
|
||||
- `|`: create a regex-ready string, instead of an array
|
||||
- `>`: join values to single array element
|
||||
- `?`: randomize the given pattern using [randomatic]
|
||||
|
||||
#### plus
|
||||
|
||||
Character: _(`+`)_
|
||||
|
||||
Repeat the first argument the number of times passed on the second argument.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```js
|
||||
range('a', 3, '+');
|
||||
//=> ['a', 'a', 'a']
|
||||
|
||||
range('abc', 2, '+');
|
||||
//=> ['abc', 'abc']
|
||||
```
|
||||
|
||||
#### pipe and tilde
|
||||
|
||||
Characters: _(`|` and `~`)_
|
||||
|
||||
Creates a regex-capable string (either a logical `or` or a character class) from the expanded arguments.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```js
|
||||
range('a', 'c', '|');
|
||||
//=> ['(a|b|c)'
|
||||
|
||||
range('a', 'c', '~');
|
||||
//=> ['[a-c]'
|
||||
|
||||
range('a', 'z', '|5');
|
||||
//=> ['(a|f|k|p|u|z)'
|
||||
```
|
||||
|
||||
**Automatic separator correction**
|
||||
|
||||
To avoid this error:
|
||||
|
||||
> `Range out of order in character class`
|
||||
|
||||
Fill-range detects invalid sequences and uses the correct syntax. For example:
|
||||
|
||||
**invalid** (regex)
|
||||
|
||||
If you pass these:
|
||||
|
||||
```js
|
||||
range('a', 'z', '~5');
|
||||
// which would result in this
|
||||
//=> ['[a-f-k-p-u-z]']
|
||||
|
||||
range('10', '20', '~');
|
||||
// which would result in this
|
||||
//=> ['[10-20]']
|
||||
```
|
||||
|
||||
**valid** (regex)
|
||||
|
||||
fill-range corrects them to this:
|
||||
|
||||
```js
|
||||
range('a', 'z', '~5');
|
||||
//=> ['(a|f|k|p|u|z)'
|
||||
|
||||
range('10', '20', '~');
|
||||
//=> ['(10-20)'
|
||||
```
|
||||
|
||||
#### angle bracket
|
||||
|
||||
Character: _(`>`)_
|
||||
|
||||
Joins all values in the returned array to a single value.
|
||||
|
||||
**Examples:**
|
||||
|
||||
```js
|
||||
range('a', 'e', '>');
|
||||
//=> ['abcde']
|
||||
|
||||
range('5', '8', '>');
|
||||
//=> ['5678']
|
||||
|
||||
range('2', '20', '2>');
|
||||
//=> ['2468101214161820']
|
||||
```
|
||||
|
||||
|
||||
#### question mark
|
||||
|
||||
Character: _(`?`)_
|
||||
|
||||
Uses [randomatic] to generate randomized alpha, numeric, or alpha-numeric patterns based on the provided arguments.
|
||||
|
||||
**Examples:**
|
||||
|
||||
_(actual results would obviously be randomized)_
|
||||
|
||||
Generate a 5-character, uppercase, alphabetical string:
|
||||
|
||||
```js
|
||||
range('A', 5, '?');
|
||||
//=> ['NSHAK']
|
||||
```
|
||||
|
||||
Generate a 5-digit random number:
|
||||
|
||||
```js
|
||||
range('0', 5, '?');
|
||||
//=> ['36583']
|
||||
```
|
||||
|
||||
Generate a 10-character alpha-numeric string:
|
||||
|
||||
```js
|
||||
range('A0', 10, '?');
|
||||
//=> ['5YJD60VQNN']
|
||||
```
|
||||
|
||||
See the [randomatic] repo for all available options and or to create issues or feature requests related to randomization.
|
||||
|
||||
## Other useful libs
|
||||
* [micromatch](https://github.com/jonschlinkert/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just use `micromatch.isMatch()` instead of `minimatch()`, or use `micromatch()` instead of `multimatch()`.
|
||||
* [expand-range](https://github.com/jonschlinkert/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch.
|
||||
* [braces](https://github.com/jonschlinkert/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.
|
||||
* [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a glob pattern.
|
||||
|
||||
## Running tests
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/fill-range/issues)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2014-2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on April 07, 2015._
|
||||
|
||||
[randomatic]: https://github.com/jonschlinkert/randomatic
|
||||
[expand-range]: https://github.com/jonschlinkert/expand-range
|
||||
[micromatch]: https://github.com/jonschlinkert/micromatch
|
||||
[braces]: https://github.com/jonschlinkert/braces
|
||||
@@ -0,0 +1,408 @@
|
||||
/*!
|
||||
* fill-range <https://github.com/jonschlinkert/fill-range>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var isObject = require('isobject');
|
||||
var isNumber = require('is-number');
|
||||
var randomize = require('randomatic');
|
||||
var repeatStr = require('repeat-string');
|
||||
var repeat = require('repeat-element');
|
||||
|
||||
/**
|
||||
* Expose `fillRange`
|
||||
*/
|
||||
|
||||
module.exports = fillRange;
|
||||
|
||||
/**
|
||||
* Return a range of numbers or letters.
|
||||
*
|
||||
* @param {String} `a` Start of the range
|
||||
* @param {String} `b` End of the range
|
||||
* @param {String} `step` Increment or decrement to use.
|
||||
* @param {Function} `fn` Custom function to modify each element in the range.
|
||||
* @return {Array}
|
||||
*/
|
||||
|
||||
function fillRange(a, b, step, options, fn) {
|
||||
if (a == null || b == null) {
|
||||
throw new Error('fill-range expects the first and second args to be strings.');
|
||||
}
|
||||
|
||||
if (typeof step === 'function') {
|
||||
fn = step; options = {}; step = null;
|
||||
}
|
||||
|
||||
if (typeof options === 'function') {
|
||||
fn = options; options = {};
|
||||
}
|
||||
|
||||
if (isObject(step)) {
|
||||
options = step; step = '';
|
||||
}
|
||||
|
||||
var expand, regex = false, sep = '';
|
||||
var opts = options || {};
|
||||
|
||||
if (typeof opts.silent === 'undefined') {
|
||||
opts.silent = true;
|
||||
}
|
||||
|
||||
step = step || opts.step;
|
||||
|
||||
// store a ref to unmodified arg
|
||||
var origA = a, origB = b;
|
||||
|
||||
b = (b.toString() === '-0') ? 0 : b;
|
||||
|
||||
if (opts.optimize || opts.makeRe) {
|
||||
step = step ? (step += '~') : step;
|
||||
expand = true;
|
||||
regex = true;
|
||||
sep = '~';
|
||||
}
|
||||
|
||||
// handle special step characters
|
||||
if (typeof step === 'string') {
|
||||
var match = stepRe().exec(step);
|
||||
|
||||
if (match) {
|
||||
var i = match.index;
|
||||
var m = match[0];
|
||||
|
||||
// repeat string
|
||||
if (m === '+') {
|
||||
return repeat(a, b);
|
||||
|
||||
// randomize a, `b` times
|
||||
} else if (m === '?') {
|
||||
return [randomize(a, b)];
|
||||
|
||||
// expand right, no regex reduction
|
||||
} else if (m === '>') {
|
||||
step = step.substr(0, i) + step.substr(i + 1);
|
||||
expand = true;
|
||||
|
||||
// expand to an array, or if valid create a reduced
|
||||
// string for a regex logic `or`
|
||||
} else if (m === '|') {
|
||||
step = step.substr(0, i) + step.substr(i + 1);
|
||||
expand = true;
|
||||
regex = true;
|
||||
sep = m;
|
||||
|
||||
// expand to an array, or if valid create a reduced
|
||||
// string for a regex range
|
||||
} else if (m === '~') {
|
||||
step = step.substr(0, i) + step.substr(i + 1);
|
||||
expand = true;
|
||||
regex = true;
|
||||
sep = m;
|
||||
}
|
||||
} else if (!isNumber(step)) {
|
||||
if (!opts.silent) {
|
||||
throw new TypeError('fill-range: invalid step.');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (/[.&*()[\]^%$#@!]/.test(a) || /[.&*()[\]^%$#@!]/.test(b)) {
|
||||
if (!opts.silent) {
|
||||
throw new RangeError('fill-range: invalid range arguments.');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// has neither a letter nor number, or has both letters and numbers
|
||||
// this needs to be after the step logic
|
||||
if (!noAlphaNum(a) || !noAlphaNum(b) || hasBoth(a) || hasBoth(b)) {
|
||||
if (!opts.silent) {
|
||||
throw new RangeError('fill-range: invalid range arguments.');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// validate arguments
|
||||
var isNumA = isNumber(zeros(a));
|
||||
var isNumB = isNumber(zeros(b));
|
||||
|
||||
if ((!isNumA && isNumB) || (isNumA && !isNumB)) {
|
||||
if (!opts.silent) {
|
||||
throw new TypeError('fill-range: first range argument is incompatible with second.');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// by this point both are the same, so we
|
||||
// can use A to check going forward.
|
||||
var isNum = isNumA;
|
||||
var num = formatStep(step);
|
||||
|
||||
// is the range alphabetical? or numeric?
|
||||
if (isNum) {
|
||||
// if numeric, coerce to an integer
|
||||
a = +a; b = +b;
|
||||
} else {
|
||||
// otherwise, get the charCode to expand alpha ranges
|
||||
a = a.charCodeAt(0);
|
||||
b = b.charCodeAt(0);
|
||||
}
|
||||
|
||||
// is the pattern descending?
|
||||
var isDescending = a > b;
|
||||
|
||||
// don't create a character class if the args are < 0
|
||||
if (a < 0 || b < 0) {
|
||||
expand = false;
|
||||
regex = false;
|
||||
}
|
||||
|
||||
// detect padding
|
||||
var padding = isPadded(origA, origB);
|
||||
var res, pad, arr = [];
|
||||
var ii = 0;
|
||||
|
||||
// character classes, ranges and logical `or`
|
||||
if (regex) {
|
||||
if (shouldExpand(a, b, num, isNum, padding, opts)) {
|
||||
// make sure the correct separator is used
|
||||
if (sep === '|' || sep === '~') {
|
||||
sep = detectSeparator(a, b, num, isNum, isDescending);
|
||||
}
|
||||
return wrap([origA, origB], sep, opts);
|
||||
}
|
||||
}
|
||||
|
||||
while (isDescending ? (a >= b) : (a <= b)) {
|
||||
if (padding && isNum) {
|
||||
pad = padding(a);
|
||||
}
|
||||
|
||||
// custom function
|
||||
if (typeof fn === 'function') {
|
||||
res = fn(a, isNum, pad, ii++);
|
||||
|
||||
// letters
|
||||
} else if (!isNum) {
|
||||
if (regex && isInvalidChar(a)) {
|
||||
res = null;
|
||||
} else {
|
||||
res = String.fromCharCode(a);
|
||||
}
|
||||
|
||||
// numbers
|
||||
} else {
|
||||
res = formatPadding(a, pad);
|
||||
}
|
||||
|
||||
// add result to the array, filtering any nulled values
|
||||
if (res !== null) arr.push(res);
|
||||
|
||||
// increment or decrement
|
||||
if (isDescending) {
|
||||
a -= num;
|
||||
} else {
|
||||
a += num;
|
||||
}
|
||||
}
|
||||
|
||||
// now that the array is expanded, we need to handle regex
|
||||
// character classes, ranges or logical `or` that wasn't
|
||||
// already handled before the loop
|
||||
if ((regex || expand) && !opts.noexpand) {
|
||||
// make sure the correct separator is used
|
||||
if (sep === '|' || sep === '~') {
|
||||
sep = detectSeparator(a, b, num, isNum, isDescending);
|
||||
}
|
||||
if (arr.length === 1 || a < 0 || b < 0) { return arr; }
|
||||
return wrap(arr, sep, opts);
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the string with the correct regex
|
||||
* syntax.
|
||||
*/
|
||||
|
||||
function wrap(arr, sep, opts) {
|
||||
if (sep === '~') { sep = '-'; }
|
||||
var str = arr.join(sep);
|
||||
var pre = opts && opts.regexPrefix;
|
||||
|
||||
// regex logical `or`
|
||||
if (sep === '|') {
|
||||
str = pre ? pre + str : str;
|
||||
str = '(' + str + ')';
|
||||
}
|
||||
|
||||
// regex character class
|
||||
if (sep === '-') {
|
||||
str = (pre && pre === '^')
|
||||
? pre + str
|
||||
: str;
|
||||
str = '[' + str + ']';
|
||||
}
|
||||
return [str];
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for invalid characters
|
||||
*/
|
||||
|
||||
function isCharClass(a, b, step, isNum, isDescending) {
|
||||
if (isDescending) { return false; }
|
||||
if (isNum) { return a <= 9 && b <= 9; }
|
||||
if (a < b) { return step === 1; }
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the correct separator to use
|
||||
*/
|
||||
|
||||
function shouldExpand(a, b, num, isNum, padding, opts) {
|
||||
if (isNum && (a > 9 || b > 9)) { return false; }
|
||||
return !padding && num === 1 && a < b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect the correct separator to use
|
||||
*/
|
||||
|
||||
function detectSeparator(a, b, step, isNum, isDescending) {
|
||||
var isChar = isCharClass(a, b, step, isNum, isDescending);
|
||||
if (!isChar) {
|
||||
return '|';
|
||||
}
|
||||
return '~';
|
||||
}
|
||||
|
||||
/**
|
||||
* Correctly format the step based on type
|
||||
*/
|
||||
|
||||
function formatStep(step) {
|
||||
return Math.abs(step >> 0) || 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format padding, taking leading `-` into account
|
||||
*/
|
||||
|
||||
function formatPadding(ch, pad) {
|
||||
var res = pad ? pad + ch : ch;
|
||||
if (pad && ch.toString().charAt(0) === '-') {
|
||||
res = '-' + pad + ch.toString().substr(1);
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for invalid characters
|
||||
*/
|
||||
|
||||
function isInvalidChar(str) {
|
||||
var ch = toStr(str);
|
||||
return ch === '\\'
|
||||
|| ch === '['
|
||||
|| ch === ']'
|
||||
|| ch === '^'
|
||||
|| ch === '('
|
||||
|| ch === ')'
|
||||
|| ch === '`';
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert to a string from a charCode
|
||||
*/
|
||||
|
||||
function toStr(ch) {
|
||||
return String.fromCharCode(ch);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Step regex
|
||||
*/
|
||||
|
||||
function stepRe() {
|
||||
return /\?|>|\||\+|\~/g;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if `val` has either a letter
|
||||
* or a number
|
||||
*/
|
||||
|
||||
function noAlphaNum(val) {
|
||||
return /[a-z0-9]/i.test(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if `val` has both a letter and
|
||||
* a number (invalid)
|
||||
*/
|
||||
|
||||
function hasBoth(val) {
|
||||
return /[a-z][0-9]|[0-9][a-z]/i.test(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalize zeros for checks
|
||||
*/
|
||||
|
||||
function zeros(val) {
|
||||
if (/^-*0+$/.test(val.toString())) {
|
||||
return '0';
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if `val` has leading zeros,
|
||||
* or a similar valid pattern.
|
||||
*/
|
||||
|
||||
function hasZeros(val) {
|
||||
return /[^.]\.|^-*0+[0-9]/.test(val);
|
||||
}
|
||||
|
||||
/**
|
||||
* If the string is padded, returns a curried function with
|
||||
* the a cached padding string, or `false` if no padding.
|
||||
*
|
||||
* @param {*} `origA` String or number.
|
||||
* @return {String|Boolean}
|
||||
*/
|
||||
|
||||
function isPadded(origA, origB) {
|
||||
if (hasZeros(origA) || hasZeros(origB)) {
|
||||
var alen = length(origA);
|
||||
var blen = length(origB);
|
||||
|
||||
var len = alen >= blen
|
||||
? alen
|
||||
: blen;
|
||||
|
||||
return function (a) {
|
||||
return repeatStr('0', len - length(a));
|
||||
};
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the string length of `val`
|
||||
*/
|
||||
|
||||
function length(val) {
|
||||
return val.toString().length;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,104 @@
|
||||
# is-number [](http://badge.fury.io/js/is-number) [](https://travis-ci.org/jonschlinkert/is-number)
|
||||
|
||||
> Returns true if the value is a number. comprehensive tests.
|
||||
|
||||
To understand some of the rationale behind the decisions made in this library (and to learn about some oddities of number evaluation in JavaScript), [see this gist][gist].
|
||||
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i is-number --save
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var isNumber = require('is-number');
|
||||
```
|
||||
|
||||
### true
|
||||
|
||||
See the [tests](./test.js) for more examples.
|
||||
|
||||
```js
|
||||
isNumber(5e3) //=> 'true'
|
||||
isNumber(0xff) //=> 'true'
|
||||
isNumber(-1.1) //=> 'true'
|
||||
isNumber(0) //=> 'true'
|
||||
isNumber(1) //=> 'true'
|
||||
isNumber(1.1) //=> 'true'
|
||||
isNumber(10) //=> 'true'
|
||||
isNumber(10.10) //=> 'true'
|
||||
isNumber(100) //=> 'true'
|
||||
isNumber('-1.1') //=> 'true'
|
||||
isNumber('0') //=> 'true'
|
||||
isNumber('012') //=> 'true'
|
||||
isNumber('0xff') //=> 'true'
|
||||
isNumber('1') //=> 'true'
|
||||
isNumber('1.1') //=> 'true'
|
||||
isNumber('10') //=> 'true'
|
||||
isNumber('10.10') //=> 'true'
|
||||
isNumber('100') //=> 'true'
|
||||
isNumber('5e3') //=> 'true'
|
||||
isNumber(parseInt('012')) //=> 'true'
|
||||
isNumber(parseFloat('012')) //=> 'true'
|
||||
```
|
||||
|
||||
### False
|
||||
|
||||
See the [tests](./test.js) for more examples.
|
||||
|
||||
```js
|
||||
isNumber('foo') //=> 'false'
|
||||
isNumber([1]) //=> 'false'
|
||||
isNumber([]) //=> 'false'
|
||||
isNumber(function () {}) //=> 'false'
|
||||
isNumber(Infinity) //=> 'false'
|
||||
isNumber(NaN) //=> 'false'
|
||||
isNumber(new Array('abc')) //=> 'false'
|
||||
isNumber(new Array(2)) //=> 'false'
|
||||
isNumber(new Buffer('abc')) //=> 'false'
|
||||
isNumber(null) //=> 'false'
|
||||
isNumber(undefined) //=> 'false'
|
||||
isNumber({abc: 'abc'}) //=> 'false'
|
||||
```
|
||||
|
||||
## Other projects
|
||||
* [kind-of](https://github.com/jonschlinkert/kind-of): Get the native type of a value.
|
||||
* [is-primitive](https://github.com/jonschlinkert/is-primitive): Returns `true` if the value is a primitive.
|
||||
* [even](https://github.com/jonschlinkert/even): Get the even numbered items from an array.
|
||||
* [odd](https://github.com/jonschlinkert/odd): Get the odd numbered items from an array.
|
||||
* [is-even](https://github.com/jonschlinkert/is-even): Return true if the given number is even.
|
||||
* [is-odd](https://github.com/jonschlinkert/is-odd): Returns true if the given number is odd.
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/is-number/issues)
|
||||
|
||||
|
||||
## Run tests
|
||||
Install dev dependencies.
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on March 05, 2015._
|
||||
|
||||
[infinity]: http://en.wikipedia.org/wiki/Infinity
|
||||
[gist]: https://gist.github.com/jonschlinkert/e30c70c713da325d0e81
|
||||
@@ -0,0 +1,14 @@
|
||||
/*!
|
||||
* is-number <https://github.com/jonschlinkert/is-number>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function isNumber(n) {
|
||||
return (!!(+n) && !Array.isArray(n)) && isFinite(n)
|
||||
|| n === '0'
|
||||
|| n === 0;
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "is-number",
|
||||
"description": "Returns true if the value is a number. comprehensive tests.",
|
||||
"version": "1.1.2",
|
||||
"homepage": "https://github.com/jonschlinkert/is-number",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/is-number.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/is-number/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/is-number/blob/master/LICENSE"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmarked": "^0.1.3",
|
||||
"chalk": "^0.5.1",
|
||||
"mocha": "^2.1.0"
|
||||
},
|
||||
"keywords": [
|
||||
"check",
|
||||
"coerce",
|
||||
"coercion",
|
||||
"integer",
|
||||
"is number",
|
||||
"is",
|
||||
"is-number",
|
||||
"istype",
|
||||
"kind of",
|
||||
"math",
|
||||
"number",
|
||||
"test",
|
||||
"type",
|
||||
"typeof",
|
||||
"value"
|
||||
],
|
||||
"gitHead": "a902495bca1f471beaa8deb6193ba628bf80c0e4",
|
||||
"_id": "is-number@1.1.2",
|
||||
"_shasum": "9d82409f3a8a8beecf249b1bc7dada49829966e4",
|
||||
"_from": "is-number@>=1.1.2 <2.0.0",
|
||||
"_npmVersion": "2.5.1",
|
||||
"_nodeVersion": "0.12.0",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "9d82409f3a8a8beecf249b1bc7dada49829966e4",
|
||||
"tarball": "http://registry.npmjs.org/is-number/-/is-number-1.1.2.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/is-number/-/is-number-1.1.2.tgz"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,81 @@
|
||||
# isobject [](http://badge.fury.io/js/isobject) [](https://travis-ci.org/jonschlinkert/isobject)
|
||||
|
||||
> Returns true if the value is an object and not an array or null.
|
||||
|
||||
Use [is-plain-object](https://github.com/jonschlinkert/is-plain-object) if you want only objects that are created by the `Object` constructor.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i isobject --save
|
||||
```
|
||||
|
||||
Install with [bower](http://bower.io/)
|
||||
|
||||
```sh
|
||||
$ bower install isobject --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var isObject = require('isobject');
|
||||
```
|
||||
|
||||
**True**
|
||||
|
||||
All of the following return `true`:
|
||||
|
||||
```js
|
||||
isObject({});
|
||||
isObject(Object.create({}));
|
||||
isObject(Object.create(Object.prototype));
|
||||
isObject(Object.create(null));
|
||||
isObject({});
|
||||
isObject(new Foo);
|
||||
isObject(/foo/);
|
||||
```
|
||||
|
||||
**False**
|
||||
|
||||
All of the following return `false`:
|
||||
|
||||
```js
|
||||
isObject();
|
||||
isObject(function () {});
|
||||
isObject(1);
|
||||
isObject([]);
|
||||
isObject(undefined);
|
||||
isObject(null);
|
||||
```
|
||||
|
||||
## Related projects
|
||||
|
||||
* [assign-deep](https://github.com/jonschlinkert/assign-deep): Deeply assign the enumerable properties of source objects to a destination object.
|
||||
* [extend-shallow](https://github.com/jonschlinkert/extend-shallow): Extend an object with the properties of additional objects. node.js/javascript util.
|
||||
* [is-plain-object](https://github.com/jonschlinkert/is-plain-object): Returns true if an object was created by the `Object` constructor.
|
||||
* [is-extendable](https://github.com/jonschlinkert/is-extendable): Returns true if a value is any of the object types: array, regexp, plain object,… [more](https://github.com/jonschlinkert/is-extendable)
|
||||
* [is-equal-shallow](https://github.com/jonschlinkert/is-equal-shallow): Does a shallow comparison of two objects, returning false if the keys or values differ.
|
||||
* [kind-of](https://github.com/jonschlinkert/kind-of): Get the native type of a value.
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/isobject/issues/new)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2014-2015 [Jon Schlinkert](https://github.com/jonschlinkert)
|
||||
Released under the [MIT](https://github.com/jonschlinkert/isobject/blob/master/LICENSE) license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on July 13, 2015._
|
||||
@@ -0,0 +1,13 @@
|
||||
/*!
|
||||
* isobject <https://github.com/jonschlinkert/isobject>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function isObject(val) {
|
||||
return val != null && typeof val === 'object'
|
||||
&& !Array.isArray(val);
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "isobject",
|
||||
"description": "Returns true if the value is an object and not an array or null.",
|
||||
"version": "1.0.2",
|
||||
"homepage": "https://github.com/jonschlinkert/isobject",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/isobject.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/isobject/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/isobject/blob/master/LICENSE"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "*"
|
||||
},
|
||||
"keywords": [
|
||||
"check",
|
||||
"function",
|
||||
"is",
|
||||
"is-object",
|
||||
"isobject",
|
||||
"javascript",
|
||||
"kind",
|
||||
"kind-of",
|
||||
"kindof",
|
||||
"native",
|
||||
"object",
|
||||
"of",
|
||||
"type",
|
||||
"typeof",
|
||||
"validate",
|
||||
"value"
|
||||
],
|
||||
"gitHead": "0d3070262eb950e2e19c5781da8f243b629c7731",
|
||||
"_id": "isobject@1.0.2",
|
||||
"_shasum": "f0f9b8ce92dd540fa0740882e3835a2e022ec78a",
|
||||
"_from": "isobject@>=1.0.0 <2.0.0",
|
||||
"_npmVersion": "2.10.1",
|
||||
"_nodeVersion": "0.12.4",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "f0f9b8ce92dd540fa0740882e3835a2e022ec78a",
|
||||
"tarball": "http://registry.npmjs.org/isobject/-/isobject-1.0.2.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/isobject/-/isobject-1.0.2.tgz",
|
||||
"readme": "ERROR: No README data found!"
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
# randomatic [](http://badge.fury.io/js/randomatic)
|
||||
|
||||
> Generate randomized strings of a specified length, fast. Only the length is necessary, but you can optionally generate patterns using any combination of numeric, alpha-numeric, alphabetical, special or custom characters.
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i randomatic --save
|
||||
```
|
||||
### Install with [bower](https://github.com/bower/bower)
|
||||
|
||||
```bash
|
||||
bower install randomatic --save
|
||||
```
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var randomize = require('randomatic');
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
```
|
||||
randomize(pattern, length, options);
|
||||
```
|
||||
|
||||
- `pattern` **{String}**: The pattern to use for randomizing
|
||||
- `length` **{Object}**: The length of the string to generate
|
||||
|
||||
|
||||
### pattern
|
||||
|
||||
> The pattern to use for randomizing
|
||||
|
||||
Patterns can contain any combination of the below characters, specified in any order.
|
||||
|
||||
**Example:**
|
||||
|
||||
To generate a 10-character randomized string using all available characters:
|
||||
|
||||
```js
|
||||
randomize('*', 10);
|
||||
//=>
|
||||
|
||||
randomize('Aa0!', 10);
|
||||
//=>
|
||||
```
|
||||
|
||||
* `a`: Lowercase alpha characters (`abcdefghijklmnopqrstuvwxyz'`)
|
||||
* `A`: Uppercase alpha characters (`ABCDEFGHIJKLMNOPQRSTUVWXYZ'`)
|
||||
* `0`: Numeric characters (`0123456789'`)
|
||||
* `!`: Special characters (`~!@#$%^&()_+-={}[];\',.`)
|
||||
* `*`: All characters (all of the above combined)
|
||||
* `?`: Custom characters (pass a string of custom characters to the options)
|
||||
|
||||
|
||||
### length
|
||||
|
||||
> the length of the string to generate
|
||||
|
||||
**Examples:**
|
||||
|
||||
* `randomize('A', 5)` will generate a 5-character, uppercase, alphabetical, randomized string, e.g. `KDJWJ`.
|
||||
* `randomize('0', 2)` will generate a 2-digit random number
|
||||
* `randomize('0', 3)` will generate a 3-digit random number
|
||||
* `randomize('0', 12)` will generate a 12-digit random number
|
||||
* `randomize('A0', 16)` will generate a 16-character, alpha-numeric randomized string
|
||||
|
||||
If `length` is left undefined, the length of the pattern in the first parameter will be used. For example:
|
||||
|
||||
* `randomize('00')` will generate a 2-digit random number
|
||||
* `randomize('000')` will generate a 3-digit random number
|
||||
* `randomize('0000')` will generate a 4-digit random number...
|
||||
* `randomize('AAAAA')` will generate a 5-character, uppercase alphabetical random string...
|
||||
|
||||
These are just examples, [see the tests](./test.js) for more use cases and examples.
|
||||
|
||||
|
||||
|
||||
## options
|
||||
|
||||
#### chars
|
||||
Type: `String`
|
||||
|
||||
Default: `undefined`
|
||||
|
||||
Define a custom string to be randomized.
|
||||
|
||||
**Example:**
|
||||
|
||||
* `randomize('?', 20, {chars: 'jonschlinkert'})` will generate a 20-character randomized string from the letters contained in `jonschlinkert`.
|
||||
* `randomize('?', {chars: 'jonschlinkert'})` will generate a 13-character randomized string from the letters contained in `jonschlinkert`.
|
||||
|
||||
|
||||
|
||||
## Usage Examples
|
||||
|
||||
* `randomize('A', 4)` (_whitespace insenstive_) would result in randomized 4-digit uppercase letters, like, `ZAKH`, `UJSL`... etc.
|
||||
* `randomize('AAAA')` is equivelant to `randomize('A', 4)`
|
||||
* `randomize('AAA0')` and `randomize('AA00')` and `randomize('A0A0')` are equivelant to `randomize('A0', 4)`
|
||||
* `randomize('aa')`: results in double-digit, randomized, lower-case letters (`abcdefghijklmnopqrstuvwxyz`)
|
||||
* `randomize('AAA')`: results in triple-digit, randomized, upper-case letters (`ABCDEFGHIJKLMNOPQRSTUVWXYZ`)
|
||||
* `randomize('0', 6)`: results in six-digit, randomized nubmers (`0123456789`)
|
||||
* `randomize('!', 5)`: results in single-digit randomized, _valid_ non-letter characters (`~!@#$%^&()_+-={}[];\',.`)
|
||||
* `randomize('A!a0', 9)`: results in nine-digit, randomized characters (any of the above)
|
||||
|
||||
_The order in which the characters are defined is insignificant._
|
||||
|
||||
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm install -d && mocha
|
||||
```
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/randomatic/issues)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb](https://github.com/assemble/verb) on January 26, 2015._
|
||||
@@ -0,0 +1,86 @@
|
||||
/*!
|
||||
* randomatic <https://github.com/jonschlinkert/randomatic>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License (MIT)
|
||||
*
|
||||
* Many changes have been made, but this was originally
|
||||
* inspired by <http://stackoverflow.com/a/10727155/1267639>
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var isNumber = require('is-number');
|
||||
var typeOf = require('kind-of');
|
||||
|
||||
/**
|
||||
* Expose `randomatic`
|
||||
*/
|
||||
|
||||
module.exports = randomatic;
|
||||
|
||||
/**
|
||||
* Available mask characters
|
||||
*/
|
||||
|
||||
var type = {
|
||||
lower: 'abcdefghijklmnopqrstuvwxyz',
|
||||
upper: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
number: '0123456789',
|
||||
special: '~!@#$%^&()_+-={}[];\',.'
|
||||
};
|
||||
|
||||
type.all = type.lower + type.upper + type.number;
|
||||
|
||||
/**
|
||||
* Generate random character sequences of a specified `length`,
|
||||
* based on the given `pattern`.
|
||||
*
|
||||
* @param {String} `pattern` The pattern to use for generating the random string.
|
||||
* @param {String} `length` The length of the string to generate.
|
||||
* @param {String} `options`
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function randomatic(pattern, length, options) {
|
||||
if (typeof pattern === 'undefined') {
|
||||
throw new Error('randomatic expects a string or number.');
|
||||
}
|
||||
|
||||
var custom = false;
|
||||
if (arguments.length === 1) {
|
||||
if (typeof pattern === 'string') {
|
||||
length = pattern.length;
|
||||
|
||||
} else if (isNumber(pattern)) {
|
||||
options = {}; length = pattern; pattern = '*';
|
||||
}
|
||||
}
|
||||
|
||||
if(typeOf(length) === 'object' && length.hasOwnProperty('chars')) {
|
||||
options = length;
|
||||
pattern = options.chars;
|
||||
length = pattern.length;
|
||||
custom = true;
|
||||
}
|
||||
|
||||
var opts = options || {};
|
||||
var mask = '';
|
||||
var res = '';
|
||||
|
||||
// Characters to be used
|
||||
if (pattern.indexOf('?') !== -1) mask += opts.chars;
|
||||
if (pattern.indexOf('a') !== -1) mask += type.lower;
|
||||
if (pattern.indexOf('A') !== -1) mask += type.upper;
|
||||
if (pattern.indexOf('0') !== -1) mask += type.number;
|
||||
if (pattern.indexOf('!') !== -1) mask += type.special;
|
||||
if (pattern.indexOf('*') !== -1) mask += type.all;
|
||||
if (custom) mask += pattern;
|
||||
|
||||
while (length--) {
|
||||
res += mask.charAt(parseInt(Math.random() * mask.length));
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "randomatic",
|
||||
"description": "Generate randomized strings of a specified length, fast. Only the length is necessary, but you can optionally generate patterns using any combination of numeric, alpha-numeric, alphabetical, special or custom characters.",
|
||||
"version": "1.1.0",
|
||||
"homepage": "https://github.com/jonschlinkert/randomatic",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jonschlinkert/randomatic.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/randomatic/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/randomatic/blob/master/LICENSE-MIT"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
},
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"is-number": "^1.1.0",
|
||||
"kind-of": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmarked": "^0.1.3",
|
||||
"chalk": "^0.5.1",
|
||||
"glob": "^4.3.5",
|
||||
"should": "^4.4.1"
|
||||
},
|
||||
"keywords": [
|
||||
"alpha",
|
||||
"alpha-numeric",
|
||||
"alphanumeric",
|
||||
"characters",
|
||||
"chars",
|
||||
"numeric",
|
||||
"rand",
|
||||
"random",
|
||||
"randomize",
|
||||
"randomized"
|
||||
],
|
||||
"gitHead": "ca326363bee58a3eb2556a5805822ffbf328397e",
|
||||
"_id": "randomatic@1.1.0",
|
||||
"_shasum": "2ca36b9f93747aac985eb242749af88b45d5d42d",
|
||||
"_from": "randomatic@>=1.1.0 <2.0.0",
|
||||
"_npmVersion": "1.4.28",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "2ca36b9f93747aac985eb242749af88b45d5d42d",
|
||||
"tarball": "http://registry.npmjs.org/randomatic/-/randomatic-1.1.0.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.0.tgz"
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,94 @@
|
||||
# repeat-string [](http://badge.fury.io/js/repeat-string) [](https://travis-ci.org/jonschlinkert/repeat-string)
|
||||
|
||||
> Repeat the given string n times. Fastest implementation for repeating a string.
|
||||
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i repeat-string --save
|
||||
```
|
||||
## Install with [bower](https://github.com/bower/bower)
|
||||
|
||||
```bash
|
||||
bower install repeat-string --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### [repeat](./index.js#L34)
|
||||
|
||||
Repeat the given `string` the specified `number` of times.
|
||||
|
||||
* `string` **{String}**: The string to repeat
|
||||
* `number` **{Number}**: The number of times to repeat the string
|
||||
* `returns` **{String}**: Repeated string
|
||||
|
||||
**Example:**
|
||||
|
||||
```js
|
||||
var repeat = require('repeat-string');
|
||||
repeat('A', 5);
|
||||
//=> AAAAA
|
||||
```
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Repeat string is significantly faster than [repeating](https://github.com/sindresorhus/repeating).
|
||||
|
||||
```bash
|
||||
# 20,000x
|
||||
repeat-string.js x 16,634,213 ops/sec ±0.92% (93 runs sampled)
|
||||
repeating.js x 5,883,928 ops/sec ±0.95% (93 runs sampled)
|
||||
|
||||
# 2,000x
|
||||
repeat-string.js x 17,438,654 ops/sec ±0.76% (97 runs sampled)
|
||||
repeating.js x 6,639,978 ops/sec ±0.84% (97 runs sampled)
|
||||
|
||||
# 250x
|
||||
repeat-string.js x 16,246,885 ops/sec ±0.81% (92 runs sampled)
|
||||
repeating.js x 7,659,342 ops/sec ±0.67% (99 runs sampled)
|
||||
|
||||
# 50x
|
||||
repeat-string.js x 15,803,340 ops/sec ±0.74% (92 runs sampled)
|
||||
repeating.js x 9,668,300 ops/sec ±0.89% (98 runs sampled)
|
||||
|
||||
# 5x
|
||||
repeat-string.js x 16,926,291 ops/sec ±0.78% (97 runs sampled)
|
||||
repeating.js x 12,215,384 ops/sec ±1.01% (96 runs sampled)
|
||||
```
|
||||
|
||||
**Run the benchmarks**
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && node benchmark
|
||||
```
|
||||
|
||||
### Other javascript/node.js utils
|
||||
[repeat-element](https://github.com/jonschlinkert/repeat-element): Create an array by repeating the given string n times.
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/repeat-string/issues)
|
||||
|
||||
## Running tests
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on April 01, 2015._
|
||||
@@ -0,0 +1,66 @@
|
||||
/*!
|
||||
* repeat-string <https://github.com/jonschlinkert/repeat-string>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Expose `repeat`
|
||||
*/
|
||||
|
||||
module.exports = repeat;
|
||||
|
||||
/**
|
||||
* Repeat the given `string` the specified `number`
|
||||
* of times.
|
||||
*
|
||||
* **Example:**
|
||||
*
|
||||
* ```js
|
||||
* var repeat = require('repeat-string');
|
||||
* repeat('A', 5);
|
||||
* //=> AAAAA
|
||||
* ```
|
||||
*
|
||||
* @param {String} `string` The string to repeat
|
||||
* @param {Number} `number` The number of times to repeat the string
|
||||
* @return {String} Repeated string
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function repeat(str, num) {
|
||||
if (typeof str !== 'string') {
|
||||
throw new TypeError('repeat-string expects a string.');
|
||||
}
|
||||
|
||||
if (num === 1) return str;
|
||||
if (num === 2) return str + str;
|
||||
|
||||
var max = str.length * num;
|
||||
if (cache !== str || typeof cache === 'undefined') {
|
||||
cache = str;
|
||||
res = '';
|
||||
}
|
||||
|
||||
while (max > res.length && num > 0) {
|
||||
if (num & 1) {
|
||||
res += str;
|
||||
}
|
||||
|
||||
num >>= 1;
|
||||
if (!num) break;
|
||||
str += str;
|
||||
}
|
||||
|
||||
return res.substr(0, max);
|
||||
}
|
||||
|
||||
/**
|
||||
* Results cache
|
||||
*/
|
||||
|
||||
var res = '';
|
||||
var cache;
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"name": "repeat-string",
|
||||
"description": "Repeat the given string n times. Fastest implementation for repeating a string.",
|
||||
"version": "1.5.2",
|
||||
"homepage": "https://github.com/jonschlinkert/repeat-string",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "http://github.com/jonschlinkert/"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/repeat-string.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/repeat-string/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/repeat-string/blob/master/LICENSE"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmarked": "^0.1.3",
|
||||
"chalk": "^0.5.1",
|
||||
"glob": "^4.3.5",
|
||||
"mocha": "^2.2.1",
|
||||
"repeating": "^1.1.1",
|
||||
"should": "^4.0.4"
|
||||
},
|
||||
"keywords": [
|
||||
"fast",
|
||||
"fastest",
|
||||
"fill",
|
||||
"left",
|
||||
"left-pad",
|
||||
"multiple",
|
||||
"pad",
|
||||
"padding",
|
||||
"repetition",
|
||||
"repeat",
|
||||
"repeating",
|
||||
"right",
|
||||
"right-pad",
|
||||
"string",
|
||||
"times"
|
||||
],
|
||||
"gitHead": "bf20e5dc1414305bec6ff26d90988378a5bad6ec",
|
||||
"_id": "repeat-string@1.5.2",
|
||||
"_shasum": "21065f70727ad053a0dd5e957ac9e00c7560d90a",
|
||||
"_from": "repeat-string@>=1.5.2 <2.0.0",
|
||||
"_npmVersion": "2.5.1",
|
||||
"_nodeVersion": "0.12.0",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "21065f70727ad053a0dd5e957ac9e00c7560d90a",
|
||||
"tarball": "http://registry.npmjs.org/repeat-string/-/repeat-string-1.5.2.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.5.2.tgz"
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"name": "fill-range",
|
||||
"description": "Fill in a range of numbers or letters, optionally passing an increment or multiplier to use.",
|
||||
"version": "2.2.2",
|
||||
"homepage": "https://github.com/jonschlinkert/fill-range",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/fill-range.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/fill-range/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/fill-range/blob/master/LICENSE"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"dependencies": {
|
||||
"is-number": "^1.1.2",
|
||||
"isobject": "^1.0.0",
|
||||
"randomatic": "^1.1.0",
|
||||
"repeat-element": "^1.1.0",
|
||||
"repeat-string": "^1.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmarked": "^0.1.3",
|
||||
"chalk": "^0.5.1",
|
||||
"should": "*"
|
||||
},
|
||||
"keywords": [
|
||||
"alpha",
|
||||
"alphabetical",
|
||||
"bash",
|
||||
"brace",
|
||||
"expand",
|
||||
"expansion",
|
||||
"glob",
|
||||
"match",
|
||||
"matches",
|
||||
"matching",
|
||||
"number",
|
||||
"numerical",
|
||||
"range",
|
||||
"ranges",
|
||||
"sh"
|
||||
],
|
||||
"gitHead": "dafcb07a8cb9d8138543234fde0cc92340248cb1",
|
||||
"_id": "fill-range@2.2.2",
|
||||
"_shasum": "2ad9d158a6a666f9fb8c9f9f05345dff68d45760",
|
||||
"_from": "fill-range@>=2.1.0 <3.0.0",
|
||||
"_npmVersion": "2.5.1",
|
||||
"_nodeVersion": "0.12.0",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
{
|
||||
"name": "doowb",
|
||||
"email": "brian.woodward@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "es128",
|
||||
"email": "elan.shanker+npm@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "2ad9d158a6a666f9fb8c9f9f05345dff68d45760",
|
||||
"tarball": "http://registry.npmjs.org/fill-range/-/fill-range-2.2.2.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.2.tgz"
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
{
|
||||
"name": "expand-range",
|
||||
"description": "Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See the benchmarks. Used by micromatch.",
|
||||
"version": "1.8.1",
|
||||
"homepage": "https://github.com/jonschlinkert/expand-range",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/expand-range.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/expand-range/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/expand-range/blob/master/LICENSE-MIT"
|
||||
},
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"fill-range": "^2.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmarked": "^0.1.1",
|
||||
"brace-expansion": "^1.1.0",
|
||||
"glob": "^4.3.2",
|
||||
"minimatch": "^2.0.1",
|
||||
"mocha": "*",
|
||||
"should": "^4.1.0"
|
||||
},
|
||||
"keywords": [
|
||||
"alpha",
|
||||
"alphabetical",
|
||||
"bash",
|
||||
"brace",
|
||||
"expand",
|
||||
"expansion",
|
||||
"glob",
|
||||
"match",
|
||||
"matches",
|
||||
"matching",
|
||||
"number",
|
||||
"numerical",
|
||||
"range",
|
||||
"ranges",
|
||||
"sh"
|
||||
],
|
||||
"gitHead": "de01a2ae06e6fe9c69812595c439870cca71839f",
|
||||
"_id": "expand-range@1.8.1",
|
||||
"_shasum": "acbd63e56efd9139722b755f099b9db5ac1f33f6",
|
||||
"_from": "expand-range@>=1.8.1 <2.0.0",
|
||||
"_npmVersion": "2.5.1",
|
||||
"_nodeVersion": "0.12.0",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "acbd63e56efd9139722b755f099b9db5ac1f33f6",
|
||||
"tarball": "http://registry.npmjs.org/expand-range/-/expand-range-1.8.1.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.1.tgz"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,92 @@
|
||||
# lazy-cache [](http://badge.fury.io/js/lazy-cache)
|
||||
|
||||
> Cache requires to be lazy-loaded when needed.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i lazy-cache --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var lazy = require('lazy-cache')(require);
|
||||
```
|
||||
|
||||
**Use as a property on `lazy`**
|
||||
|
||||
The module is also added as a property to the `lazy` function
|
||||
so it can be called without having to call a function first.
|
||||
|
||||
```js
|
||||
var lazy = require('lazy-cache')(require);
|
||||
|
||||
// `npm install glob`
|
||||
lazy('glob');
|
||||
|
||||
// glob sync
|
||||
console.log(lazy.glob.sync('*.js'));
|
||||
|
||||
// glob async
|
||||
lazy.glob('*.js', function (err, files) {
|
||||
console.log(files);
|
||||
});
|
||||
```
|
||||
|
||||
**Use as a function**
|
||||
|
||||
```js
|
||||
var lazy = require('lazy-cache')(require);
|
||||
var glob = lazy('glob');
|
||||
|
||||
// `glob` is a now a function that may be called when needed
|
||||
glob().sync('foo/*.js');
|
||||
```
|
||||
|
||||
## Aliases
|
||||
|
||||
An alias may be passed as the second argument if you don't want to use the automatically camel-cased variable name.
|
||||
|
||||
**Example**
|
||||
|
||||
```js
|
||||
var lazy = require('lazy-cache')(require);
|
||||
|
||||
lazy('ansi-yellow', 'yellow');
|
||||
console.log(lazy.yellow('foo'));
|
||||
```
|
||||
|
||||
## Related
|
||||
|
||||
[lint-deps](https://github.com/jonschlinkert/lint-deps): CLI tool that tells you when dependencies are missing from package.json and offers you a… [more](https://github.com/jonschlinkert/lint-deps)
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/lazy-cache/issues/new)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2015 Jon Schlinkert
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on August 19, 2015._
|
||||
@@ -0,0 +1,62 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Cache results of the first function call to ensure only calling once.
|
||||
*
|
||||
* ```js
|
||||
* var lazy = require('lazy-cache')(require);
|
||||
* // cache the call to `require('ansi-yellow')`
|
||||
* lazy('ansi-yellow', 'yellow');
|
||||
* // use `ansi-yellow`
|
||||
* console.log(lazy.yellow('this is yellow'));
|
||||
* ```
|
||||
*
|
||||
* @param {Function} `fn` Function that will be called only once.
|
||||
* @return {Function} Function that can be called to get the cached function
|
||||
* @api public
|
||||
*/
|
||||
|
||||
function lazyCache(fn) {
|
||||
var cache = {};
|
||||
var proxy = function (mod, name) {
|
||||
name = name || camelcase(mod);
|
||||
Object.defineProperty(proxy, name, {
|
||||
get: getter
|
||||
});
|
||||
|
||||
function getter () {
|
||||
if (cache.hasOwnProperty(name)) {
|
||||
return cache[name];
|
||||
}
|
||||
try {
|
||||
return (cache[name] = fn(mod));
|
||||
} catch (err) {
|
||||
err.message = 'lazy-cache ' + err.message + ' ' + __filename;
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
return getter;
|
||||
};
|
||||
return proxy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to camelcase the name to be stored on the `lazy` object.
|
||||
*
|
||||
* @param {String} `str` String containing `_`, `.`, `-` or whitespace that will be camelcased.
|
||||
* @return {String} camelcased string.
|
||||
*/
|
||||
|
||||
function camelcase(str) {
|
||||
if (str.length === 1) { return str.toLowerCase(); }
|
||||
str = str.replace(/^[\W_]+|[\W_]+$/g, '').toLowerCase();
|
||||
return str.replace(/[\W_]+(\w|$)/g, function (_, ch) {
|
||||
return ch.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Expose `lazyCache`
|
||||
*/
|
||||
|
||||
module.exports = lazyCache;
|
||||
@@ -0,0 +1,75 @@
|
||||
{
|
||||
"name": "lazy-cache",
|
||||
"description": "Cache requires to be lazy-loaded when needed.",
|
||||
"version": "0.2.3",
|
||||
"homepage": "https://github.com/jonschlinkert/lazy-cache",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/lazy-cache.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/lazy-cache/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ansi-yellow": "^0.1.1",
|
||||
"glob": "^5.0.14",
|
||||
"mocha": "*"
|
||||
},
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"dependencies",
|
||||
"dependency",
|
||||
"lazy",
|
||||
"require",
|
||||
"requires"
|
||||
],
|
||||
"verb": {
|
||||
"related": {
|
||||
"list": [
|
||||
"lint-deps"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gitHead": "a25332b0e118340af776729423135a198f10783d",
|
||||
"_id": "lazy-cache@0.2.3",
|
||||
"_shasum": "0f30be62cce1e025039f921efde5cce31f2625c8",
|
||||
"_from": "lazy-cache@>=0.2.3 <0.3.0",
|
||||
"_npmVersion": "2.10.1",
|
||||
"_nodeVersion": "0.12.4",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
{
|
||||
"name": "doowb",
|
||||
"email": "brian.woodward@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "0f30be62cce1e025039f921efde5cce31f2625c8",
|
||||
"tarball": "http://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.3.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-0.2.3.tgz"
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
# Enforce Unix newlines
|
||||
*.* text eol=lf
|
||||
*.css text eol=lf
|
||||
*.html text eol=lf
|
||||
*.js text eol=lf
|
||||
*.json text eol=lf
|
||||
*.less text eol=lf
|
||||
*.md text eol=lf
|
||||
*.yml text eol=lf
|
||||
|
||||
*.jpg binary
|
||||
*.gif binary
|
||||
*.png binary
|
||||
*.jpeg binary
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"asi": false,
|
||||
"boss": true,
|
||||
"curly": true,
|
||||
"eqeqeq": true,
|
||||
"eqnull": true,
|
||||
"esnext": true,
|
||||
"immed": true,
|
||||
"latedef": true,
|
||||
"laxcomma": false,
|
||||
"newcap": true,
|
||||
"noarg": true,
|
||||
"node": true,
|
||||
"sub": true,
|
||||
"undef": true,
|
||||
"unused": true,
|
||||
"globals": {
|
||||
"define": true,
|
||||
"before": true,
|
||||
"after": true,
|
||||
"describe": true,
|
||||
"it": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
# Numerous always-ignore extensions
|
||||
*.csv
|
||||
*.dat
|
||||
*.diff
|
||||
*.err
|
||||
*.gz
|
||||
*.log
|
||||
*.orig
|
||||
*.out
|
||||
*.pid
|
||||
*.rar
|
||||
*.rej
|
||||
*.seed
|
||||
*.swo
|
||||
*.swp
|
||||
*.vi
|
||||
*.yo-rc.json
|
||||
*.zip
|
||||
*~
|
||||
.ruby-version
|
||||
lib-cov
|
||||
npm-debug.log
|
||||
|
||||
# Always-ignore dirs
|
||||
/bower_components/
|
||||
/node_modules/
|
||||
/temp/
|
||||
/tmp/
|
||||
/vendor/
|
||||
_gh_pages
|
||||
|
||||
# OS or Editor folders
|
||||
*.esproj
|
||||
*.komodoproject
|
||||
.komodotools
|
||||
*.sublime-*
|
||||
._*
|
||||
.cache
|
||||
.DS_Store
|
||||
.idea
|
||||
.project
|
||||
.settings
|
||||
.tmproj
|
||||
nbproject
|
||||
Thumbs.db
|
||||
|
||||
# grunt-html-validation
|
||||
validation-status.json
|
||||
validation-report.json
|
||||
|
||||
# misc
|
||||
TODO.md
|
||||
benchmark
|
||||
@@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- '0.10'
|
||||
@@ -0,0 +1,59 @@
|
||||
# {%= name %} {%= badge("fury") %}
|
||||
|
||||
> {%= description %}
|
||||
|
||||
Useful for protecting tokens, like templates in HTML, from being mutated when the string is transformed in some way, like from a formatter/beautifier.
|
||||
|
||||
**Example without `preserve`**
|
||||
|
||||
Let's say you want to use [js-beautify] on a string of html with Lo-Dash/Underscore templates, such as: `<ul><li><%= name %></li></ul>`:
|
||||
|
||||
js-beautify will render the template unusable (and apply incorrect formatting because of the unfamiliar syntax from the Lo-Dash template):
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li>
|
||||
<%=n ame %>
|
||||
</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
**Example with `preserve`**
|
||||
|
||||
Correct.
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li><%= name %></li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
For the record, this is just a random example, I've had very few issues with js-beautify in general. But with or without js-beautify, this kind of token mangling does happen sometimes when you use formatters, beautifiers or similar tools.
|
||||
|
||||
## Install
|
||||
{%= include("install-npm", {save: true}) %}
|
||||
|
||||
## Run tests
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
## API
|
||||
{%= apidocs("index.js") %}
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue]({%= bugs.url %})
|
||||
|
||||
## Author
|
||||
{%= include("author") %}
|
||||
|
||||
## License
|
||||
{%= copyright() %}
|
||||
{%= license() %}
|
||||
|
||||
***
|
||||
|
||||
{%= include("footer") %}
|
||||
|
||||
[js-beautify]: https://github.com/beautify-web/js-beautify
|
||||
@@ -0,0 +1,24 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -0,0 +1,90 @@
|
||||
# preserve [](http://badge.fury.io/js/preserve)
|
||||
|
||||
> Temporarily substitute tokens in the given `string` with placeholders, then put them back after transforming the string.
|
||||
|
||||
Useful for protecting tokens, like templates in HTML, from being mutated when the string is transformed in some way, like from a formatter/beautifier.
|
||||
|
||||
**Example without `preserve`**
|
||||
|
||||
Let's say you want to use [js-beautify] on a string of html with Lo-Dash/Underscore templates, such as: `<ul><li><%= name %></li></ul>`:
|
||||
|
||||
js-beautify will render the template unusable (and apply incorrect formatting because of the unfamiliar syntax from the Lo-Dash template):
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li>
|
||||
<%=n ame %>
|
||||
</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
**Example with `preserve`**
|
||||
|
||||
Correct.
|
||||
|
||||
```html
|
||||
<ul>
|
||||
<li><%= name %></li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
For the record, this is just a random example, I've had very few issues with js-beautify in general. But with or without js-beautify, this kind of token mangling does happen sometimes when you use formatters, beautifiers or similar tools.
|
||||
|
||||
## Install
|
||||
## Install with [npm](npmjs.org)
|
||||
|
||||
```bash
|
||||
npm i preserve --save
|
||||
```
|
||||
|
||||
## Run tests
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
## API
|
||||
### [.before](index.js#L23)
|
||||
|
||||
Replace tokens in `str` with a temporary, heuristic placeholder.
|
||||
|
||||
* `str` **{String}**
|
||||
* `returns` **{String}**: String with placeholders.
|
||||
|
||||
```js
|
||||
tokens.before('{a\\,b}');
|
||||
//=> '{__ID1__}'
|
||||
```
|
||||
|
||||
### [.after](index.js#L44)
|
||||
|
||||
Replace placeholders in `str` with original tokens.
|
||||
|
||||
* `str` **{String}**: String with placeholders
|
||||
* `returns` **{String}** `str`: String with original tokens.
|
||||
|
||||
```js
|
||||
tokens.after('{__ID1__}');
|
||||
//=> '{a\\,b}'
|
||||
```
|
||||
|
||||
|
||||
## Contributing
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/preserve/issues)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
Copyright (c) 2015-2015, Jon Schlinkert.
|
||||
Released under the MIT license
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb](https://github.com/assemble/verb) on January 10, 2015._
|
||||
|
||||
[js-beautify]: https://github.com/beautify-web/js-beautify
|
||||
@@ -0,0 +1,54 @@
|
||||
/*!
|
||||
* preserve <https://github.com/jonschlinkert/preserve>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Replace tokens in `str` with a temporary, heuristic placeholder.
|
||||
*
|
||||
* ```js
|
||||
* tokens.before('{a\\,b}');
|
||||
* //=> '{__ID1__}'
|
||||
* ```
|
||||
*
|
||||
* @param {String} `str`
|
||||
* @return {String} String with placeholders.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.before = function before(str, re) {
|
||||
return str.replace(re, function (match) {
|
||||
var id = randomize();
|
||||
cache[id] = match;
|
||||
return '__ID' + id + '__';
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Replace placeholders in `str` with original tokens.
|
||||
*
|
||||
* ```js
|
||||
* tokens.after('{__ID1__}');
|
||||
* //=> '{a\\,b}'
|
||||
* ```
|
||||
*
|
||||
* @param {String} `str` String with placeholders
|
||||
* @return {String} `str` String with original tokens.
|
||||
* @api public
|
||||
*/
|
||||
|
||||
exports.after = function after(str) {
|
||||
return str.replace(/__ID(.{5})__/g, function (_, id) {
|
||||
return cache[id];
|
||||
});
|
||||
};
|
||||
|
||||
function randomize() {
|
||||
return Math.random().toString().slice(2, 7);
|
||||
}
|
||||
|
||||
var cache = {};
|
||||
@@ -0,0 +1,69 @@
|
||||
{
|
||||
"name": "preserve",
|
||||
"description": "Temporarily substitute tokens in the given `string` with placeholders, then put them back after transforming the string.",
|
||||
"version": "0.2.0",
|
||||
"homepage": "https://github.com/jonschlinkert/preserve",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/preserve.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/preserve/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/preserve/blob/master/LICENSE-MIT"
|
||||
},
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha -R spec"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmarked": "^0.1.3",
|
||||
"chalk": "^0.5.1",
|
||||
"js-beautify": "^1.5.4",
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
},
|
||||
"keywords": [
|
||||
"escape",
|
||||
"format",
|
||||
"placeholder",
|
||||
"placeholders",
|
||||
"prettify",
|
||||
"regex",
|
||||
"replace",
|
||||
"template",
|
||||
"templates",
|
||||
"token",
|
||||
"tokens"
|
||||
],
|
||||
"gitHead": "1bf405d35e4aea06a2ee83db2d34dc54abc0a1f9",
|
||||
"_id": "preserve@0.2.0",
|
||||
"_shasum": "815ed1f6ebc65926f865b310c0713bcb3315ce4b",
|
||||
"_from": "preserve@>=0.2.0 <0.3.0",
|
||||
"_npmVersion": "1.4.23",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "815ed1f6ebc65926f865b310c0713bcb3315ce4b",
|
||||
"tarball": "http://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz"
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*!
|
||||
* preserve <https://github.com/jonschlinkert/preserve>
|
||||
*
|
||||
* Copyright (c) 2014-2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var should = require('should');
|
||||
var tokens = require('./');
|
||||
|
||||
var re = /<%=\s*[^>]+%>/g;
|
||||
var pretty = function(str) {
|
||||
return require('js-beautify').html(str, {
|
||||
indent_char: ' ',
|
||||
indent_size: 2,
|
||||
});
|
||||
};
|
||||
|
||||
describe('preserve tokens', function () {
|
||||
var testRe = /__ID.{5}__\n__ID.{5}__\n__ID.{5}__/;
|
||||
var re = /<%=\s*[^>]+%>/g;
|
||||
|
||||
it('should (e.g. shouldn\'t, but will) mangle tokens in the given string', function () {
|
||||
var html = pretty('<ul><li><%= name %></li></ul>');
|
||||
html.should.equal('<ul>\n <li>\n <%=n ame %>\n </li>\n</ul>');
|
||||
});
|
||||
|
||||
it('should preserve tokens in the given string', function () {
|
||||
var html = tokens.after(pretty(tokens.before('<ul><li><%= name %></li></ul>', re)));
|
||||
html.should.equal('<ul>\n <li><%= name %></li>\n</ul>');
|
||||
});
|
||||
|
||||
describe('.before()', function () {
|
||||
it('should replace matches with placeholder tokens:', function () {
|
||||
tokens.before('<%= a %>\n<%= b %>\n<%= c %>', re).should.match(testRe);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tokens.after()', function () {
|
||||
it('should replace placeholder tokens with original values:', function () {
|
||||
var before = tokens.before('<%= a %>\n<%= b %>\n<%= c %>', re);
|
||||
before.should.match(testRe);
|
||||
tokens.after(before).should.equal('<%= a %>\n<%= b %>\n<%= c %>');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,71 @@
|
||||
# repeat-element [](http://badge.fury.io/js/repeat-element)
|
||||
|
||||
> Create an array by repeating the given value n times.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```bash
|
||||
npm i repeat-element --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var repeat = require('repeat-element');
|
||||
|
||||
repeat('a', 5);
|
||||
//=> ['a', 'a', 'a', 'a', 'a']
|
||||
|
||||
repeat('a', 1);
|
||||
//=> ['a']
|
||||
|
||||
repeat('a', 0);
|
||||
//=> []
|
||||
|
||||
repeat(null, 5)
|
||||
//» [ null, null, null, null, null ]
|
||||
|
||||
repeat({some: 'object'}, 5)
|
||||
//» [ { some: 'object' },
|
||||
// { some: 'object' },
|
||||
// { some: 'object' },
|
||||
// { some: 'object' },
|
||||
// { some: 'object' } ]
|
||||
|
||||
repeat(5, 5)
|
||||
//» [ 5, 5, 5, 5, 5 ]
|
||||
```
|
||||
|
||||
## Related projects
|
||||
|
||||
[repeat-string](https://github.com/jonschlinkert/repeat-string): Repeat the given string n times. Fastest implementation for repeating a string.
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```bash
|
||||
npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/repeat-element/issues)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on May 06, 2015._
|
||||
@@ -0,0 +1,18 @@
|
||||
/*!
|
||||
* repeat-element <https://github.com/jonschlinkert/repeat-element>
|
||||
*
|
||||
* Copyright (c) 2015 Jon Schlinkert.
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = function repeat(ele, num) {
|
||||
var arr = new Array(num);
|
||||
|
||||
for (var i = 0; i < num; i++) {
|
||||
arr[i] = ele;
|
||||
}
|
||||
|
||||
return arr;
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"name": "repeat-element",
|
||||
"description": "Create an array by repeating the given value n times.",
|
||||
"version": "1.1.2",
|
||||
"homepage": "https://github.com/jonschlinkert/repeat-element",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/jonschlinkert/repeat-element.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/repeat-element/issues"
|
||||
},
|
||||
"license": {
|
||||
"type": "MIT",
|
||||
"url": "https://github.com/jonschlinkert/repeat-element/blob/master/LICENSE"
|
||||
},
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"keywords": [
|
||||
"array",
|
||||
"element",
|
||||
"repeat",
|
||||
"string"
|
||||
],
|
||||
"devDependencies": {
|
||||
"benchmarked": "^0.1.4",
|
||||
"chalk": "^1.0.0",
|
||||
"glob": "^5.0.5",
|
||||
"minimist": "^1.1.1",
|
||||
"mocha": "^2.2.4"
|
||||
},
|
||||
"gitHead": "7a6b21d58eafcc44fc8de133c70a8398ee9fdd8d",
|
||||
"_id": "repeat-element@1.1.2",
|
||||
"_shasum": "ef089a178d1483baae4d93eb98b4f9e4e11d990a",
|
||||
"_from": "repeat-element@>=1.1.2 <2.0.0",
|
||||
"_npmVersion": "2.5.1",
|
||||
"_nodeVersion": "0.12.0",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "ef089a178d1483baae4d93eb98b4f9e4e11d990a",
|
||||
"tarball": "http://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz"
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
{
|
||||
"name": "braces",
|
||||
"description": "Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces specification.",
|
||||
"version": "1.8.1",
|
||||
"homepage": "https://github.com/jonschlinkert/braces",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/braces.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/braces/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"expand-range": "^1.8.1",
|
||||
"lazy-cache": "^0.2.3",
|
||||
"preserve": "^0.2.0",
|
||||
"repeat-element": "^1.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"benchmarked": "^0.1.3",
|
||||
"brace-expansion": "^1.1.0",
|
||||
"chalk": "^0.5.1",
|
||||
"minimatch": "^2.0.1",
|
||||
"minimist": "^1.1.0",
|
||||
"mocha": "*",
|
||||
"should": "*"
|
||||
},
|
||||
"keywords": [
|
||||
"alpha",
|
||||
"alphabetical",
|
||||
"bash",
|
||||
"brace",
|
||||
"expand",
|
||||
"expansion",
|
||||
"filepath",
|
||||
"fill",
|
||||
"fs",
|
||||
"glob",
|
||||
"globbing",
|
||||
"letter",
|
||||
"match",
|
||||
"matches",
|
||||
"matching",
|
||||
"number",
|
||||
"numerical",
|
||||
"path",
|
||||
"range",
|
||||
"ranges",
|
||||
"sh"
|
||||
],
|
||||
"gitHead": "04aa03dccdadaf469bb7cad86ac8a31d21e974d7",
|
||||
"_id": "braces@1.8.1",
|
||||
"_shasum": "2d195b85a0a997ec21be78a7f1bc970480b12a1a",
|
||||
"_from": "braces@>=1.8.0 <2.0.0",
|
||||
"_npmVersion": "2.10.1",
|
||||
"_nodeVersion": "0.12.4",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
{
|
||||
"name": "es128",
|
||||
"email": "elan.shanker+npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "doowb",
|
||||
"email": "brian.woodward@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "2d195b85a0a997ec21be78a7f1bc970480b12a1a",
|
||||
"tarball": "http://registry.npmjs.org/braces/-/braces-1.8.1.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/braces/-/braces-1.8.1.tgz"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Jon Schlinkert
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,89 @@
|
||||
# expand-brackets [](http://badge.fury.io/js/expand-brackets)
|
||||
|
||||
> Expand POSIX bracket expressions (character classes) in glob patterns.
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i expand-brackets --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var brackets = require('expand-brackets');
|
||||
|
||||
brackets('[![:lower:]]');
|
||||
//=> '[^a-z]'
|
||||
```
|
||||
|
||||
## .isMatch
|
||||
|
||||
Return true if the given string matches the bracket expression:
|
||||
|
||||
```js
|
||||
brackets.isMatch('A', '[![:lower:]]');
|
||||
//=> true
|
||||
|
||||
brackets.isMatch('a', '[![:lower:]]');
|
||||
//=> false
|
||||
```
|
||||
|
||||
## .makeRe
|
||||
|
||||
Make a regular expression from a bracket expression:
|
||||
|
||||
```js
|
||||
brackets.makeRe('[![:lower:]]');
|
||||
//=> /[^a-z]/
|
||||
```
|
||||
|
||||
The following named POSIX bracket expressions are supported:
|
||||
|
||||
* `[:alnum:]`: Alphanumeric characters (`a-zA-Z0-9]`)
|
||||
* `[:alpha:]`: Alphabetic characters (`a-zA-Z]`)
|
||||
* `[:blank:]`: Space and tab (`[ t]`)
|
||||
* `[:digit:]`: Digits (`[0-9]`)
|
||||
* `[:lower:]`: Lowercase letters (`[a-z]`)
|
||||
* `[:punct:]`: Punctuation and symbols. (`[!"#$%&'()*+, -./:;<=>?@ [\]^_``{|}~]`)
|
||||
* `[:upper:]`: Uppercase letters (`[A-Z]`)
|
||||
* `[:word:]`: Word characters (letters, numbers and underscores) (`[A-Za-z0-9_]`)
|
||||
* `[:xdigit:]`: Hexadecimal digits (`[A-Fa-f0-9]`)
|
||||
|
||||
Collating sequences are not supported.
|
||||
|
||||
## Related projects
|
||||
|
||||
* [extglob](https://github.com/jonschlinkert/extglob): Convert extended globs to regex-compatible strings. Add (almost) the expressive power of regular expressions to… [more](https://github.com/jonschlinkert/extglob)
|
||||
* [is-glob](https://github.com/jonschlinkert/is-glob): Returns `true` if the given string looks like a glob pattern.
|
||||
* [is-extglob](https://github.com/jonschlinkert/is-extglob): Returns true if a string has an extglob.
|
||||
* [is-posix-bracket](https://github.com/jonschlinkert/is-posix-bracket): Returns true if the given string is a POSIX bracket expression (POSIX character class).
|
||||
* [micromatch](https://github.com/jonschlinkert/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://github.com/jonschlinkert/micromatch)
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/expand-brackets/issues/new)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2015 Jon Schlinkert
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on August 01, 2015._
|
||||
@@ -0,0 +1,157 @@
|
||||
/*!
|
||||
* expand-brackets <https://github.com/jonschlinkert/expand-brackets>
|
||||
*
|
||||
* Copyright (c) 2015 Jon Schlinkert.
|
||||
* Licensed under the MIT license.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* POSIX character classes
|
||||
*/
|
||||
|
||||
var POSIX = {
|
||||
alnum: 'a-zA-Z0-9',
|
||||
alpha: 'a-zA-Z',
|
||||
blank: ' \\t',
|
||||
cntrl: '\\x00-\\x1F\\x7F',
|
||||
digit: '0-9',
|
||||
graph: '\\x21-\\x7E',
|
||||
lower: 'a-z',
|
||||
print: '\\x20-\\x7E',
|
||||
punct: '!"#$%&\'()\\*+,-./:;<=>?@[\\]^_`{|}~',
|
||||
space: ' \\t\\r\\n\\v\\f',
|
||||
upper: 'A-Z',
|
||||
word: 'A-Za-z0-9_',
|
||||
xdigit: 'A-Fa-f0-9',
|
||||
};
|
||||
|
||||
/**
|
||||
* Expose `brackets`
|
||||
*/
|
||||
|
||||
module.exports = brackets;
|
||||
|
||||
function brackets(str) {
|
||||
var negated = false;
|
||||
if (str.indexOf('[^') !== -1) {
|
||||
negated = true;
|
||||
str = str.split('[^').join('[');
|
||||
}
|
||||
if (str.indexOf('[!') !== -1) {
|
||||
negated = true;
|
||||
str = str.split('[!').join('[');
|
||||
}
|
||||
|
||||
var a = str.split('[');
|
||||
var b = str.split(']');
|
||||
var imbalanced = a.length !== b.length;
|
||||
|
||||
var parts = str.split(/(?::\]\[:|\[?\[:|:\]\]?)/);
|
||||
var len = parts.length, i = 0;
|
||||
var end = '', beg = '';
|
||||
var res = [];
|
||||
|
||||
// start at the end (innermost) first
|
||||
while (len--) {
|
||||
var inner = parts[i++];
|
||||
if (inner === '^[!' || inner === '[!') {
|
||||
inner = '';
|
||||
negated = true;
|
||||
}
|
||||
|
||||
var prefix = negated ? '^' : '';
|
||||
var ch = POSIX[inner];
|
||||
|
||||
if (ch) {
|
||||
res.push('[' + prefix + ch + ']');
|
||||
} else if (inner) {
|
||||
if (/^\[?\w-\w\]?$/.test(inner)) {
|
||||
if (i === parts.length) {
|
||||
res.push('[' + prefix + inner);
|
||||
} else if (i === 1) {
|
||||
res.push(prefix + inner + ']');
|
||||
} else {
|
||||
res.push(prefix + inner);
|
||||
}
|
||||
} else {
|
||||
if (i === 1) {
|
||||
beg += inner;
|
||||
} else if (i === parts.length) {
|
||||
end += inner;
|
||||
} else {
|
||||
res.push('[' + prefix + inner + ']');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var result = res.join('|');
|
||||
var rlen = res.length || 1;
|
||||
if (rlen > 1) {
|
||||
result = '(?:' + result + ')';
|
||||
rlen = 1;
|
||||
}
|
||||
if (beg) {
|
||||
rlen++;
|
||||
if (beg.charAt(0) === '[') {
|
||||
if (imbalanced) {
|
||||
beg = '\\[' + beg.slice(1);
|
||||
} else {
|
||||
beg += ']';
|
||||
}
|
||||
}
|
||||
result = beg + result;
|
||||
}
|
||||
if (end) {
|
||||
rlen++;
|
||||
if (end.slice(-1) === ']') {
|
||||
if (imbalanced) {
|
||||
end = end.slice(0, end.length - 1) + '\\]';
|
||||
} else {
|
||||
end = '[' + end;
|
||||
}
|
||||
}
|
||||
result += end;
|
||||
}
|
||||
|
||||
if (rlen > 1) {
|
||||
result = result.split('][').join(']|[');
|
||||
if (result.indexOf('|') !== -1 && !/\(\?/.test(result)) {
|
||||
result = '(?:' + result + ')';
|
||||
}
|
||||
}
|
||||
|
||||
result = result.replace(/\[+=|=\]+/g, '\\b');
|
||||
return result;
|
||||
}
|
||||
|
||||
brackets.makeRe = function (pattern) {
|
||||
try {
|
||||
return new RegExp(brackets(pattern));
|
||||
} catch (err) {}
|
||||
};
|
||||
|
||||
brackets.isMatch = function (str, pattern) {
|
||||
try {
|
||||
return brackets.makeRe(pattern).test(str);
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
brackets.match = function (arr, pattern) {
|
||||
var len = arr.length, i = 0;
|
||||
var res = arr.slice();
|
||||
|
||||
var re = brackets.makeRe(pattern);
|
||||
while (i < len) {
|
||||
var ele = arr[i++];
|
||||
if (!re.test(ele)) {
|
||||
continue;
|
||||
}
|
||||
res.splice(i, 1);
|
||||
}
|
||||
return res;
|
||||
};
|
||||
@@ -0,0 +1,79 @@
|
||||
{
|
||||
"name": "expand-brackets",
|
||||
"description": "Expand POSIX bracket expressions (character classes) in glob patterns.",
|
||||
"version": "0.1.4",
|
||||
"homepage": "https://github.com/jonschlinkert/expand-brackets",
|
||||
"author": {
|
||||
"name": "Jon Schlinkert",
|
||||
"url": "https://github.com/jonschlinkert"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/jonschlinkert/expand-brackets.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/jonschlinkert/expand-brackets/issues"
|
||||
},
|
||||
"license": "MIT",
|
||||
"files": [
|
||||
"index.js"
|
||||
],
|
||||
"main": "index.js",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^2.2.5",
|
||||
"should": "^7.0.2"
|
||||
},
|
||||
"keywords": [
|
||||
"bracket",
|
||||
"character class",
|
||||
"expression",
|
||||
"posix"
|
||||
],
|
||||
"verb": {
|
||||
"related": {
|
||||
"list": [
|
||||
"extglob",
|
||||
"micromatch",
|
||||
"is-glob",
|
||||
"is-extglob",
|
||||
"is-posix-bracket"
|
||||
]
|
||||
}
|
||||
},
|
||||
"gitHead": "38475d3e4973b8496812e39983d2945a78d0ade3",
|
||||
"_id": "expand-brackets@0.1.4",
|
||||
"_shasum": "797b9e484101205f418cecaec6312c132f51e2ae",
|
||||
"_from": "expand-brackets@>=0.1.1 <0.2.0",
|
||||
"_npmVersion": "2.10.1",
|
||||
"_nodeVersion": "0.12.4",
|
||||
"_npmUser": {
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "jonschlinkert",
|
||||
"email": "github@sellside.com"
|
||||
},
|
||||
{
|
||||
"name": "es128",
|
||||
"email": "elan.shanker+npm@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "doowb",
|
||||
"email": "brian.woodward@gmail.com"
|
||||
}
|
||||
],
|
||||
"dist": {
|
||||
"shasum": "797b9e484101205f418cecaec6312c132f51e2ae",
|
||||
"tarball": "http://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.4.tgz"
|
||||
},
|
||||
"directories": {},
|
||||
"_resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.4.tgz"
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,88 @@
|
||||
# extglob [](http://badge.fury.io/js/extglob) [](https://travis-ci.org/jonschlinkert/extglob)
|
||||
|
||||
> Convert extended globs to regex-compatible strings. Add (almost) the expressive power of regular expressions to glob patterns.
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i extglob --save
|
||||
```
|
||||
|
||||
Used by [micromatch](https://github.com/jonschlinkert/micromatch).
|
||||
|
||||
**Features**
|
||||
|
||||
* Convert an extglob string to a regex-compatible string. **Only converts extglobs**, to handle full globs use [micromatch](https://github.com/jonschlinkert/micromatch).
|
||||
* Pass `{regex: true}` to return a regex
|
||||
* Handles nested patterns
|
||||
* More complete (and correct) support than [minimatch](https://github.com/isaacs/minimatch)
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var extglob = require('extglob');
|
||||
|
||||
extglob('?(z)');
|
||||
//=> '(?:z)?'
|
||||
extglob('*(z)');
|
||||
//=> '(?:z)*'
|
||||
extglob('+(z)');
|
||||
//=> '(?:z)+'
|
||||
extglob('@(z)');
|
||||
//=> '(?:z)'
|
||||
extglob('!(z)');
|
||||
//=> '(?!^(?:(?!z)[^/]*?)).*$'
|
||||
```
|
||||
|
||||
**Optionally return regex**
|
||||
|
||||
```js
|
||||
extglob('!(z)', {regex: true});
|
||||
//=> /(?!^(?:(?!z)[^/]*?)).*$/
|
||||
```
|
||||
|
||||
## Extglob patterns
|
||||
|
||||
To learn more about how extglobs work, see the docs for [Bash pattern matching](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html):
|
||||
|
||||
* `?(pattern)`: Match zero or one occurrence of the given pattern.
|
||||
* `*(pattern)`: Match zero or more occurrences of the given pattern.
|
||||
* `+(pattern)`: Match one or more occurrences of the given pattern.
|
||||
* `@(pattern)`: Match one of the given pattern.
|
||||
* `!(pattern)`: Match anything except one of the given pattern.
|
||||
|
||||
## Related
|
||||
|
||||
* [braces](https://github.com/jonschlinkert/braces): Fastest brace expansion for node.js, with the most complete support for the Bash 4.3 braces… [more](https://github.com/jonschlinkert/braces)
|
||||
* [expand-brackets](https://github.com/jonschlinkert/expand-brackets): Expand POSIX bracket expressions (character classes) in glob patterns.
|
||||
* [expand-range](https://github.com/jonschlinkert/expand-range): Fast, bash-like range expansion. Expand a range of numbers or letters, uppercase or lowercase. See… [more](https://github.com/jonschlinkert/expand-range)
|
||||
* [fill-range](https://github.com/jonschlinkert/fill-range): Fill in a range of numbers or letters, optionally passing an increment or multiplier to… [more](https://github.com/jonschlinkert/fill-range)
|
||||
* [micromatch](https://github.com/jonschlinkert/micromatch): Glob matching for javascript/node.js. A drop-in replacement and faster alternative to minimatch and multimatch. Just… [more](https://github.com/jonschlinkert/micromatch)
|
||||
|
||||
## Run tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/extglob/issues/new)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2015 Jon Schlinkert
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on August 01, 2015._
|
||||
@@ -0,0 +1,178 @@
|
||||
/*!
|
||||
* extglob <https://github.com/jonschlinkert/extglob>
|
||||
*
|
||||
* Copyright (c) 2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Module dependencies
|
||||
*/
|
||||
|
||||
var isExtglob = require('is-extglob');
|
||||
var re, cache = {};
|
||||
|
||||
/**
|
||||
* Expose `extglob`
|
||||
*/
|
||||
|
||||
module.exports = extglob;
|
||||
|
||||
/**
|
||||
* Convert the given extglob `string` to a regex-compatible
|
||||
* string.
|
||||
*
|
||||
* ```js
|
||||
* var extglob = require('extglob');
|
||||
* extglob('!(a?(b))');
|
||||
* //=> '(?!a(?:b)?)[^/]*?'
|
||||
* ```
|
||||
*
|
||||
* @param {String} `str` The string to convert.
|
||||
* @param {Object} `options`
|
||||
* @option {Boolean} [options] `esc` If `false` special characters will not be escaped. Defaults to `true`.
|
||||
* @option {Boolean} [options] `regex` If `true` a regular expression is returned instead of a string.
|
||||
* @return {String}
|
||||
* @api public
|
||||
*/
|
||||
|
||||
|
||||
function extglob(str, opts) {
|
||||
opts = opts || {};
|
||||
var o = {}, i = 0;
|
||||
|
||||
// fix common character reversals
|
||||
// '*!(.js)' => '*.!(js)'
|
||||
str = str.replace(/!\(([^\w*()])/g, '$1!(');
|
||||
|
||||
// support file extension negation
|
||||
str = str.replace(/([*\/])\.!\([*]\)/g, function (m, ch) {
|
||||
if (ch === '/') {
|
||||
return escape('\\/[^.]+');
|
||||
}
|
||||
return escape('[^.]+');
|
||||
});
|
||||
|
||||
// create a unique key for caching by
|
||||
// combining the string and options
|
||||
var key = str
|
||||
+ String(!!opts.regex)
|
||||
+ String(!!opts.contains)
|
||||
+ String(!!opts.escape);
|
||||
|
||||
if (cache.hasOwnProperty(key)) {
|
||||
return cache[key];
|
||||
}
|
||||
|
||||
if (!(re instanceof RegExp)) {
|
||||
re = regex();
|
||||
}
|
||||
|
||||
opts.negate = false;
|
||||
var m;
|
||||
|
||||
while (m = re.exec(str)) {
|
||||
var prefix = m[1];
|
||||
var inner = m[3];
|
||||
if (prefix === '!') {
|
||||
opts.negate = true;
|
||||
}
|
||||
|
||||
var id = '__EXTGLOB_' + (i++) + '__';
|
||||
// use the prefix of the _last_ (outtermost) pattern
|
||||
o[id] = wrap(inner, prefix, opts.escape);
|
||||
str = str.split(m[0]).join(id);
|
||||
}
|
||||
|
||||
var keys = Object.keys(o);
|
||||
var len = keys.length;
|
||||
|
||||
// we have to loop again to allow us to convert
|
||||
// patterns in reverse order (starting with the
|
||||
// innermost/last pattern first)
|
||||
while (len--) {
|
||||
var prop = keys[len];
|
||||
str = str.split(prop).join(o[prop]);
|
||||
}
|
||||
|
||||
var result = opts.regex
|
||||
? toRegex(str, opts.contains, opts.negate)
|
||||
: str;
|
||||
|
||||
result = result.split('.').join('\\.');
|
||||
|
||||
// cache the result and return it
|
||||
return (cache[key] = result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert `string` to a regex string.
|
||||
*
|
||||
* @param {String} `str`
|
||||
* @param {String} `prefix` Character that determines how to wrap the string.
|
||||
* @param {Boolean} `esc` If `false` special characters will not be escaped. Defaults to `true`.
|
||||
* @return {String}
|
||||
*/
|
||||
|
||||
function wrap(inner, prefix, esc) {
|
||||
if (esc) inner = escape(inner);
|
||||
|
||||
switch (prefix) {
|
||||
case '!':
|
||||
return '(?!' + inner + ')[^/]' + (esc ? '%%%~' : '*?');
|
||||
case '@':
|
||||
return '(?:' + inner + ')';
|
||||
case '+':
|
||||
return '(?:' + inner + ')+';
|
||||
case '*':
|
||||
return '(?:' + inner + ')' + (esc ? '%%' : '*')
|
||||
case '?':
|
||||
return '(?:' + inner + '|)';
|
||||
default:
|
||||
return inner;
|
||||
}
|
||||
}
|
||||
|
||||
function escape(str) {
|
||||
str = str.split('*').join('[^/]%%%~');
|
||||
str = str.split('.').join('\\.');
|
||||
return str;
|
||||
}
|
||||
|
||||
/**
|
||||
* extglob regex.
|
||||
*/
|
||||
|
||||
function regex() {
|
||||
return /(\\?[@?!+*$]\\?)(\(([^()]*?)\))/;
|
||||
}
|
||||
|
||||
/**
|
||||
* Negation regex
|
||||
*/
|
||||
|
||||
function negate(str) {
|
||||
return '(?!^' + str + ').*$';
|
||||
}
|
||||
|
||||
/**
|
||||
* Create the regex to do the matching. If
|
||||
* the leading character in the `pattern` is `!`
|
||||
* a negation regex is returned.
|
||||
*
|
||||
* @param {String} `pattern`
|
||||
* @param {Boolean} `contains` Allow loose matching.
|
||||
* @param {Boolean} `isNegated` True if the pattern is a negation pattern.
|
||||
*/
|
||||
|
||||
function toRegex(pattern, contains, isNegated) {
|
||||
var prefix = contains ? '^' : '';
|
||||
var after = contains ? '$' : '';
|
||||
pattern = ('(?:' + pattern + ')' + after);
|
||||
if (isNegated) {
|
||||
pattern = prefix + negate(pattern);
|
||||
}
|
||||
return new RegExp(prefix + pattern);
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) <%= year() %>, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,14 @@
|
||||
/*!
|
||||
* ansi-green <https://github.com/jonschlinkert/ansi-green>
|
||||
*
|
||||
* Copyright (c) 2015, Jon Schlinkert.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
var wrap = require('ansi-wrap');
|
||||
|
||||
module.exports = function green(message) {
|
||||
return wrap(32, 39, message);
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015, Jon Schlinkert.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,89 @@
|
||||
# ansi-wrap [](http://badge.fury.io/js/ansi-wrap)
|
||||
|
||||
> Create ansi colors by passing the open and close codes.
|
||||
|
||||
## Install
|
||||
|
||||
Install with [npm](https://www.npmjs.com/)
|
||||
|
||||
```sh
|
||||
$ npm i ansi-wrap --save
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
```js
|
||||
var wrap = require('ansi-wrap');
|
||||
```
|
||||
|
||||
**Example**
|
||||
|
||||
Pass codes for [ansi magenta background](https://github.com/jonschlinkert/ansi-bgmagenta):
|
||||
|
||||
```js
|
||||
console.log(wrap(45, 49, 'This is a message...'));
|
||||
//=> '\u001b[45mfoo\u001b[49m'
|
||||
```
|
||||
|
||||
Which prints out...
|
||||
|
||||
[](https://www.npmjs.com/)
|
||||
|
||||
## Related projects
|
||||
|
||||
This is used in these projects:
|
||||
|
||||
* [ansi-reset](https://github.com/jonschlinkert/ansi-reset)
|
||||
* [ansi-bold](https://github.com/jonschlinkert/ansi-bold)
|
||||
* [ansi-dim](https://github.com/jonschlinkert/ansi-dim)
|
||||
* [ansi-italic](https://github.com/jonschlinkert/ansi-italic)
|
||||
* [ansi-underline](https://github.com/jonschlinkert/ansi-underline)
|
||||
* [ansi-inverse](https://github.com/jonschlinkert/ansi-inverse)
|
||||
* [ansi-hidden](https://github.com/jonschlinkert/ansi-hidden)
|
||||
* [ansi-strikethrough](https://github.com/jonschlinkert/ansi-strikethrough)
|
||||
* [ansi-black](https://github.com/jonschlinkert/ansi-black)
|
||||
* [ansi-red](https://github.com/jonschlinkert/ansi-red)
|
||||
* [ansi-green](https://github.com/jonschlinkert/ansi-green)
|
||||
* [ansi-yellow](https://github.com/jonschlinkert/ansi-yellow)
|
||||
* [ansi-blue](https://github.com/jonschlinkert/ansi-blue)
|
||||
* [ansi-magenta](https://github.com/jonschlinkert/ansi-magenta)
|
||||
* [ansi-cyan](https://github.com/jonschlinkert/ansi-cyan)
|
||||
* [ansi-white](https://github.com/jonschlinkert/ansi-white)
|
||||
* [ansi-gray](https://github.com/jonschlinkert/ansi-gray)
|
||||
* [ansi-grey](https://github.com/jonschlinkert/ansi-grey)
|
||||
* [ansi-bgblack](https://github.com/jonschlinkert/ansi-bgblack)
|
||||
* [ansi-bgred](https://github.com/jonschlinkert/ansi-bgred)
|
||||
* [ansi-bggreen](https://github.com/jonschlinkert/ansi-bggreen)
|
||||
* [ansi-bgyellow](https://github.com/jonschlinkert/ansi-bgyellow)
|
||||
* [ansi-bgblue](https://github.com/jonschlinkert/ansi-bgblue)
|
||||
* [ansi-bgmagenta](https://github.com/jonschlinkert/ansi-bgmagenta)
|
||||
* [ansi-bgcyan](https://github.com/jonschlinkert/ansi-bgcyan)
|
||||
* [ansi-bgwhite](https://github.com/jonschlinkert/ansi-bgwhite)
|
||||
|
||||
## Running tests
|
||||
|
||||
Install dev dependencies:
|
||||
|
||||
```sh
|
||||
$ npm i -d && npm test
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](https://github.com/jonschlinkert/ansi-wrap/issues/new)
|
||||
|
||||
## Author
|
||||
|
||||
**Jon Schlinkert**
|
||||
|
||||
+ [github/jonschlinkert](https://github.com/jonschlinkert)
|
||||
+ [twitter/jonschlinkert](http://twitter.com/jonschlinkert)
|
||||
|
||||
## License
|
||||
|
||||
Copyright © 2015 Jon Schlinkert
|
||||
Released under the MIT license.
|
||||
|
||||
***
|
||||
|
||||
_This file was generated by [verb-cli](https://github.com/assemble/verb-cli) on May 21, 2015._
|
||||
@@ -0,0 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function(a, b, msg) {
|
||||
return '\u001b['+ a + 'm' + msg + '\u001b[' + b + 'm';
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user