first commit

This commit is contained in:
Stefan Hacker
2026-04-03 09:38:48 +02:00
commit 37ad745546
47450 changed files with 3120798 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
{
"root": true,
"extends": "eslint:recommended",
"env": {
"node": true,
"es6": true
},
"rules": {
"indent": [2, 2],
"quotes": [1, "single", "avoid-escape"],
"curly": 0,
"strict": [2, "global"],
"no-shadow": 0,
"no-underscore-dangle": 0,
"no-use-before-define": [1, "nofunc"],
"prefer-spread": 1,
"prefer-const": 1,
"no-console": 0,
"no-var": 1
}
}
+2
View File
@@ -0,0 +1,2 @@
node_modules
.idea
+11
View File
@@ -0,0 +1,11 @@
script:
- "npm test"
language: node_js
node_js:
- "4"
- "6"
- "7"
sudo: false
+19
View File
@@ -0,0 +1,19 @@
Copyright (c) 2015 Andreas Madsen
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.
+63
View File
@@ -0,0 +1,63 @@
[![Build Status](https://travis-ci.org/Jeff-Lewis/async-hook-jl.svg?branch=master)](https://travis-ci.org/Jeff-Lewis/async-hook-jl)
#async-hook-jl
> Inspect the life of handle objects in node
## Documentation
This is high level abstraction of the currently undocumented node API called
AsyncWrap. It patches some issues, makes the API more uniform and allows multiply
hooks to be created.
I personally hope that most of this will make it into nodecore, but for now
it exists as an userland module.
For the details of how AsyncWrap works and by extension how this module works,
please see the semi-official AsyncWrap documentation:
https://github.com/nodejs/diagnostics/blob/master/tracing/AsyncWrap/README.md
```javascript
const asyncHook = require('async-hook-jl');
```
#### Hooks
The function arguments are:
```javascript
function init(uid, handle, provider, parentUid, parentHandle) { /* your code */ }
function pre(uid, handle) { /* your code */ }
function post(uid, handle, didThrow) { /* your code */ }
function destroy(uid) { /* your code */ }
```
To add hooks:
```javascript
asyncHook.addHooks({ init, pre, post, destroy });
```
To remove hooks:
```javascript
asyncHooks.removeHooks({ init, pre, post, destroy });
```
All properties in the hooks object that `addHooks` and `removeHooks` takes are
optional.
#### Providers
The providers map is exposed as:
```
asyncHook.providers[provider];
```
#### Enable and disable
You can enable and disable all hooks by using `asyncHook.enable()` and
`asyncHook.disable()`. By default it is disabled.
Be careful about disabling the hooks, this will most likely conflict with other
modules that uses `async-hook-jl`.
+134
View File
@@ -0,0 +1,134 @@
'use strict';
const asyncWrap = process.binding('async_wrap');
const TIMERWRAP = asyncWrap.Providers.TIMERWRAP;
const patchs = {
'nextTick': require('./patches/next-tick.js'),
'promise': require('./patches/promise.js'),
'timers': require('./patches/timers.js')
};
const ignoreUIDs = new Set();
function State() {
this.enabled = false;
this.counter = 0;
}
function Hooks() {
const initFns = this.initFns = [];
const preFns = this.preFns = [];
const postFns = this.postFns = [];
const destroyFns = this.destroyFns = [];
this.init = function (uid, provider, parentUid, parentHandle) {
// Ignore TIMERWRAP, since setTimeout etc. is monkey patched
if (provider === TIMERWRAP) {
ignoreUIDs.add(uid);
return;
}
// call hooks
for (const hook of initFns) {
hook(uid, this, provider, parentUid, parentHandle);
}
};
this.pre = function (uid) {
if (ignoreUIDs.has(uid)) return;
// call hooks
for (const hook of preFns) {
hook(uid, this);
}
};
this.post = function (uid, didThrow) {
if (ignoreUIDs.has(uid)) return;
// call hooks
for (const hook of postFns) {
hook(uid, this, didThrow);
}
};
this.destroy = function (uid) {
// Cleanup the ignore list if this uid should be ignored
if (ignoreUIDs.has(uid)) {
ignoreUIDs.delete(uid);
return;
}
// call hooks
for (const hook of destroyFns) {
hook(uid);
}
};
}
Hooks.prototype.add = function (hooks) {
if (hooks.init) this.initFns.push(hooks.init);
if (hooks.pre) this.preFns.push(hooks.pre);
if (hooks.post) this.postFns.push(hooks.post);
if (hooks.destroy) this.destroyFns.push(hooks.destroy);
};
function removeElement(array, item) {
const index = array.indexOf(item);
if (index === -1) return;
array.splice(index, 1);
}
Hooks.prototype.remove = function (hooks) {
if (hooks.init) removeElement(this.initFns, hooks.init);
if (hooks.pre) removeElement(this.preFns, hooks.pre);
if (hooks.post) removeElement(this.postFns, hooks.post);
if (hooks.destroy) removeElement(this.destroyFns, hooks.destroy);
};
function AsyncHook() {
this._state = new State();
this._hooks = new Hooks();
// expose version for conflict detection
this.version = require('./package.json').version;
// expose the Providers map
this.providers = asyncWrap.Providers;
// apply patches
for (const key of Object.keys(patchs)) {
patchs[key].call(this);
}
// setup async wrap
if (process.env.hasOwnProperty('NODE_ASYNC_HOOK_WARNING')) {
console.warn('warning: you are using async-hook-jl which is unstable.');
}
asyncWrap.setupHooks({
init: this._hooks.init,
pre: this._hooks.pre,
post: this._hooks.post,
destroy: this._hooks.destroy
});
}
module.exports = AsyncHook;
AsyncHook.prototype.addHooks = function (hooks) {
this._hooks.add(hooks);
};
AsyncHook.prototype.removeHooks = function (hooks) {
this._hooks.remove(hooks);
};
AsyncHook.prototype.enable = function () {
this._state.enabled = true;
asyncWrap.enable();
};
AsyncHook.prototype.disable = function () {
this._state.enabled = false;
asyncWrap.disable();
};
+31
View File
@@ -0,0 +1,31 @@
'use strict';
const AsyncHook = require('./async-hook.js');
// If a another copy (same version or not) of stack-chain exists it will result
// in wrong stack traces (most likely dublicate callSites).
if (global._asyncHook) {
// In case the version match, we can simply return the first initialized copy
if (global._asyncHook.version === require('./package.json').version) {
module.exports = global._asyncHook;
}
// The version don't match, this is really bad. Lets just throw
else {
throw new Error('Conflicting version of async-hook-jl found');
}
} else {
const stackChain = require('stack-chain');
// Remove callSites from this module. AsyncWrap doesn't have any callSites
// and the hooks are expected to be completely transparent.
stackChain.filter.attach(function (error, frames) {
return frames.filter(function (callSite) {
const filename = callSite.getFileName();
// filename is not always a string, for example in case of eval it is
// undefined. So check if the filename is defined.
return !(filename && filename.slice(0, __dirname.length) === __dirname);
});
});
module.exports = global._asyncHook = new AsyncHook();
}
+33
View File
@@ -0,0 +1,33 @@
{
"name": "async-hook-jl",
"description": "Inspect the life of handle objects in node",
"version": "1.7.6",
"author": "Andreas Madsen <amwebdk@gmail.com>",
"main": "./index.js",
"scripts": {
"test": "node ./test/runner.js && eslint ."
},
"repository": {
"type": "git",
"url": "git://github.com/jeff-lewis/async-hook-jl.git"
},
"keywords": [
"async",
"async hooks",
"inspect",
"async wrap"
],
"license": "MIT",
"dependencies": {
"stack-chain": "^1.3.7"
},
"devDependencies": {
"async": "1.5.x",
"cli-color": "1.1.x",
"eslint": "^3.4.0",
"endpoint": "0.4.x"
},
"engines": {
"node": "^4.7 || >=6.9 || >=7.3"
}
}
+57
View File
@@ -0,0 +1,57 @@
'use strict';
function NextTickWrap() {}
module.exports = function patch() {
const hooks = this._hooks;
const state = this._state;
const oldNextTick = process.nextTick;
process.nextTick = function () {
if (!state.enabled) return oldNextTick.apply(process, arguments);
const args = new Array(arguments.length);
for (let i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
const callback = args[0];
if (typeof callback !== 'function') {
throw new TypeError('callback is not a function');
}
const handle = new NextTickWrap();
const uid = --state.counter;
// call the init hook
hooks.init.call(handle, uid, 0, null, null);
// overwrite callback
args[0] = function () {
// call the pre hook
hooks.pre.call(handle, uid);
let didThrow = true;
try {
callback.apply(this, arguments);
didThrow = false;
} finally {
// If `callback` threw and there is an uncaughtException handler
// then call the `post` and `destroy` hook after the uncaughtException
// user handlers have been invoked.
if(didThrow && process.listenerCount('uncaughtException') > 0) {
process.once('uncaughtException', function () {
hooks.post.call(handle, uid, true);
hooks.destroy.call(null, uid);
});
}
}
// callback done successfully
hooks.post.call(handle, uid, false);
hooks.destroy.call(null, uid);
};
return oldNextTick.apply(process, args);
};
}
+64
View File
@@ -0,0 +1,64 @@
'use strict';
function PromiseWrap() {}
module.exports = function patchPromise() {
const hooks = this._hooks;
const state = this._state;
const Promise = global.Promise;
/* As per ECMAScript 2015, .catch must be implemented by calling .then, as
* such we need needn't patch .catch as well. see:
* http://www.ecma-international.org/ecma-262/6.0/#sec-promise.prototype.catch
*/
const oldThen = Promise.prototype.then;
Promise.prototype.then = wrappedThen;
function makeWrappedHandler(fn, handle, uid, isOnFulfilled) {
if ('function' !== typeof fn) {
return isOnFulfilled
? makeUnhandledResolutionHandler(uid)
: makeUnhandledRejectionHandler(uid);
}
return function wrappedHandler() {
hooks.pre.call(handle, uid);
try {
return fn.apply(this, arguments);
} finally {
hooks.post.call(handle, uid, false);
hooks.destroy.call(null, uid);
}
};
}
function makeUnhandledResolutionHandler(uid) {
return function unhandledResolutionHandler(val) {
hooks.destroy.call(null, uid);
return val;
};
}
function makeUnhandledRejectionHandler(uid) {
return function unhandledRejectedHandler(val) {
hooks.destroy.call(null, uid);
throw val;
};
}
function wrappedThen(onFulfilled, onRejected) {
if (!state.enabled) return oldThen.call(this, onFulfilled, onRejected);
const handle = new PromiseWrap();
const uid = --state.counter;
hooks.init.call(handle, uid, 0, null, null);
return oldThen.call(
this,
makeWrappedHandler(onFulfilled, handle, uid, true),
makeWrappedHandler(onRejected, handle, uid, false)
);
}
};
+117
View File
@@ -0,0 +1,117 @@
'use strict';
const timers = require('timers');
function TimeoutWrap() {}
function IntervalWrap() {}
function ImmediateWrap() {}
const timeoutMap = new Map();
const intervalMap = new Map();
const ImmediateMap = new Map();
let activeCallback = null;
let clearedInCallback = false;
module.exports = function patch() {
patchTimer(this._hooks, this._state, 'setTimeout', 'clearTimeout', TimeoutWrap, timeoutMap, true);
patchTimer(this._hooks, this._state, 'setInterval', 'clearInterval', IntervalWrap, intervalMap, false);
patchTimer(this._hooks, this._state, 'setImmediate', 'clearImmediate', ImmediateWrap, ImmediateMap, true);
global.setTimeout = timers.setTimeout;
global.setInterval = timers.setInterval;
global.setImmediate = timers.setImmediate;
global.clearTimeout = timers.clearTimeout;
global.clearInterval = timers.clearInterval;
global.clearImmediate = timers.clearImmediate;
};
function patchTimer(hooks, state, setFn, clearFn, Handle, timerMap, singleCall) {
const oldSetFn = timers[setFn];
const oldClearFn = timers[clearFn];
// overwrite set[Timeout]
timers[setFn] = function () {
if (!state.enabled) return oldSetFn.apply(timers, arguments);
const args = new Array(arguments.length);
for (let i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
const callback = args[0];
if (typeof callback !== 'function') {
throw new TypeError('"callback" argument must be a function');
}
const handle = new Handle();
const uid = --state.counter;
let timerId = undefined;
// call the init hook
hooks.init.call(handle, uid, 0, null, null);
// overwrite callback
args[0] = function () {
// call the pre hook
activeCallback = timerId;
hooks.pre.call(handle, uid);
let didThrow = true;
try {
callback.apply(this, arguments);
didThrow = false;
} finally {
// If `callback` threw and there is an uncaughtException handler
// then call the `post` and `destroy` hook after the uncaughtException
// user handlers have been invoked.
if (didThrow && process.listenerCount('uncaughtException') > 0) {
process.once('uncaughtException', function () {
// call the post hook
hooks.post.call(handle, uid, true);
// setInterval won't continue
timerMap.delete(timerId);
hooks.destroy.call(null, uid);
});
}
}
// callback done successfully
hooks.post.call(handle, uid, false);
activeCallback = null;
// call the destroy hook if the callback will only be called once
if (singleCall || clearedInCallback) {
clearedInCallback = false;
timerMap.delete(timerId);
hooks.destroy.call(null, uid);
}
};
timerId = oldSetFn.apply(timers, args);
// Bind the timerId and uid for later use, in case the clear* function is
// called.
timerMap.set(timerId, uid);
return timerId;
};
// overwrite clear[Timeout]
timers[clearFn] = function (timerId) {
// If clear* was called within the timer callback, then delay the destroy
// event to after the post event has been called.
if (activeCallback === timerId && timerId !== null) {
clearedInCallback = true;
}
// clear should call the destroy hook. Note if timerId doesn't exists
// it is because asyncWrap wasn't enabled at the time.
else if (timerMap.has(timerId)) {
const uid = timerMap.get(timerId);
timerMap.delete(timerId);
hooks.destroy.call(null, uid);
}
oldClearFn.apply(timers, arguments);
};
}
+55
View File
@@ -0,0 +1,55 @@
'use strict';
const fs = require('fs');
const path = require('path');
const async = require('async');
const spawn = require('child_process').spawn;
const clc = require('cli-color');
const allFailed = clc.red.bold;
const allPassed = clc.green;
const failed = clc.yellow;
const passed = (t) => t;
const files = fs.readdirSync(__dirname).filter(function (filename) {
return filename.slice(0, 5) === 'test-';
});
async.mapSeries(files, runTest, function (err, passed) {
if (err) throw err;
let failed = 0;
for (const ok of passed) {
if (!ok) failed += 1;
}
if (failed > 0) {
console.log(allFailed('failed') + ` - ${failed} tests failed`);
} else {
console.log(allPassed('passed') + ` - ${passed.length} tests passed`);
}
});
function runTest(filename, done) {
process.stdout.write(` - running ${filename} ...`);
const p = spawn(process.execPath, [path.resolve(__dirname, filename)], {
stdio: ['ignore', 1, 2],
env: {
'NODE_ASYNC_HOOK_NO_WARNING': '1'
}
});
p.once('close', function (statusCode) {
const ok = (statusCode === 0);
if (ok) {
console.log(' ' + passed('ok'));
} else {
console.log(' - ' + failed('failed'));
}
done(null, ok);
});
}
+11
View File
@@ -0,0 +1,11 @@
'use strict';
const assert = require('assert');
const existing = global._asyncHook = {
version: require('../package.json').version
};
const asyncHook = require('../');
assert.equal(asyncHook, existing);
+13
View File
@@ -0,0 +1,13 @@
'use strict';
const assert = require('assert');
global._asyncHook = {
version: '0.0.0'
};
try {
require('../');
} catch (e) {
assert.equal(e.message, 'Conflicting version of async-hook-jl found');
}
+33
View File
@@ -0,0 +1,33 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fs = require('fs');
let called = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
fs.access(__filename, function () {
called = true;
});
process.once('exit', function () {
assert.equal(called, true);
});
+75
View File
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fs = require('fs');
let called = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let postDidThrow = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
fs.access(__filename, function () {
called = true;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'FSReqWrap');
assert.equal(initParent, null);
assert.equal(initProvider, asyncHook.providers.FSREQWRAP);
assert.equal(postDidThrow, false);
assert.equal(called, true);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+48
View File
@@ -0,0 +1,48 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fs = require('fs');
let called = false;
let initCalls = 0;
let preCalls = 0;
let postCalls = 0;
let destroyCalls = 0;
const hooks = {
init: function () {
initCalls += 1;
},
pre: function () {
preCalls += 1;
},
post: function () {
postCalls += 1;
},
destroy: function () {
destroyCalls += 1;
}
};
asyncHook.addHooks(hooks);
asyncHook.addHooks(hooks);
asyncHook.removeHooks(hooks);
asyncHook.enable();
fs.access(__filename, function () {
called = true;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(called, true);
assert.equal(initCalls, 1);
assert.equal(preCalls, 1);
assert.equal(postCalls, 1);
assert.equal(destroyCalls, 1);
});
+47
View File
@@ -0,0 +1,47 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fs = require('fs');
let called = false;
let initCalls = 0;
let preCalls = 0;
let postCalls = 0;
let destroyCalls = 0;
const hooks = {
init: function () {
initCalls += 1;
},
pre: function () {
preCalls += 1;
},
post: function () {
postCalls += 1;
},
destroy: function () {
destroyCalls += 1;
}
};
asyncHook.addHooks(hooks);
asyncHook.addHooks(hooks);
asyncHook.enable();
fs.access(__filename, function () {
called = true;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(called, true);
assert.equal(initCalls, 2);
assert.equal(preCalls, 2);
assert.equal(postCalls, 2);
assert.equal(destroyCalls, 2);
});
+38
View File
@@ -0,0 +1,38 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const timings = [];
asyncHook.addHooks({
init: function (uid, handle) {
timings.push(`init#${uid} - ${handle.constructor.name}`);
},
pre: function (uid) {
timings.push(`pre#${uid}`);
},
post: function (uid) {
timings.push(`post#${uid}`);
},
destroy: function (uid) {
timings.push(`destroy#${uid}`);
}
});
asyncHook.enable();
const timerId = setImmediate(() => {
timings.push('callback');
clearImmediate(timerId);
}, 100);
asyncHook.disable();
process.once('exit', function () {
assert.deepEqual(timings, [
'init#-1 - ImmediateWrap',
'pre#-1',
'callback',
'post#-1',
'destroy#-1'
]);
});
+59
View File
@@ -0,0 +1,59 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandleName = '';
let initParent = {};
let initProvider = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandleName = handle.constructor.name;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
const timerId = setImmediate(function () {
timerCalled = true;
});
clearImmediate(timerId);
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, destroyUid);
assert.equal(initHandleName, 'ImmediateWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(timerCalled, false);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
let throwFlag = null;
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid, handle, didThrow) {
throwFlag = didThrow;
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
process.once('uncaughtException', function () {
eventOrder.push('exception');
});
setImmediate(function () {
eventOrder.push('callback');
throw new Error('error');
});
asyncHook.disable();
process.once('exit', function () {
assert.strictEqual(throwFlag, true);
assert.deepEqual(eventOrder, [
'init#-1 ImmediateWrap', 'pre#-1',
'callback', 'exception',
'post#-1', 'destroy#-1'
]);
});
+42
View File
@@ -0,0 +1,42 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerACalled = false;
let timerBCalled = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
const timerId = setImmediate(function () {
timerACalled = true;
});
clearImmediate(timerId);
setImmediate(function (arg1, arg2) {
timerBCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 'a', 'b');
process.once('exit', function () {
assert.equal(timerACalled, false);
assert.equal(timerBCalled, true);
});
+76
View File
@@ -0,0 +1,76 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let postDidThrow = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
setImmediate(function (arg1, arg2) {
timerCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 'a', 'b');
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'ImmediateWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(postDidThrow, false);
assert.equal(timerCalled, true);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+32
View File
@@ -0,0 +1,32 @@
'use strict';
if (process.env.hasOwnProperty('ASYNC_HOOK_TEST_CHILD')) {
const asyncHook = require('../');
asyncHook.enable();
setImmediate(function () {
throw new Error('test error');
});
} else {
const spawn = require('child_process').spawn;
const endpoint = require('endpoint');
const child = spawn(process.execPath, [__filename], {
env: Object.assign({ ASYNC_HOOK_TEST_CHILD: '' }, process.env),
stdio: ['ignore', 1, 'pipe']
});
let stderr = null;
child.stderr.pipe(endpoint(function (err, _stderr) {
if (err) throw err;
stderr = _stderr;
}));
child.once('close', function (statusCode) {
if (statusCode !== 1 || stderr.toString().indexOf('test error') === -1) {
process.stderr.write(stderr);
process.exit(statusCode);
}
});
}
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
asyncHook.enable();
let throws = false;
try {
setImmediate(undefined, 1);
} catch (e) {
assert.equal(e.message, '"callback" argument must be a function');
assert.equal(e.name, 'TypeError');
throws = true;
}
asyncHook.disable();
process.once('exit', function () {
assert(throws);
});
+38
View File
@@ -0,0 +1,38 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const timings = [];
asyncHook.addHooks({
init: function (uid, handle) {
timings.push(`init#${uid} - ${handle.constructor.name}`);
},
pre: function (uid) {
timings.push(`pre#${uid}`);
},
post: function (uid) {
timings.push(`post#${uid}`);
},
destroy: function (uid) {
timings.push(`destroy#${uid}`);
}
});
asyncHook.enable();
const timerId = setInterval(() => {
timings.push('callback');
clearInterval(timerId);
}, 100);
asyncHook.disable();
process.once('exit', function () {
assert.deepEqual(timings, [
'init#-1 - IntervalWrap',
'pre#-1',
'callback',
'post#-1',
'destroy#-1'
]);
});
+59
View File
@@ -0,0 +1,59 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandleName = '';
let initParent = {};
let initProvider = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandleName = handle.constructor.name;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
const timerId = setInterval(function () {
timerCalled = true;
});
clearInterval(timerId);
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, destroyUid);
assert.equal(initHandleName, 'IntervalWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(timerCalled, false);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
let throwFlag = null;
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid, handle, didThrow) {
throwFlag = didThrow;
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
process.once('uncaughtException', function () {
eventOrder.push('exception');
});
setInterval(function () {
eventOrder.push('callback');
throw new Error('error');
});
asyncHook.disable();
process.once('exit', function () {
assert.strictEqual(throwFlag, true);
assert.deepEqual(eventOrder, [
'init#-1 IntervalWrap', 'pre#-1',
'callback', 'exception',
'post#-1', 'destroy#-1'
]);
});
+42
View File
@@ -0,0 +1,42 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerACalled = false;
let timerBCalled = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
const timerAId = setInterval(function () {
timerACalled = true;
});
clearInterval(timerAId);
const timerBId = setInterval(function (arg1, arg2) {
timerBCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
clearInterval(timerBId);
}, 0, 'a', 'b');
process.once('exit', function () {
assert.equal(timerACalled, false);
assert.equal(timerBCalled, true);
});
+86
View File
@@ -0,0 +1,86 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = 0;
let initCalls = 0;
let preCalls = 0;
let postCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let postDidThrow = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
preCalls += 1;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
postCalls += 1;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
const timerId = setInterval(function (arg1, arg2) {
timerCalled += 1;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
if (timerCalled === 2) clearInterval(timerId);
}, 0, 'a', 'b');
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'IntervalWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(postDidThrow, false);
assert.equal(timerCalled, 2);
assert.equal(initCalls, 1);
assert.equal(preCalls, 2);
assert.equal(postCalls, 2);
assert.equal(destroyCalls, 1);
});
+32
View File
@@ -0,0 +1,32 @@
'use strict';
if (process.env.hasOwnProperty('ASYNC_HOOK_TEST_CHILD')) {
const asyncHook = require('../');
asyncHook.enable();
setInterval(function () {
throw new Error('test error');
});
} else {
const spawn = require('child_process').spawn;
const endpoint = require('endpoint');
const child = spawn(process.execPath, [__filename], {
env: Object.assign({ ASYNC_HOOK_TEST_CHILD: '' }, process.env),
stdio: ['ignore', 1, 'pipe']
});
let stderr = null;
child.stderr.pipe(endpoint(function (err, _stderr) {
if (err) throw err;
stderr = _stderr;
}));
child.once('close', function (statusCode) {
if (statusCode !== 1 || stderr.toString().indexOf('test error') === -1) {
process.stderr.write(stderr);
process.exit(statusCode);
}
});
}
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
asyncHook.enable();
let throws = false;
try {
setInterval(undefined, 1);
} catch (e) {
assert.equal(e.message, '"callback" argument must be a function');
assert.equal(e.name, 'TypeError');
throws = true;
}
asyncHook.disable();
process.once('exit', function () {
assert(throws);
});
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
let throwFlag = null;
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid, handle, didThrow) {
throwFlag = didThrow;
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
process.once('uncaughtException', function () {
eventOrder.push('exception');
});
process.nextTick(function () {
eventOrder.push('callback');
throw new Error('error');
});
asyncHook.disable();
process.once('exit', function () {
assert.strictEqual(throwFlag, true);
assert.deepEqual(eventOrder, [
'init#-1 NextTickWrap', 'pre#-1',
'callback', 'exception',
'post#-1', 'destroy#-1'
]);
});
+34
View File
@@ -0,0 +1,34 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let called = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
process.nextTick(function (arg1, arg2) {
called = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 'a', 'b');
process.once('exit', function () {
assert.equal(called, true);
});
+76
View File
@@ -0,0 +1,76 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let called = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postDidThrow = NaN;
let postHandle = {};
let postUid = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
process.nextTick(function (arg1, arg2) {
called = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 'a', 'b');
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'NextTickWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(postDidThrow, false);
assert.equal(called, true);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+32
View File
@@ -0,0 +1,32 @@
'use strict';
if (process.env.hasOwnProperty('ASYNC_HOOK_TEST_CHILD')) {
const asyncHook = require('../');
asyncHook.enable();
process.nextTick(function () {
throw new Error('test error');
});
} else {
const spawn = require('child_process').spawn;
const endpoint = require('endpoint');
const child = spawn(process.execPath, [__filename], {
env: Object.assign({ ASYNC_HOOK_TEST_CHILD: '' }, process.env),
stdio: ['ignore', 1, 'pipe']
});
let stderr = null;
child.stderr.pipe(endpoint(function (err, _stderr) {
if (err) throw err;
stderr = _stderr;
}));
child.once('close', function (statusCode) {
if (statusCode !== 1 || stderr.toString().indexOf('test error') === -1) {
process.stderr.write(stderr);
process.exit(statusCode);
}
});
}
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
asyncHook.enable();
let throws = false;
try {
process.nextTick(undefined, 1);
} catch (e) {
assert.equal(e.message, 'callback is not a function');
assert.equal(e.name, 'TypeError');
throws = true;
}
asyncHook.disable();
process.once('exit', function () {
assert(throws);
});
+58
View File
@@ -0,0 +1,58 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const net = require('net');
let called = false;
let firstHook = true;
let initCalls = 0;
let serverHandle = {};
let serverUid = NaN;
let clientParentHandle = {};
let clientParentUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parentUid, parentHandle) {
if (provider != asyncHook.providers.TCPWRAP) return;
if (firstHook) {
firstHook = false;
serverUid = uid;
serverHandle = handle;
assert.equal(parentUid, null);
assert.equal(parentHandle, null);
} else {
clientParentHandle = parentHandle;
clientParentUid = parentUid;
}
initCalls += 1;
}
});
asyncHook.enable();
const server = net.createServer(function (socket) {
socket.end();
server.close();
called = true;
}).listen(function () {
net.connect(this.address());
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(serverHandle, clientParentHandle);
assert.equal(serverUid, clientParentUid);
assert.equal(called, true);
assert.equal(initCalls, 2);
});
+75
View File
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let rejctedCalled = false;
let rejectedArg = null;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle) {
postUid = uid;
postHandle = handle;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
Promise
.reject('a')
.catch(arg => {
rejctedCalled = true;
rejectedArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'PromiseWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(rejctedCalled, true);
assert.equal(rejectedArg, 'a');
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
@@ -0,0 +1,80 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let rejectedCalled = false;
let fulfilledCalled = false;
let fulfilledArg = null;
const initUid = [];
const initHandle = [];
const initProvider = [];
const initParent = [];
const preUid = [];
const preHandle = [];
const postUid = [];
const postHandle = [];
const destroyUid = [];
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid.push(uid);
initHandle.push(handle);
initProvider.push(provider);
initParent.push(parent);
},
pre: function (uid, handle) {
preUid.push(uid);
preHandle.push(handle);
},
post: function (uid, handle) {
postUid.push(uid);
postHandle.push(handle);
},
destroy: function (uid) {
destroyUid.push(uid);
}
});
asyncHook.enable();
Promise
.resolve('a')
.catch(() => {
rejectedCalled = true;
})
.then(arg => {
fulfilledCalled = true;
fulfilledArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid.length, 2, 'both handlers should init');
assert.equal(preUid.length, 1, 'only the .then should pre');
assert.equal(postUid.length, 1, 'only the .then should post');
assert.equal(destroyUid.length, 2, 'both handlers should destroy');
assert.equal(initUid[0], destroyUid[0]);
assert.equal(initUid[1], preUid[0]);
assert.equal(initUid[1], postUid[0]);
assert.equal(initUid[1], destroyUid[1]);
assert.equal(initHandle[1], preHandle[0]);
assert.equal(initHandle[1], postHandle[0]);
for (let i = 0; i < 2; ++i) {
assert.equal(initHandle[i].constructor.name, 'PromiseWrap');
assert.equal(initParent[i], null);
assert.equal(initProvider[i], 0);
}
assert.equal(rejectedCalled, false);
assert.equal(fulfilledCalled, true);
assert.equal(fulfilledArg, 'a');
});
+72
View File
@@ -0,0 +1,72 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const thenHandlersCalledA = [false, false];
const thenHandlersCalledB = [false, false];
let catchHandlerCalledC = false;
let catchHandlerCalledD = false;
let fulfilledArgA = null;
let rejectedArgB = null;
let rejectedArgC = null;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
Promise
.resolve('a')
.then(arg => {
fulfilledArgA = arg;
thenHandlersCalledA[0] = true;
}, () => {
thenHandlersCalledA[1] = true;
});
Promise
.reject('b')
.then(() => {
thenHandlersCalledB[0] = true;
}, arg => {
rejectedArgB = arg;
thenHandlersCalledB[1] = true;
});
Promise
.reject('c')
.catch(arg => {
rejectedArgC = arg;
catchHandlerCalledC = true;
});
Promise
.resolve('d')
.catch(() => {
catchHandlerCalledD = true;
});
process.once('exit', function () {
assert.deepStrictEqual(thenHandlersCalledA, [true, false]);
assert.equal(fulfilledArgA, 'a');
assert.deepStrictEqual(thenHandlersCalledB, [false, true]);
assert.equal(rejectedArgB, 'b');
assert.equal(catchHandlerCalledC, true);
assert.equal(rejectedArgC, 'c');
assert.equal(catchHandlerCalledD, false);
});
@@ -0,0 +1,81 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let fulfilledCalled = false;
let rejectedCalled = false;
let rejectedArg = null;
const initUid = [];
const initHandle = [];
const initProvider = [];
const initParent = [];
const preUid = [];
const preHandle = [];
const postUid = [];
const postHandle = [];
const destroyUid = [];
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid.push(uid);
initHandle.push(handle);
initProvider.push(provider);
initParent.push(parent);
},
pre: function (uid, handle) {
preUid.push(uid);
preHandle.push(handle);
},
post: function (uid, handle) {
postUid.push(uid);
postHandle.push(handle);
},
destroy: function (uid) {
destroyUid.push(uid);
}
});
asyncHook.enable();
Promise
.reject('a')
.then(() => {
fulfilledCalled = true;
})
.catch(arg => {
rejectedCalled = true;
rejectedArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid.length, 2, 'both handlers should init');
assert.equal(preUid.length, 1, 'only the .catch should pre');
assert.equal(postUid.length, 1, 'only the .catch should post');
assert.equal(destroyUid.length, 2, 'both handlers should destroy');
assert.equal(initUid[0], destroyUid[0]);
assert.equal(initUid[1], preUid[0]);
assert.equal(initUid[1], postUid[0]);
assert.equal(initUid[1], destroyUid[1]);
assert.equal(initHandle[1], preHandle[0]);
assert.equal(initHandle[1], postHandle[0]);
for (let i = 0; i < 2; ++i) {
assert.equal(initHandle[i].constructor.name, 'PromiseWrap');
assert.equal(initParent[i], null);
assert.equal(initProvider[i], 0);
}
assert.equal(fulfilledCalled, false);
assert.equal(rejectedCalled, true);
assert.equal(rejectedArg, 'a');
});
@@ -0,0 +1,80 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let fulfilledCalledA = false;
let fulfilledArgA = null;
let fulfilledCalledB = false;
let fulfilledArgB = null;
const initUid = [];
const initHandle = [];
const initProvider = [];
const initParent = [];
const preUid = [];
const preHandle = [];
const postUid = [];
const postHandle = [];
const destroyUid = [];
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid.push(uid);
initHandle.push(handle);
initProvider.push(provider);
initParent.push(parent);
},
pre: function (uid, handle) {
preUid.push(uid);
preHandle.push(handle);
},
post: function (uid, handle) {
postUid.push(uid);
postHandle.push(handle);
},
destroy: function (uid) {
destroyUid.push(uid);
}
});
asyncHook.enable();
Promise
.resolve('a')
.then(arg => {
fulfilledCalledA = true;
fulfilledArgA = arg;
return 'b';
})
.then(arg => {
fulfilledCalledB = true;
fulfilledArgB = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid.length, 2);
for (let i = 0; i < 2; ++i) {
assert.equal(initUid[i], preUid[i]);
assert.equal(initUid[i], postUid[i]);
assert.equal(initUid[i], destroyUid[i]);
assert.equal(initHandle[i], preHandle[i]);
assert.equal(initHandle[i], postHandle[i]);
assert.equal(initHandle[i].constructor.name, 'PromiseWrap');
assert.equal(initParent[i], null);
assert.equal(initProvider[i], 0);
}
assert.equal(fulfilledCalledA, true);
assert.equal(fulfilledArgA, 'a');
assert.equal(fulfilledCalledB, true);
assert.equal(fulfilledArgB, 'b');
});
+79
View File
@@ -0,0 +1,79 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let fulfilledCalled = false;
let fulfilledArg = null;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let postDidThrow = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle, didThrow) {
postUid = uid;
postHandle = handle;
postDidThrow = didThrow;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
Promise
.resolve('a')
.then(arg => {
fulfilledCalled = true;
fulfilledArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'PromiseWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(postDidThrow, false);
assert.equal(fulfilledCalled, true);
assert.equal(fulfilledArg, 'a');
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const fulfilledCalled = [];
const fulfilledArg = [];
const initUid = [];
const initHandle = [];
const initProvider = [];
const initParent = [];
const preUid = [];
const preHandle = [];
const postUid = [];
const postHandle = [];
const destroyUid = [];
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid.push(uid);
initHandle.push(handle);
initProvider.push(provider);
initParent.push(parent);
},
pre: function (uid, handle) {
preUid.push(uid);
preHandle.push(handle);
},
post: function (uid, handle) {
postUid.push(uid);
postHandle.push(handle);
},
destroy: function (uid) {
destroyUid.push(uid);
}
});
asyncHook.enable();
const p = Promise.resolve('a');
p.then(arg => {
fulfilledCalled.push(true);
fulfilledArg.push(arg);
});
p.then(arg => {
fulfilledCalled.push(true);
fulfilledArg.push(arg);
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid.length, 2);
for (let i = 0; i < 2; ++i) {
assert.equal(initUid[i], preUid[i]);
assert.equal(initUid[i], postUid[i]);
assert.equal(initUid[i], destroyUid[i]);
assert.equal(initHandle[i], preHandle[i]);
assert.equal(initHandle[i], postHandle[i]);
assert.equal(initHandle[i].constructor.name, 'PromiseWrap');
assert.equal(initParent[i], null);
assert.equal(initProvider[i], 0);
assert.equal(fulfilledCalled[i], true);
assert.equal(fulfilledArg[i], 'a');
}
});
+75
View File
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let rejectedCalled = false;
let rejectedArg = null;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle) {
postUid = uid;
postHandle = handle;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
Promise
.reject('a')
.then(null, arg => {
rejectedCalled = true;
rejectedArg = arg;
});
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'PromiseWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(rejectedCalled, true);
assert.equal(rejectedArg, 'a');
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+75
View File
@@ -0,0 +1,75 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid) {
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
new Promise(function (s) {
setTimeout(s, 100); // 1
})
.then(function () {
return new Promise((s) => setTimeout(s, 100)); // 4
})
.then();
process.once('exit', function () {
const nodeMajor = parseInt(process.versions.node.split('.')[0], 10);
if (nodeMajor >= 6) {
assert.deepEqual(eventOrder, [
'init#-1 TimeoutWrap',
'init#-2 PromiseWrap',
'init#-3 PromiseWrap',
'pre#-1',
'post#-1',
'destroy#-1',
'pre#-2',
'init#-4 TimeoutWrap',
'post#-2',
'destroy#-2',
'init#-5 PromiseWrap',
'pre#-4',
'post#-4',
'destroy#-4',
'pre#-5',
'post#-5',
'destroy#-5',
'destroy#-3'
]);
} else {
assert.deepEqual(eventOrder, [
'init#-1 TimeoutWrap',
'init#-2 PromiseWrap',
'init#-3 PromiseWrap',
'pre#-1',
'post#-1',
'destroy#-1',
'pre#-2',
'init#-4 TimeoutWrap',
'post#-2',
'destroy#-2',
'pre#-4',
'post#-4',
'destroy#-4',
'destroy#-3'
]);
}
});
+9
View File
@@ -0,0 +1,9 @@
'use strict';
const assert = require('assert');
require('../');
let e;
eval('(function() { e = new Error(); })()');
assert.equal(e.stack.split('\n').length, 10);
+38
View File
@@ -0,0 +1,38 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const timings = [];
asyncHook.addHooks({
init: function (uid, handle) {
timings.push(`init#${uid} - ${handle.constructor.name}`);
},
pre: function (uid) {
timings.push(`pre#${uid}`);
},
post: function (uid) {
timings.push(`post#${uid}`);
},
destroy: function (uid) {
timings.push(`destroy#${uid}`);
}
});
asyncHook.enable();
const timerId = setTimeout(() => {
timings.push('callback');
clearTimeout(timerId);
}, 100);
asyncHook.disable();
process.once('exit', function () {
assert.deepEqual(timings, [
'init#-1 - TimeoutWrap',
'pre#-1',
'callback',
'post#-1',
'destroy#-1'
]);
});
+59
View File
@@ -0,0 +1,59 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandleName = '';
let initParent = {};
let initProvider = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandleName = handle.constructor.name;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
const timerId = setTimeout(function () {
timerCalled = true;
});
clearTimeout(timerId);
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, destroyUid);
assert.equal(initHandleName, 'TimeoutWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(timerCalled, false);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+46
View File
@@ -0,0 +1,46 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
const eventOrder = [];
let throwFlag = null;
asyncHook.addHooks({
init: function (uid, handle) {
eventOrder.push(`init#${uid} ${handle.constructor.name}`);
},
pre: function (uid) {
eventOrder.push(`pre#${uid}`);
},
post: function (uid, handle, didThrow) {
throwFlag = didThrow;
eventOrder.push(`post#${uid}`);
},
destroy: function (uid) {
eventOrder.push(`destroy#${uid}`);
}
});
asyncHook.enable();
process.once('uncaughtException', function () {
eventOrder.push('exception');
});
setTimeout(function () {
eventOrder.push('callback');
throw new Error('error');
});
asyncHook.disable();
process.once('exit', function () {
assert.strictEqual(throwFlag, true);
assert.deepEqual(eventOrder, [
'init#-1 TimeoutWrap', 'pre#-1',
'callback', 'exception',
'post#-1', 'destroy#-1'
]);
});
+42
View File
@@ -0,0 +1,42 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerACalled = false;
let timerBCalled = false;
asyncHook.addHooks({
init: function () {
assert(false);
},
pre: function () {
assert(false);
},
post: function () {
assert(false);
},
destroy: function () {
assert(false);
}
});
asyncHook.enable();
asyncHook.disable();
const timerId = setTimeout(function () {
timerACalled = true;
});
clearTimeout(timerId);
setTimeout(function (arg1, arg2) {
timerBCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 0, 'a', 'b');
process.once('exit', function () {
assert.equal(timerACalled, false);
assert.equal(timerBCalled, true);
});
+72
View File
@@ -0,0 +1,72 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
let timerCalled = false;
let initCalls = 0;
let destroyCalls = 0;
let initUid = NaN;
let initHandle = {};
let initParent = {};
let initProvider = NaN;
let preHandle = {};
let preUid = NaN;
let postHandle = {};
let postUid = NaN;
let destroyUid = NaN;
asyncHook.addHooks({
init: function (uid, handle, provider, parent) {
initUid = uid;
initHandle = handle;
initParent = parent;
initProvider = provider;
initCalls += 1;
},
pre: function (uid, handle) {
preUid = uid;
preHandle = handle;
},
post: function (uid, handle) {
postUid = uid;
postHandle = handle;
},
destroy: function (uid) {
destroyUid = uid;
destroyCalls += 1;
}
});
asyncHook.enable();
setTimeout(function (arg1, arg2) {
timerCalled = true;
assert.equal(arg1, 'a');
assert.equal(arg2, 'b');
}, 0, 'a', 'b');
asyncHook.disable();
process.once('exit', function () {
assert.equal(initUid, preUid);
assert.equal(initUid, postUid);
assert.equal(initUid, destroyUid);
assert.equal(initHandle, preHandle);
assert.equal(initHandle, postHandle);
assert.equal(initHandle.constructor.name, 'TimeoutWrap');
assert.equal(initParent, null);
assert.equal(initProvider, 0);
assert.equal(timerCalled, true);
assert.equal(initCalls, 1);
assert.equal(destroyCalls, 1);
});
+32
View File
@@ -0,0 +1,32 @@
'use strict';
if (process.env.hasOwnProperty('ASYNC_HOOK_TEST_CHILD')) {
const asyncHook = require('../');
asyncHook.enable();
setTimeout(function () {
throw new Error('test error');
});
} else {
const spawn = require('child_process').spawn;
const endpoint = require('endpoint');
const child = spawn(process.execPath, [__filename], {
env: Object.assign({ ASYNC_HOOK_TEST_CHILD: '' }, process.env),
stdio: ['ignore', 1, 'pipe']
});
let stderr = null;
child.stderr.pipe(endpoint(function (err, _stderr) {
if (err) throw err;
stderr = _stderr;
}));
child.once('close', function (statusCode) {
if (statusCode !== 1 || stderr.toString().indexOf('test error') === -1) {
process.stderr.write(stderr);
process.exit(statusCode);
}
});
}
+21
View File
@@ -0,0 +1,21 @@
'use strict';
const asyncHook = require('../');
const assert = require('assert');
asyncHook.enable();
let throws = false;
try {
setTimeout(undefined, 1);
} catch (e) {
assert.equal(e.message, '"callback" argument must be a function');
assert.equal(e.name, 'TypeError');
throws = true;
}
asyncHook.disable();
process.once('exit', function () {
assert(throws);
});
+900
View File
@@ -0,0 +1,900 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
acorn-jsx@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b"
dependencies:
acorn "^3.0.4"
acorn@^3.0.4:
version "3.3.0"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a"
acorn@^5.0.1:
version "5.0.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.0.3.tgz#c460df08491463f028ccb82eab3730bf01087b3d"
ajv-keywords@^1.0.0:
version "1.5.1"
resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c"
ajv@^4.7.0:
version "4.11.8"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536"
dependencies:
co "^4.6.0"
json-stable-stringify "^1.0.1"
ansi-escapes@^1.1.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e"
ansi-regex@2, ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
dependencies:
sprintf-js "~1.0.2"
array-union@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39"
dependencies:
array-uniq "^1.0.1"
array-uniq@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6"
arrify@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
async@1.5.x:
version "1.5.2"
resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a"
babel-code-frame@^6.16.0:
version "6.22.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4"
dependencies:
chalk "^1.1.0"
esutils "^2.0.2"
js-tokens "^3.0.0"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
caller-path@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f"
dependencies:
callsites "^0.2.0"
callsites@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca"
chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
has-ansi "^2.0.0"
strip-ansi "^3.0.0"
supports-color "^2.0.0"
circular-json@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d"
cli-color@1.1.x:
version "1.1.0"
resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-1.1.0.tgz#de188cdc4929d83b67aea04110fbed40fdbf6775"
dependencies:
ansi-regex "2"
d "^0.1.1"
es5-ext "^0.10.8"
es6-iterator "2"
memoizee "^0.3.9"
timers-ext "0.1"
cli-cursor@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987"
dependencies:
restore-cursor "^1.0.1"
cli-width@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.1.0.tgz#b234ca209b29ef66fc518d9b98d5847b00edf00a"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
code-point-at@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
concat-stream@^1.5.2:
version "1.6.0"
resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7"
dependencies:
inherits "^2.0.3"
readable-stream "^2.2.2"
typedarray "^0.0.6"
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
d@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f"
dependencies:
es5-ext "^0.10.9"
d@^0.1.1, d@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309"
dependencies:
es5-ext "~0.10.2"
debug@^2.1.1:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
dependencies:
ms "2.0.0"
deep-is@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
del@^2.0.2:
version "2.2.2"
resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8"
dependencies:
globby "^5.0.0"
is-path-cwd "^1.0.0"
is-path-in-cwd "^1.0.0"
object-assign "^4.0.1"
pify "^2.0.0"
pinkie-promise "^2.0.0"
rimraf "^2.2.8"
doctrine@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63"
dependencies:
esutils "^2.0.2"
isarray "^1.0.0"
endpoint@0.4.x:
version "0.4.5"
resolved "https://registry.yarnpkg.com/endpoint/-/endpoint-0.4.5.tgz#8a32db66ad94c3161d279ed1ab4ffb6c4101b79a"
dependencies:
inherits "^2.0.1"
es5-ext@^0.10.14, es5-ext@^0.10.8, es5-ext@^0.10.9, es5-ext@~0.10.11, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.5, es5-ext@~0.10.6:
version "0.10.23"
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.23.tgz#7578b51be974207a5487821b56538c224e4e7b38"
dependencies:
es6-iterator "2"
es6-symbol "~3.1"
es6-iterator@2, es6-iterator@^2.0.1, es6-iterator@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.1.tgz#8e319c9f0453bf575d374940a655920e59ca5512"
dependencies:
d "1"
es5-ext "^0.10.14"
es6-symbol "^3.1"
es6-iterator@~0.1.3:
version "0.1.3"
resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-0.1.3.tgz#d6f58b8c4fc413c249b4baa19768f8e4d7c8944e"
dependencies:
d "~0.1.1"
es5-ext "~0.10.5"
es6-symbol "~2.0.1"
es6-map@^0.1.3:
version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0"
dependencies:
d "1"
es5-ext "~0.10.14"
es6-iterator "~2.0.1"
es6-set "~0.1.5"
es6-symbol "~3.1.1"
event-emitter "~0.3.5"
es6-set@~0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
dependencies:
d "1"
es5-ext "~0.10.14"
es6-iterator "~2.0.1"
es6-symbol "3.1.1"
event-emitter "~0.3.5"
es6-symbol@3.1.1, es6-symbol@^3.1, es6-symbol@^3.1.1, es6-symbol@~3.1, es6-symbol@~3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77"
dependencies:
d "1"
es5-ext "~0.10.14"
es6-symbol@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-2.0.1.tgz#761b5c67cfd4f1d18afb234f691d678682cb3bf3"
dependencies:
d "~0.1.1"
es5-ext "~0.10.5"
es6-weak-map@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.2.tgz#5e3ab32251ffd1538a1f8e5ffa1357772f92d96f"
dependencies:
d "1"
es5-ext "^0.10.14"
es6-iterator "^2.0.1"
es6-symbol "^3.1.1"
es6-weak-map@~0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-0.1.4.tgz#706cef9e99aa236ba7766c239c8b9e286ea7d228"
dependencies:
d "~0.1.1"
es5-ext "~0.10.6"
es6-iterator "~0.1.3"
es6-symbol "~2.0.1"
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
escope@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/escope/-/escope-3.6.0.tgz#e01975e812781a163a6dadfdd80398dc64c889c3"
dependencies:
es6-map "^0.1.3"
es6-weak-map "^2.0.1"
esrecurse "^4.1.0"
estraverse "^4.1.1"
eslint@^3.4.0:
version "3.19.0"
resolved "https://registry.yarnpkg.com/eslint/-/eslint-3.19.0.tgz#c8fc6201c7f40dd08941b87c085767386a679acc"
dependencies:
babel-code-frame "^6.16.0"
chalk "^1.1.3"
concat-stream "^1.5.2"
debug "^2.1.1"
doctrine "^2.0.0"
escope "^3.6.0"
espree "^3.4.0"
esquery "^1.0.0"
estraverse "^4.2.0"
esutils "^2.0.2"
file-entry-cache "^2.0.0"
glob "^7.0.3"
globals "^9.14.0"
ignore "^3.2.0"
imurmurhash "^0.1.4"
inquirer "^0.12.0"
is-my-json-valid "^2.10.0"
is-resolvable "^1.0.0"
js-yaml "^3.5.1"
json-stable-stringify "^1.0.0"
levn "^0.3.0"
lodash "^4.0.0"
mkdirp "^0.5.0"
natural-compare "^1.4.0"
optionator "^0.8.2"
path-is-inside "^1.0.1"
pluralize "^1.2.1"
progress "^1.1.8"
require-uncached "^1.0.2"
shelljs "^0.7.5"
strip-bom "^3.0.0"
strip-json-comments "~2.0.1"
table "^3.7.8"
text-table "~0.2.0"
user-home "^2.0.0"
espree@^3.4.0:
version "3.4.3"
resolved "https://registry.yarnpkg.com/espree/-/espree-3.4.3.tgz#2910b5ccd49ce893c2ffffaab4fd8b3a31b82374"
dependencies:
acorn "^5.0.1"
acorn-jsx "^3.0.0"
esprima@^3.1.1:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
esquery@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa"
dependencies:
estraverse "^4.0.0"
esrecurse@^4.1.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163"
dependencies:
estraverse "^4.1.0"
object-assign "^4.0.1"
estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
esutils@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
event-emitter@~0.3.4, event-emitter@~0.3.5:
version "0.3.5"
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
dependencies:
d "1"
es5-ext "~0.10.14"
exit-hook@^1.0.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8"
fast-levenshtein@~2.0.4:
version "2.0.6"
resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
figures@^1.3.5:
version "1.7.0"
resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e"
dependencies:
escape-string-regexp "^1.0.5"
object-assign "^4.1.0"
file-entry-cache@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361"
dependencies:
flat-cache "^1.2.1"
object-assign "^4.0.1"
flat-cache@^1.2.1:
version "1.2.2"
resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96"
dependencies:
circular-json "^0.3.1"
del "^2.0.2"
graceful-fs "^4.1.2"
write "^0.2.1"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
generate-function@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
generate-object-property@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
dependencies:
is-property "^1.0.0"
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5:
version "7.1.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^9.14.0:
version "9.18.0"
resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a"
globby@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d"
dependencies:
array-union "^1.0.1"
arrify "^1.0.0"
glob "^7.0.3"
object-assign "^4.0.1"
pify "^2.0.0"
pinkie-promise "^2.0.0"
graceful-fs@^4.1.2:
version "4.1.11"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
dependencies:
ansi-regex "^2.0.0"
ignore@^3.2.0:
version "3.3.3"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d"
imurmurhash@^0.1.4:
version "0.1.4"
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
dependencies:
once "^1.3.0"
wrappy "1"
inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
inquirer@^0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-0.12.0.tgz#1ef2bfd63504df0bc75785fff8c2c41df12f077e"
dependencies:
ansi-escapes "^1.1.0"
ansi-regex "^2.0.0"
chalk "^1.0.0"
cli-cursor "^1.0.1"
cli-width "^2.0.0"
figures "^1.3.5"
lodash "^4.3.0"
readline2 "^1.0.1"
run-async "^0.1.0"
rx-lite "^3.1.2"
string-width "^1.0.1"
strip-ansi "^3.0.0"
through "^2.3.6"
interpret@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.3.tgz#cbc35c62eeee73f19ab7b10a801511401afc0f90"
is-fullwidth-code-point@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb"
dependencies:
number-is-nan "^1.0.0"
is-fullwidth-code-point@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
is-my-json-valid@^2.10.0:
version "2.16.0"
resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz#f079dd9bfdae65ee2038aae8acbc86ab109e3693"
dependencies:
generate-function "^2.0.0"
generate-object-property "^1.1.0"
jsonpointer "^4.0.0"
xtend "^4.0.0"
is-path-cwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d"
is-path-in-cwd@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc"
dependencies:
is-path-inside "^1.0.0"
is-path-inside@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f"
dependencies:
path-is-inside "^1.0.1"
is-property@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
is-resolvable@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62"
dependencies:
tryit "^1.0.1"
isarray@^1.0.0, isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
js-tokens@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7"
js-yaml@^3.5.1:
version "3.8.4"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.8.4.tgz#520b4564f86573ba96662af85a8cafa7b4b5a6f6"
dependencies:
argparse "^1.0.7"
esprima "^3.1.1"
json-stable-stringify@^1.0.0, json-stable-stringify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af"
dependencies:
jsonify "~0.0.0"
jsonify@~0.0.0:
version "0.0.0"
resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73"
jsonpointer@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
levn@^0.3.0, levn@~0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee"
dependencies:
prelude-ls "~1.1.2"
type-check "~0.3.2"
lodash@^4.0.0, lodash@^4.3.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
lru-queue@0.1:
version "0.1.0"
resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3"
dependencies:
es5-ext "~0.10.2"
memoizee@^0.3.9:
version "0.3.10"
resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.3.10.tgz#4eca0d8aed39ec9d017f4c5c2f2f6432f42e5c8f"
dependencies:
d "~0.1.1"
es5-ext "~0.10.11"
es6-weak-map "~0.1.4"
event-emitter "~0.3.4"
lru-queue "0.1"
next-tick "~0.2.2"
timers-ext "0.1"
minimatch@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
mkdirp@^0.5.0, mkdirp@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
mute-stream@0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.5.tgz#8fbfabb0a98a253d3184331f9e8deb7372fac6c0"
natural-compare@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7"
next-tick@1:
version "1.0.0"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c"
next-tick@~0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-0.2.2.tgz#75da4a927ee5887e39065880065b7336413b310d"
number-is-nan@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
object-assign@^4.0.1, object-assign@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
onetime@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789"
optionator@^0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64"
dependencies:
deep-is "~0.1.3"
fast-levenshtein "~2.0.4"
levn "~0.3.0"
prelude-ls "~1.1.2"
type-check "~0.3.2"
wordwrap "~1.0.0"
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
path-is-inside@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
path-parse@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1"
pify@^2.0.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
pinkie-promise@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa"
dependencies:
pinkie "^2.0.0"
pinkie@^2.0.0:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870"
pluralize@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-1.2.1.tgz#d1a21483fd22bb41e58a12fa3421823140897c45"
prelude-ls@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
progress@^1.1.8:
version "1.1.8"
resolved "https://registry.yarnpkg.com/progress/-/progress-1.1.8.tgz#e260c78f6161cdd9b0e56cc3e0a85de17c7a57be"
readable-stream@^2.2.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.2.tgz#5a04df05e4f57fe3f0dc68fdd11dc5c97c7e6f4d"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
safe-buffer "~5.1.0"
string_decoder "~1.0.0"
util-deprecate "~1.0.1"
readline2@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/readline2/-/readline2-1.0.1.tgz#41059608ffc154757b715d9989d199ffbf372e35"
dependencies:
code-point-at "^1.0.0"
is-fullwidth-code-point "^1.0.0"
mute-stream "0.0.5"
rechoir@^0.6.2:
version "0.6.2"
resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384"
dependencies:
resolve "^1.1.6"
require-uncached@^1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3"
dependencies:
caller-path "^0.1.0"
resolve-from "^1.0.0"
resolve-from@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226"
resolve@^1.1.6:
version "1.3.3"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.3.tgz#655907c3469a8680dc2de3a275a8fdd69691f0e5"
dependencies:
path-parse "^1.0.5"
restore-cursor@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541"
dependencies:
exit-hook "^1.0.0"
onetime "^1.0.0"
rimraf@^2.2.8:
version "2.6.1"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d"
dependencies:
glob "^7.0.5"
run-async@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/run-async/-/run-async-0.1.0.tgz#c8ad4a5e110661e402a7d21b530e009f25f8e389"
dependencies:
once "^1.3.0"
rx-lite@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
safe-buffer@~5.1.0:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
shelljs@^0.7.5:
version "0.7.8"
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
dependencies:
glob "^7.0.0"
interpret "^1.0.0"
rechoir "^0.6.2"
slice-ansi@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
stack-chain@^1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
string-width@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3"
dependencies:
code-point-at "^1.0.0"
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
string-width@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e"
dependencies:
is-fullwidth-code-point "^2.0.0"
strip-ansi "^3.0.0"
string_decoder@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
dependencies:
safe-buffer "~5.1.0"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
strip-bom@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3"
strip-json-comments@~2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
table@^3.7.8:
version "3.8.3"
resolved "https://registry.yarnpkg.com/table/-/table-3.8.3.tgz#2bbc542f0fda9861a755d3947fefd8b3f513855f"
dependencies:
ajv "^4.7.0"
ajv-keywords "^1.0.0"
chalk "^1.1.1"
lodash "^4.0.0"
slice-ansi "0.0.4"
string-width "^2.0.0"
text-table@~0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
through@^2.3.6:
version "2.3.8"
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
timers-ext@0.1:
version "0.1.2"
resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.2.tgz#61cc47a76c1abd3195f14527f978d58ae94c5204"
dependencies:
es5-ext "~0.10.14"
next-tick "1"
tryit@^1.0.1:
version "1.0.3"
resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb"
type-check@~0.3.2:
version "0.3.2"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72"
dependencies:
prelude-ls "~1.1.2"
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
user-home@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f"
dependencies:
os-homedir "^1.0.0"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
wordwrap@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
write@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757"
dependencies:
mkdirp "^0.5.1"
xtend@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"