Compare commits

...

30 Commits

Author SHA1 Message Date
Overtorment
113433d505 mute 2020-03-26 15:12:47 +00:00
Wes Filleman
7d4fcd5c89 Forced all HTTPS Certs to accept. We have specific project reasons for doing this.
Updated for Android X, added podspec support,
2020-01-28 13:23:54 -07:00
naviocean
bb0a453c8e update dependencies, fix android packageName, bump 3.3.2 2018-11-29 11:36:19 +07:00
Ed Lafoy
1f7f99f844
Update package.json 2018-11-16 11:52:06 -06:00
Ed Lafoy
34aef6409e
Merge pull request #1 from atvenu/master
Support CocoaPods
2018-11-16 11:46:37 -06:00
Andre Staltz
a5e396c628
release 3.3.1 2018-07-26 19:49:51 +03:00
Andre Staltz
b793911a9a
add rnpm config 2018-07-26 19:49:37 +03:00
Andre Staltz
65ccf53a3f
set as public npm package 2018-07-26 15:57:39 +03:00
Andre Staltz
417ac600b3
update readme for this fork 2018-07-26 15:56:40 +03:00
Andre Staltz
ab42502f39
publish as @staltz/react-native-tcp 2018-07-26 15:54:48 +03:00
Andre Staltz
c8693a17bd
Merge 'datanav/master' into 'staltz/master' 2018-07-26 15:36:13 +03:00
Baard H. Rehn Johansen
5072101b2c Remove 2 sec delay (not sure why it suddenly worked) 2018-05-11 16:22:50 +02:00
Baard H. Rehn Johansen
ebc4fc6d27 Use underlying Secure System for TLS on IOS 2018-05-11 14:19:31 +02:00
Baard H. Rehn Johansen
eb87500c72 Added TLS 'upgrade' support on IOS 2018-05-11 13:33:00 +02:00
Baard H. Rehn Johansen
7453aed769 Added TLS 'upgrade' support on Android 2018-05-04 00:50:39 +02:00
Baard H. Rehn Johansen
0e7f3457c2 Added TLS support on Android 2018-05-04 00:46:03 +02:00
Paul Puey
c6af8f728f Set callback after write can cause callback being skipped
When didWriteDataWithTag is called but callback is not yet pushed to
pendingSends dictionary, it will be skipped and cause stream to hang
forever.
2018-04-19 15:13:48 +03:00
Allen Hujsak
bd0fd5623d Added stream-browserfy to stop crashing for partners 2018-03-07 14:57:01 -05:00
Eliran Zach
58c516d6e2
Merge pull request #2 from Airbitz/close-socket-on-error
Close the socket if we get an error even if we don't have a listener
2018-02-05 11:49:14 -08:00
Paul Puey
b27f3825e1 Close the socket if we get an error even if we don't have a listener 2018-02-05 14:37:11 -05:00
Paul Puey
f86fdce98c Do not call new Error() on write() if socket is disconnected 2018-01-06 01:55:12 -08:00
Paul Puey
7aba85bf51 Do not throw on write() if socket is closed. Only call callback if available. 2018-01-06 00:22:14 -08:00
Paul Puey
570a4915c3 Merge branch 'master' of https://github.com/Airbitz/react-native-tcp 2018-01-05 18:25:04 -08:00
Paul Puey
f4645ce822 Fix crashes on Android
* Do callback vs throw on write() when socket is disconnected
* Close socket if we fail to connect
2018-01-05 18:24:46 -08:00
thehobbit85
1cb311a899 commented out annoying redundant logs 2018-01-05 11:22:28 -08:00
Andy Hiew
95ae7b5c81 Support CocoaPods 2017-12-01 15:47:39 -07:00
Paul Puey
bd91614f42 Add TLS support for iOS 2017-11-06 00:05:06 -08:00
Paul Puey
53fdc03b8e Fix for RN 0.47 2017-08-29 21:44:17 -07:00
Paul V Puey
d00165f83c Merge pull request #1 from safitudo/patch-1
prevent native ios crashes
2017-07-21 15:32:38 -07:00
Stanislav Synko
cdcd666673 prevent native ios crashes 2017-07-21 15:31:59 -07:00
21 changed files with 1572 additions and 107 deletions

View File

@ -2,27 +2,29 @@
node's [net](https://nodejs.org/api/net.html) API in React Native
This module is used by [Peel](http://www.peel.com/)
## Install
* Create a new react-native project. [Check react-native getting started](http://facebook.github.io/react-native/docs/getting-started.html#content)
- Create a new react-native project. [Check react-native getting started](http://facebook.github.io/react-native/docs/getting-started.html#content)
* In your project dir:
- In your project dir:
```
npm install react-native-tcp --save
npm install @hawkingnetwork/react-native-tcp --save
```
__Note for iOS:__ If your react-native version < 0.40 install with this tag instead:
```
npm install react-native-tcp@3.1.0 --save
## if using Cocoapods
Update the following line with your path to `node_modules/` and add it to your
podfile:
```ruby
pod 'TcpSockets', :path => '../node_modules/react-native-tcp'
```
## Link in the native dependency
```
react-native link react-native-tcp
react-native link @hawkingnetwork/react-native-tcp
```
## Additional dependencies
@ -30,22 +32,23 @@ react-native link react-native-tcp
### Due to limitations in the react-native packager, streams need to be hacked in with [rn-nodeify](https://www.npmjs.com/package/rn-nodeify)
1. install rn-nodeify as a dev-dependency
``` npm install --save-dev rn-nodeify ```
`npm install --save-dev rn-nodeify`
2. run rn-nodeify manually
``` rn-nodeify --install stream,process,util --hack ```
`rn-nodeify --install stream,process,util --hack`
3. optionally you can add this as a postinstall script
``` "postinstall": "rn-nodeify --install stream,process,util --hack" ```
`"postinstall": "rn-nodeify --install stream,process,util --hack"`
## Usage
### package.json
_only if you want to write require('net') in your javascript_
_only if you want to write require('net') or require('tls') in your javascript_
```json
{
"browser": {
"net": "react-native-tcp"
"react-native": {
"net": "@hawkingnetwork/react-native-tcp",
"tls": "@hawkingnetwork/react-native-tcp/tls"
}
}
```
@ -55,31 +58,41 @@ _only if you want to write require('net') in your javascript_
_see/run [index.ios.js/index.android.js](examples/rctsockets) for a complete example, but basically it's just like net_
```js
var net = require('net');
// OR, if not shimming via package.json "browser" field:
// var net = require('react-native-tcp')
var net = require("net");
var net = require("tls");
// OR, if not shimming via package.json "react-native" field:
// var net = require('@hawkingnetwork/react-native-tcp')
// var tls = require('@hawkingnetwork/react-native-tcp/tls')
var server = net.createServer(function(socket) {
socket.write('excellent!');
}).listen(12345);
var server = net
.createServer(function(socket) {
socket.write("excellent!");
})
.listen(12345);
var client = net.createConnection(12345);
client.on('error', function(error) {
console.log(error)
client.on("error", function(error) {
console.log(error);
});
client.on('data', function(data) {
console.log('message was received', data)
client.on("data", function(data) {
console.log("message was received", data);
});
```
### TODO
### TLS support
add select tests from node's tests for net
TLS is only supported in the client interface. To use TLS, use the `tls.connect()`
syntax and not `socket = new tls.Socket()` syntax.
PR's welcome!
```
const socket = tls.connect({port: 50002, host:'electrum.villocq.com', rejectUnauthorized: false}, () => {
socket.write('{ "id": 5, "method": "blockchain.estimatefee", "params": [2] }\n')
console.log('Connected')
})
_originally forked from [react-native-udp](https://github.com/tradle/react-native-udp)_
socket.on('data', (data) => {
console.log('data:' + data.toString('ascii'))
})
```

View File

@ -54,10 +54,10 @@ function TcpServer(connectionListener: (socket: Socket) => void) {
util.inherits(TcpServer, EventEmitter);
TcpServer.prototype._debug = function() {
if (__DEV__) {
var args = [].slice.call(arguments);
console.log.apply(console, args);
}
// if (__DEV__) {
// var args = [].slice.call(arguments);
// console.log.apply(console, args);
// }
};
// TODO : determine how to properly overload this with flow

View File

@ -8,8 +8,11 @@
'use strict';
global.process = require('process'); // needed to make stream-browserify happy
var Buffer = global.Buffer = global.Buffer || require('buffer').Buffer;
if(!(global.process && global.process.nextTick)){
console.log('WHY AM I HERE?');
global.process = require('process'); // needed to make stream-browserify happy
}
var Buffer = global.Buffer || require('buffer').Buffer;
var util = require('util');
var stream = require('stream-browserify');
@ -34,6 +37,7 @@ function TcpSocket(options: ?{ id: ?number }) {
if (!(this instanceof TcpSocket)) {
return new TcpSocket(options);
}
this.useSsl = false
if (options && options.id) {
// e.g. incoming server connections
@ -60,6 +64,9 @@ function TcpSocket(options: ?{ id: ?number }) {
this._state = STATE.DISCONNECTED;
// cache all client.send calls to this array if currently upgrading
this._upgradeCache = []
this.read(0);
}
@ -120,10 +127,15 @@ TcpSocket.prototype.connect = function(options, callback) : TcpSocket {
}
this._state = STATE.CONNECTING;
this._debug('connecting, host:', host, 'port:', port);
this._destroyed = false;
Sockets.connect(this._id, host, Number(port), options);
if (this.useSsl) {
this._debug('connecting TLS, host:', host, 'port:', port);
Sockets.connectTls(this._id, host, Number(port), options);
} else {
this._debug('connecting, host:', host, 'port:', port);
Sockets.connect(this._id, host, Number(port), options);
}
return this;
};
@ -278,6 +290,12 @@ TcpSocket.prototype._registerEvents = function(): void {
return;
}
this._onError(ev.error);
}),
this._eventEmitter.addListener('secureConnect', ev => {
if (this._id !== ev.id) {
return;
}
this._onSecureConnect();
})
];
};
@ -338,12 +356,17 @@ TcpSocket.prototype._onClose = function(hadError: boolean): void {
};
TcpSocket.prototype._onError = function(error: string): void {
this._debug('received', 'error');
this._debug('received', `error: ${error}`);
this.emit('error', normalizeError(error));
this.emit('onerror', normalizeError(error));
this.destroy();
};
TcpSocket.prototype._onSecureConnect = function(error: string): void {
this._debug('received', 'secureConnect');
this.emit('secureConnect');
};
TcpSocket.prototype.write = function(chunk, encoding, cb) {
if (typeof chunk !== 'string' && !(Buffer.isBuffer(chunk))) {
throw new TypeError(
@ -356,24 +379,36 @@ TcpSocket.prototype.write = function(chunk, encoding, cb) {
TcpSocket.prototype._write = function(buffer: any, encoding: ?String, callback: ?(err: ?Error) => void) : boolean {
var self = this;
callback = callback || noop;
if (this._state === STATE.DISCONNECTED) {
throw new Error('Socket is not connected.');
return callback()
// return callback(new Error('Socket is not connected.'));
} else if (this._state === STATE.CONNECTING) {
// we're ok, GCDAsyncSocket handles queueing internally
}
callback = callback || noop;
var str;
if (typeof buffer === 'string') {
self._debug('socket.WRITE(): encoding as base64');
str = Base64Str.encode(buffer);
} else if (Buffer.isBuffer(buffer)) {
str = buffer.toString('base64');
} else if (buffer instanceof Uint8Array) {
self._debug('socket.WRITE(): encoding from UInt8Array');
str = Base64Str.encode(Utf8ArrayToStr(buffer));
self._debug(str);
} else {
throw new TypeError(
'Invalid data, chunk must be a string or buffer, not ' + typeof buffer);
}
if (this._upgrading) {
self._debug('tls in progress, write added to queue');
this._upgradeCache.push({ str, callback })
return false;
}
Sockets.write(this._id, str, function(err) {
if (self._timeout) {
self._activeTimer(self._timeout.msecs);
@ -391,6 +426,40 @@ TcpSocket.prototype._write = function(buffer: any, encoding: ?String, callback:
return true;
};
function Utf8ArrayToStr(array) {
var out, i, len, c;
var char2, char3;
out = "";
len = array.length;
i = 0;
while(i < len) {
c = array[i++];
switch(c >> 4)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += String.fromCharCode(c);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = array[i++];
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}
return out;
}
function setConnected(socket: TcpSocket, address: { port: number, address: string, family: string } ) {
socket.writable = socket.readable = true;
socket._state = STATE.CONNECTED;
@ -437,6 +506,44 @@ TcpSocket.prototype._normalizeConnectArgs = function(args) {
return typeof cb === 'function' ? [options, cb] : [options];
};
TcpSocket.prototype._enableSsl = function() {
this.useSsl = true
}
TcpSocket.prototype._upgradeToSecure = function(callback) {
// TODO : if we stored the original requested hostname somewhere, then we could do host name verification
var host = null;
var port = this._address.port;
this._debug('upgrading to TLS, host:', host, 'port:', port);
this._upgrading = true;
Sockets.upgradeToSecure(this._id, host, port, () => {
// emit all cached requests
setTimeout(() => {
while (this._upgradeCache.length) {
const cacheElement = this._upgradeCache.shift()
this._debug('flushing tls cache queue', cacheElement);
const self = this;
Sockets.write(this._id, cacheElement.str, function (err) {
if (self._timeout) {
self._activeTimer(self._timeout.msecs);
}
err = normalizeError(err);
if (err) {
self._debug('write failed', err);
return cacheElement.callback(err);
}
cacheElement.callback();
});
}
this._upgrading = false;
callback();
});
});
return this;
}
// unimplemented net.Socket apis
TcpSocket.prototype.ref =
TcpSocket.prototype.unref =

23
TcpSockets.podspec Normal file
View File

@ -0,0 +1,23 @@
require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = 'TcpSockets'
s.version = package['version']
s.summary = package['description']
s.homepage = package['repository']['url']
s.license = package['license']
s.author = package['author']
s.source = { :git => s.homepage, :tag => 'v#{s.version}' }
s.requires_arc = true
s.ios.deployment_target = '8.0'
s.tvos.deployment_target = '9.0'
s.preserve_paths = 'README.md', 'package.json', '**/*.js'
s.source_files = 'ios/**/*.{h,m}'
s.dependency 'React'
end

6
android/.classpath Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

23
android/.project Normal file
View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>@hawkingnetwork_react-native-tcp</name>
<comment>Project @hawkingnetwork_react-native-tcp created by Buildship.</comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,2 @@
connection.project.dir=../../../../android
eclipse.preferences.version=1

View File

@ -1,10 +1,11 @@
buildscript {
repositories {
jcenter()
google()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.2.3'
classpath 'com.android.tools.build:gradle:3.5.3'
}
}
@ -41,5 +42,5 @@ repositories {
dependencies {
compile 'com.facebook.react:react-native:+'
compile 'com.koushikdutta.async:androidasync:2.1.6'
compile 'com.koushikdutta.async:androidasync:2.+'
}

View File

@ -10,6 +10,7 @@ public interface TcpSocketListener {
void onConnection(Integer serverId, Integer clientId, InetSocketAddress socketAddress);
// client and server
void onSecureConnect(Integer id);
void onConnect(Integer id, InetSocketAddress socketAddress);
void onData(Integer id, byte[] data);
void onClose(Integer id, String error);

View File

@ -1,15 +1,11 @@
package com.peel.react;
import android.support.annotation.Nullable;
import androidx.annotation.Nullable;
import android.util.SparseArray;
import android.os.Build;
import com.koushikdutta.async.AsyncNetworkSocket;
import com.koushikdutta.async.AsyncServer;
import com.koushikdutta.async.AsyncServerSocket;
import com.koushikdutta.async.AsyncSocket;
import com.koushikdutta.async.ByteBufferList;
import com.koushikdutta.async.DataEmitter;
import com.koushikdutta.async.Util;
import com.facebook.react.bridge.Callback;
import com.koushikdutta.async.*;
import com.koushikdutta.async.callback.CompletedCallback;
import com.koushikdutta.async.callback.ConnectCallback;
import com.koushikdutta.async.callback.DataCallback;
@ -21,6 +17,20 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLEngineResult;
import javax.net.ssl.SSLEngineResult.HandshakeStatus;
import javax.net.ssl.SSLEngineResult.Status;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.security.cert.X509Certificate;
/**
* Created by aprock on 12/29/15.
*/
@ -32,6 +42,11 @@ public final class TcpSocketManager {
private int mInstances = 5000;
static SSLContext defaultSSLContext;
static SSLContext trustAllSSLContext;
static TrustManager[] trustAllManagers;
static HostnameVerifier trustAllVerifier;
public TcpSocketManager(TcpSocketListener listener) throws IOException {
mListener = new WeakReference<TcpSocketListener>(listener);
}
@ -42,7 +57,7 @@ public final class TcpSocketManager {
public void onCompleted(Exception ex) {
TcpSocketListener listener = mListener.get();
if (listener != null) {
listener.onClose(cId, ex==null?null:ex.getMessage());
listener.onClose(cId, ex == null ? null : ex.getMessage());
}
}
});
@ -71,7 +86,8 @@ public final class TcpSocketManager {
});
}
public void listen(final Integer cId, final String host, final Integer port) throws UnknownHostException, IOException {
public void listen(final Integer cId, final String host, final Integer port)
throws UnknownHostException, IOException {
// resolve the address
final InetSocketAddress socketAddress;
if (host != null) {
@ -97,7 +113,8 @@ public final class TcpSocketManager {
mClients.put(mInstances, socket);
AsyncNetworkSocket socketConverted = Util.getWrappedSocket(socket, AsyncNetworkSocket.class);
InetSocketAddress remoteAddress = socketConverted != null ? socketConverted.getRemoteAddress() : socketAddress;
InetSocketAddress remoteAddress = socketConverted != null ? socketConverted.getRemoteAddress()
: socketAddress;
TcpSocketListener listener = mListener.get();
if (listener != null) {
@ -119,7 +136,8 @@ public final class TcpSocketManager {
});
}
public void connect(final Integer cId, final @Nullable String host, final Integer port) throws UnknownHostException, IOException {
public void connect(final Integer cId, final @Nullable String host, final Integer port, final boolean useTls)
throws UnknownHostException, IOException {
// resolve the address
final InetSocketAddress socketAddress;
if (host != null) {
@ -131,21 +149,128 @@ public final class TcpSocketManager {
mServer.connectSocket(socketAddress, new ConnectCallback() {
@Override
public void onConnectCompleted(Exception ex, AsyncSocket socket) {
TcpSocketListener listener = mListener.get();
if (ex == null) {
mClients.put(cId, socket);
setSocketCallbacks(cId, socket);
if (useTls) {
try {
// critical extension 2.5.29.15 is implemented improperly prior to 4.0.3.
// https://code.google.com/p/android/issues/detail?id=9307
// https://groups.google.com/forum/?fromgroups=#!topic/netty/UCfqPPk5O4s
// certs that use this extension will throw in Cipher.java.
// fallback is to use a custom SSLContext, and hack around the x509 extension.
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
throw new Exception();
defaultSSLContext = SSLContext.getInstance("Default");
} catch (Exception ex2) {
try {
defaultSSLContext = SSLContext.getInstance("TLS");
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
if (listener != null) {
listener.onConnect(cId, socketAddress);
public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType) {
for (X509Certificate cert : certs) {
if (cert != null && cert.getCriticalExtensionOIDs() != null)
cert.getCriticalExtensionOIDs().remove("2.5.29.15");
}
}
} };
defaultSSLContext.init(null, trustAllCerts, null);
} catch (Exception ex3) {
ex2.printStackTrace();
ex3.printStackTrace();
}
}
} else if (listener != null) {
listener.onError(cId, ex.getMessage());
try {
trustAllSSLContext = SSLContext.getInstance("TLS");
trustAllManagers = new TrustManager[] { new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
String authType) {
}
public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
String authType) {
}
} };
trustAllSSLContext.init(null, trustAllManagers, null);
// trustAllVerifier = (hostname, session) -> true;
} catch (Exception ex2) {
ex2.printStackTrace();
}
AsyncSSLSocketWrapper.handshake(socket, socketAddress.getHostName(), socketAddress.getPort(),
trustAllSSLContext.createSSLEngine(), trustAllManagers, new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}, true, new AsyncSSLSocketWrapper.HandshakeCallback() {
@Override
public void onHandshakeCompleted(Exception e, AsyncSSLSocket socket) {
onConnectionCompleted(e, socket, cId, socketAddress);
}
});
} else {
onConnectionCompleted(ex, socket, cId, socketAddress);
}
}
});
}
private void onConnectionCompleted(Exception ex, AsyncSocket socket, Integer cId, InetSocketAddress socketAddress) {
TcpSocketListener listener = mListener.get();
mClients.put(cId, socket);
if (ex == null) {
setSocketCallbacks(cId, socket);
if (listener != null) {
listener.onConnect(cId, socketAddress);
}
} else if (listener != null) {
listener.onError(cId, "unable to open socket: " + ex);
close(cId);
} else {
close(cId);
}
}
public void upgradeToSecure(final Integer cId, String host, Integer port, final Callback callback) {
Object existingSocket = mClients.get(cId);
if (existingSocket != null && existingSocket instanceof AsyncSocket) {
AsyncSSLSocketWrapper.handshake((AsyncSocket) existingSocket, host, port,
AsyncSSLSocketWrapper.getDefaultSSLContext().createSSLEngine(), null, null, true,
new AsyncSSLSocketWrapper.HandshakeCallback() {
@Override
public void onHandshakeCompleted(Exception ex, AsyncSSLSocket upgradedSocket) {
TcpSocketListener listener = mListener.get();
mClients.put(cId, upgradedSocket);
if (ex == null) {
setSocketCallbacks(cId, upgradedSocket);
if (listener != null) {
listener.onSecureConnect(cId);
}
if (callback != null) {
callback.invoke();
}
} else if (listener != null) {
listener.onError(cId, "unable to upgrade socket to tls: " + ex);
close(cId);
} else {
close(cId);
}
}
});
}
}
public void write(final Integer cId, final byte[] data) {
Object socket = mClients.get(cId);
if (socket != null && socket instanceof AsyncSocket) {
@ -164,7 +289,7 @@ public final class TcpSocketManager {
} else {
TcpSocketListener listener = mListener.get();
if (listener != null) {
listener.onError(cId, "unable to find socket");
listener.onError(cId, "unable to find socket");
}
}
}

View File

@ -5,7 +5,7 @@
package com.peel.react;
import android.support.annotation.Nullable;
import androidx.annotation.Nullable;
import android.util.Base64;
import com.facebook.common.logging.FLog;
@ -108,7 +108,7 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
protected void doInBackgroundGuarded(Void... params) {
// NOTE : ignoring options for now, just use the available interface.
try {
socketManager.connect(cId, host, port);
socketManager.connect(cId, host, port, false);
} catch (UnknownHostException uhe) {
FLog.e(TAG, "connect", uhe);
onError(cId, uhe.getMessage());
@ -120,6 +120,35 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
}.execute();
}
@ReactMethod
public void connectTls(final Integer cId, final @Nullable String host, final Integer port, final ReadableMap options) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
protected void doInBackgroundGuarded(Void... params) {
// NOTE : ignoring options for now, just use the available interface.
try {
socketManager.connect(cId, host, port, true);
} catch (UnknownHostException uhe) {
FLog.e(TAG, "connectTls", uhe);
onError(cId, uhe.getMessage());
} catch (IOException ioe) {
FLog.e(TAG, "connectTls", ioe);
onError(cId, ioe.getMessage());
}
}
}.execute();
}
@ReactMethod
public void upgradeToSecure(final Integer cId, final String host, final Integer port, final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@Override
protected void doInBackgroundGuarded(Void... params) {
socketManager.upgradeToSecure(cId, host, port, callback);
}
}.execute();
}
@ReactMethod
public void write(final Integer cId, final String base64String, final Callback callback) {
new GuardedAsyncTask<Void, Void>(getReactApplicationContext()) {
@ -194,6 +223,17 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
sendEvent("connect", eventParams);
}
@Override
public void onSecureConnect(Integer id) {
if (mShuttingDown) {
return;
}
WritableMap eventParams = Arguments.createMap();
eventParams.putInt("id", id);
sendEvent("secureConnect", eventParams);
}
@Override
public void onData(Integer id, byte[] data) {
if (mShuttingDown) {
@ -235,3 +275,4 @@ public final class TcpSockets extends ReactContextBaseJavaModule implements TcpS
sendEvent("error", eventParams);
}
}

View File

@ -28,7 +28,6 @@ public final class TcpSocketsModule implements ReactPackage {
return modules;
}
// Deprecated RN 0.47
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}

View File

@ -790,6 +790,8 @@ typedef NS_ENUM(NSInteger, GCDAsyncSocketError) {
**/
- (void)startTLS:(nullable NSDictionary <NSString*,NSObject*>*)tlsSettings;
- (void)startTLSCancelCurrentRead:(nullable NSDictionary <NSString*,NSObject*>*)tlsSettings;
#pragma mark Advanced
/**

View File

@ -6407,7 +6407,7 @@ enum GCDAsyncSocketConfig
#pragma mark Security
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (void)startTLS:(NSDictionary *)tlsSettings
- (void)doStartTLS:(NSDictionary *)tlsSettings withCancelCurrentRead:(BOOL)cancelCurrentRead
{
LogTrace();
@ -6430,6 +6430,11 @@ enum GCDAsyncSocketConfig
if ((flags & kSocketStarted) && !(flags & kQueuedTLS) && !(flags & kForbidReadsWrites))
{
// dirty hack to fix that the client has already added a read with no timeout which we need to finish
if (currentRead && cancelCurrentRead) {
LogInfo(@"Cancelling current read as requested");
[self completeCurrentRead];
}
[readQueue addObject:packet];
[writeQueue addObject:packet];
@ -6442,6 +6447,14 @@ enum GCDAsyncSocketConfig
}
- (void)startTLSCancelCurrentRead:(NSDictionary *)tlsSettings
{
[self doStartTLS:tlsSettings withCancelCurrentRead:TRUE];
}
- (void)startTLS:(NSDictionary *)tlsSettings {
[self doStartTLS:tlsSettings withCancelCurrentRead:FALSE];
}
- (void)maybeStartTLS
{
// We can't start TLS until:
@ -6781,7 +6794,9 @@ static OSStatus SSLWriteFunction(SSLConnectionRef connection, const void *data,
return;
}
// Force SSL to accept all HTTPS certs.
status = SSLSetSessionOption(sslContext, kSSLSessionOptionBreakOnServerAuth, true);
BOOL shouldManuallyEvaluateTrust = [[tlsSettings objectForKey:GCDAsyncSocketManuallyEvaluateTrust] boolValue];
if (shouldManuallyEvaluateTrust)
{

View File

@ -31,6 +31,7 @@ typedef enum RCTTCPError RCTTCPError;
- (void)onData:(NSNumber *)clientID data:(NSData *)data;
- (void)onClose:(TcpSocketClient*)client withError:(NSError *)err;
- (void)onError:(TcpSocketClient*)client withError:(NSError *)err;
- (void)onSecureConnect:(TcpSocketClient*)client;
- (NSNumber*)getNextId;
@end
@ -39,6 +40,7 @@ typedef enum RCTTCPError RCTTCPError;
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, weak) id<SocketClientDelegate> clientDelegate;
@property (nonatomic) BOOL useSsl;
///---------------------------------------------------------------------------------------
/// @name Class Methods
@ -62,10 +64,14 @@ typedef enum RCTTCPError RCTTCPError;
* @param port
* @param host ip address
* @param options NSDictionary which can have @"localAddress" and @"localPort" to specify the local interface
* @param useSsl BOOL Use SSL/TLS connection
* @return true if connected, false if there was an error
*/
- (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)options useSsl:(BOOL)useSsl error:(NSError **)error;
- (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)options error:(NSError **)error;
- (void)upgradeToSecure:(NSString *)host port:(int)port callback:(RCTResponseSenderBlock) callback;
/**
* Starts listening on a local host and port
*
@ -98,5 +104,8 @@ typedef enum RCTTCPError RCTTCPError;
*/
- (void)destroy;
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler;
@end

View File

@ -15,7 +15,9 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
{
@private
GCDAsyncSocket *_tcpSocket;
NSString *_host;
NSMutableDictionary<NSNumber *, RCTResponseSenderBlock> *_pendingSends;
RCTResponseSenderBlock _pendingUpgrade;
NSLock *_lock;
long _sendTag;
}
@ -54,6 +56,12 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
- (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)options error:(NSError **)error
{
return [self connect:host port:port withOptions:options useSsl:NO error:error];
}
- (BOOL)connect:(NSString *)host port:(int)port withOptions:(NSDictionary *)options useSsl:(BOOL)useSsl error:(NSError **)error
{
self.useSsl = useSsl;
if (_tcpSocket) {
if (error) {
*error = [self badInvocationError:@"this client's socket is already connected"];
@ -62,6 +70,7 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
return false;
}
_host = host;
_tcpSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:[self methodQueue]];
[_tcpSocket setUserData: _id];
@ -88,6 +97,16 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
return result;
}
- (void)upgradeToSecure:(NSString *)host port:(int)port callback:(RCTResponseSenderBlock) callback;
{
if (callback) {
self->_pendingUpgrade = callback;
}
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[_tcpSocket startTLSCancelCurrentRead:settings];
}
- (NSDictionary<NSString *, id> *)getAddress
{
if (_tcpSocket)
@ -184,10 +203,7 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
[self setPendingSend:callback forKey:@(_sendTag)];
}
[_tcpSocket writeData:data withTimeout:-1 tag:_sendTag];
_sendTag++;
[_tcpSocket readDataWithTimeout:-1 tag:_id.longValue];
}
- (void)end
@ -208,7 +224,10 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
[_clientDelegate onData:@(tag) data:data];
[sock readDataWithTimeout:-1 tag:tag];
if (!_pendingUpgrade) {
// if we add a read, the special packet will not be picked up in time
[sock readDataWithTimeout:-1 tag:tag];
}
}
- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket
@ -228,11 +247,34 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
return;
}
[_clientDelegate onConnect:self];
if (self.useSsl)
{
NSMutableDictionary *settings = [NSMutableDictionary dictionary];
[sock startTLS:settings];
[sock readDataWithTimeout:-1 tag:_id.longValue];
[_clientDelegate onConnect:self];
}
else
{
[_clientDelegate onConnect:self];
[sock readDataWithTimeout:-1 tag:_id.longValue];
}
}
- (void)socketDidSecure:(GCDAsyncSocket *)sock {
RCTLogInfo(@"socket secured");
if (self->_pendingUpgrade) {
self.useSsl= true;
self->_pendingUpgrade(@[]);
self->_pendingUpgrade = nil;
[_clientDelegate onSecureConnect:self];
}
// start receiving messages
if (self.useSsl)
{
[sock readDataWithTimeout:-1 tag:_id.longValue];
}
}
- (void)socketDidCloseReadStream:(GCDAsyncSocket *)sock
{
// TODO : investigate for half-closed sockets
@ -264,4 +306,10 @@ NSString *const RCTTCPErrorDomain = @"RCTTCPErrorDomain";
return dispatch_get_main_queue();
}
- (void)socket:(GCDAsyncSocket *)sock didReceiveTrust:(SecTrustRef)trust
completionHandler:(void (^)(BOOL shouldTrustPeer))completionHandler
{
completionHandler(YES);
}
@end

View File

@ -28,6 +28,7 @@ RCT_EXPORT_MODULE()
@"connection",
@"data",
@"close",
@"secureConnect",
@"error"];
}
@ -85,12 +86,39 @@ RCT_EXPORT_METHOD(connect:(nonnull NSNumber*)cId
}
}
RCT_EXPORT_METHOD(connectTls:(nonnull NSNumber*)cId
host:(NSString *)host
port:(int)port
withOptions:(NSDictionary *)options)
{
TcpSocketClient *client = _clients[cId];
if (!client) {
client = [self createSocket:cId];
}
NSError *error = nil;
if (![client connect:host port:port withOptions:options useSsl:YES error:&error])
{
[self onError:client withError:error];
return;
}
}
RCT_EXPORT_METHOD(upgradeToSecure:(nonnull NSNumber*)cId
host:(NSString *)host
port:(int)port
callback:(RCTResponseSenderBlock)callback) {
TcpSocketClient* client = [self findClient:cId];
if (!client) return;
[client upgradeToSecure:host port:port callback:callback];
}
RCT_EXPORT_METHOD(write:(nonnull NSNumber*)cId
string:(NSString *)base64String
callback:(RCTResponseSenderBlock)callback) {
TcpSocketClient* client = [self findClient:cId];
if (!client) return;
// iOS7+
// TODO: use https://github.com/nicklockwood/Base64 for compatibility with earlier iOS versions
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
@ -128,9 +156,15 @@ RCT_EXPORT_METHOD(listen:(nonnull NSNumber*)cId
body:@{ @"id": client.id, @"address" : [client getAddress] }];
}
- (void)onSecureConnect:(TcpSocketClient*) client
{
[self sendEventWithName:@"secureConnect"
body:@{ @"id": client.id }];
}
-(void)onConnection:(TcpSocketClient *)client toClient:(NSNumber *)clientID {
_clients[client.id] = client;
[self sendEventWithName:@"connection"
body:@{ @"id": clientID, @"info": @{ @"id": client.id, @"address" : [client getAddress] } }];
}

View File

@ -1,18 +1,71 @@
{
"name": "react-native-tcp",
"version": "3.3.0",
"description": "node's net API for react-native",
"main": "TcpSockets.js",
"scripts": {
"start": "exit 1"
"_from": "@hawkingnetwork/react-native-tcp",
"_id": "@hawkingnetwork/react-native-tcp@3.3.2",
"_inBundle": false,
"_integrity": "sha512-XY4F58mvx4mz2TmcAhAbGg2CAF/kmcZt8PyaUjsArAXXpXrSIPFqweLSa0DfMhUpZ9XSEyMRvRZG63XACiBdVQ==",
"_location": "/@hawkingnetwork/react-native-tcp",
"_phantomChildren": {
"inherits": "2.0.3"
},
"_requested": {
"type": "tag",
"registry": true,
"raw": "@hawkingnetwork/react-native-tcp",
"name": "@hawkingnetwork/react-native-tcp",
"escapedName": "@hawkingnetwork%2freact-native-tcp",
"scope": "@hawkingnetwork",
"rawSpec": "",
"saveSpec": null,
"fetchSpec": "latest"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/@hawkingnetwork/react-native-tcp/-/react-native-tcp-3.3.2.tgz",
"_shasum": "ed8f89b9e24e4bf2d5ce74a21eead1bd9a1e567a",
"_spec": "@hawkingnetwork/react-native-tcp",
"_where": "/Users/wesleyfilleman/Developer/MobiLincReact",
"author": {
"name": "Hawking"
},
"browser": {
"net": "./TcpSockets.js"
},
"repository": {
"type": "git",
"url": "https://github.com/PeelTechnologies/react-native-tcp"
"bugs": {
"url": "https://github.com/staltz/react-native-tcp/issues"
},
"bundleDependencies": false,
"contributors": [
{
"name": "Paul Puey",
"email": "paul@edgesecure.co"
},
{
"name": "Andy Prock",
"email": "aprock@protonmail.com"
},
{
"name": "Andre Staltz",
"email": "contact@staltz.com"
}
],
"dependencies": {
"base64-js": "1.3.0",
"buffer": "5.2.1",
"events": "3.0.0",
"ip-regex": "3.0.0",
"process": "0.11.10",
"stream-browserify": "2.0.1",
"util": "0.11.1"
},
"deprecated": false,
"description": "node's net API for react-native",
"devDependencies": {
"babel-eslint": "^4.1.6",
"eslint-plugin-react": "^3.11.3"
},
"homepage": "https://github.com/staltz/react-native-tcp",
"keywords": [
"react-component",
"reactnative",
@ -23,28 +76,21 @@
"ios",
"android"
],
"author": {
"name": "Andy Prock",
"email": "aprock@protonmail.com"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/PeelTechnologies/react-native-tcp/issues"
},
"homepage": "https://github.com/PeelTechnologies/react-native-tcp",
"main": "TcpSockets.js",
"name": "@hawkingnetwork/react-native-tcp",
"peerDependencies": {
"react-native": ">=0.40.0"
},
"dependencies": {
"base64-js": "0.0.8",
"buffer": "^5.0.0",
"events": "^1.0.2",
"ip-regex": "^1.0.3",
"process": "^0.11.9",
"util": "^0.10.3"
"publishConfig": {
"access": "public"
},
"devDependencies": {
"babel-eslint": "^4.1.6",
"eslint-plugin-react": "^3.11.3"
}
"repository": {
"type": "git",
"url": "git+https://github.com/hawkingnetwork/react-native-tcp.git"
},
"scripts": {
"start": "exit 1"
},
"version": "3.3.2"
}

23
react-native-tcp.podspec Normal file
View File

@ -0,0 +1,23 @@
require 'json'
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
Pod::Spec.new do |s|
s.name = 'react-native-tcp'
s.version = package['version']
s.summary = package['description']
s.homepage = package['repository']['url']
s.license = package['license']
s.author = package['author']
s.source = { :git => s.homepage, :tag => 'v#{s.version}' }
s.requires_arc = true
s.ios.deployment_target = '8.0'
s.tvos.deployment_target = '9.0'
s.preserve_paths = 'README.md', 'package.json', '**/*.js'
s.source_files = 'ios/**/*.{h,m}'
s.dependency 'React'
end

51
tls/index.js Normal file
View File

@ -0,0 +1,51 @@
/**
* Copyright (c) 2017-present, Edge.
* All rights reserved.
*
* @providesModule TlsSockets
* @flow
*/
'use strict';
var ipRegex = require('ip-regex');
var Socket = require('../TcpSocket');
var Server = require('../TcpServer');
exports.createServer = function(connectionListener: (socket: Socket) => void) : Server {
return new Server(connectionListener);
};
// TODO : determine how to properly overload this with flow
exports.connect = exports.createConnection = function() : Socket {
if (arguments[0] !== null && typeof arguments[0] === 'object' && arguments[0].socket != null) {
var existingSocket = arguments[0].socket;
return existingSocket._upgradeToSecure(arguments[1]);
}
var tcpSocket = new Socket();
tcpSocket._enableSsl()
console.log('creating new tls', arguments);
return Socket.prototype.connect.apply(tcpSocket, tcpSocket._normalizeConnectArgs(arguments));
};
exports.isIP = function(input: string) : number {
var result = 0;
if (ipRegex.v4({exact: true}).test(input)) {
result = 4;
} else if (ipRegex.v6({exact: true}).test(input)) {
result = 6;
}
return result;
};
exports.isIPv4 = function(input: string) : boolean {
return exports.isIP(input) === 4;
};
exports.isIPv6 = function(input: string) : boolean {
return exports.isIP(input) === 6;
};
exports.Socket = Socket;
exports.Server = Server;

896
yarn.lock Normal file
View File

@ -0,0 +1,896 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
acorn-to-esprima@^1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/acorn-to-esprima/-/acorn-to-esprima-1.0.7.tgz#9436259760098f9ead9b9da2242fab2f4850281b"
acorn@^5.2.1:
version "5.7.3"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
align-text@^0.1.1, align-text@^0.1.3:
version "0.1.4"
resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117"
dependencies:
kind-of "^3.0.2"
longest "^1.0.1"
repeat-string "^1.5.2"
alter@~0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/alter/-/alter-0.2.0.tgz#c7588808617572034aae62480af26b1d4d1cb3cd"
dependencies:
stable "~0.1.3"
amdefine@>=0.0.4:
version "1.0.1"
resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5"
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"
ast-traverse@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ast-traverse/-/ast-traverse-0.1.1.tgz#69cf2b8386f19dcda1bb1e05d68fe359d8897de6"
ast-types@0.8.12:
version "0.8.12"
resolved "http://registry.npmjs.org/ast-types/-/ast-types-0.8.12.tgz#a0d90e4351bb887716c83fd637ebf818af4adfcc"
ast-types@0.8.15:
version "0.8.15"
resolved "http://registry.npmjs.org/ast-types/-/ast-types-0.8.15.tgz#8eef0827f04dff0ec8857ba925abe3fea6194e52"
ast-types@0.9.6:
version "0.9.6"
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.9.6.tgz#102c9e9e9005d3e7e3829bf0c4fa24ee862ee9b9"
babel-core@^5.8.33:
version "5.8.38"
resolved "http://registry.npmjs.org/babel-core/-/babel-core-5.8.38.tgz#1fcaee79d7e61b750b00b8e54f6dfc9d0af86558"
dependencies:
babel-plugin-constant-folding "^1.0.1"
babel-plugin-dead-code-elimination "^1.0.2"
babel-plugin-eval "^1.0.1"
babel-plugin-inline-environment-variables "^1.0.1"
babel-plugin-jscript "^1.0.4"
babel-plugin-member-expression-literals "^1.0.1"
babel-plugin-property-literals "^1.0.1"
babel-plugin-proto-to-assign "^1.0.3"
babel-plugin-react-constant-elements "^1.0.3"
babel-plugin-react-display-name "^1.0.3"
babel-plugin-remove-console "^1.0.1"
babel-plugin-remove-debugger "^1.0.1"
babel-plugin-runtime "^1.0.7"
babel-plugin-undeclared-variables-check "^1.0.2"
babel-plugin-undefined-to-void "^1.1.6"
babylon "^5.8.38"
bluebird "^2.9.33"
chalk "^1.0.0"
convert-source-map "^1.1.0"
core-js "^1.0.0"
debug "^2.1.1"
detect-indent "^3.0.0"
esutils "^2.0.0"
fs-readdir-recursive "^0.1.0"
globals "^6.4.0"
home-or-tmp "^1.0.0"
is-integer "^1.0.4"
js-tokens "1.0.1"
json5 "^0.4.0"
lodash "^3.10.0"
minimatch "^2.0.3"
output-file-sync "^1.1.0"
path-exists "^1.0.0"
path-is-absolute "^1.0.0"
private "^0.1.6"
regenerator "0.8.40"
regexpu "^1.3.0"
repeating "^1.1.2"
resolve "^1.1.6"
shebang-regex "^1.0.0"
slash "^1.0.0"
source-map "^0.5.0"
source-map-support "^0.2.10"
to-fast-properties "^1.0.0"
trim-right "^1.0.0"
try-resolve "^1.0.0"
babel-eslint@^4.1.6:
version "4.1.8"
resolved "http://registry.npmjs.org/babel-eslint/-/babel-eslint-4.1.8.tgz#4f79e7a4f5879ecf03f48cb16f552a355fcc31b2"
dependencies:
acorn-to-esprima "^1.0.5"
babel-core "^5.8.33"
lodash.assign "^3.2.0"
lodash.pick "^3.1.0"
babel-plugin-constant-folding@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-plugin-constant-folding/-/babel-plugin-constant-folding-1.0.1.tgz#8361d364c98e449c3692bdba51eff0844290aa8e"
babel-plugin-dead-code-elimination@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/babel-plugin-dead-code-elimination/-/babel-plugin-dead-code-elimination-1.0.2.tgz#5f7c451274dcd7cccdbfbb3e0b85dd28121f0f65"
babel-plugin-eval@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-plugin-eval/-/babel-plugin-eval-1.0.1.tgz#a2faed25ce6be69ade4bfec263f70169195950da"
babel-plugin-inline-environment-variables@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-plugin-inline-environment-variables/-/babel-plugin-inline-environment-variables-1.0.1.tgz#1f58ce91207ad6a826a8bf645fafe68ff5fe3ffe"
babel-plugin-jscript@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/babel-plugin-jscript/-/babel-plugin-jscript-1.0.4.tgz#8f342c38276e87a47d5fa0a8bd3d5eb6ccad8fcc"
babel-plugin-member-expression-literals@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-plugin-member-expression-literals/-/babel-plugin-member-expression-literals-1.0.1.tgz#cc5edb0faa8dc927170e74d6d1c02440021624d3"
babel-plugin-property-literals@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-plugin-property-literals/-/babel-plugin-property-literals-1.0.1.tgz#0252301900192980b1c118efea48ce93aab83336"
babel-plugin-proto-to-assign@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/babel-plugin-proto-to-assign/-/babel-plugin-proto-to-assign-1.0.4.tgz#c49e7afd02f577bc4da05ea2df002250cf7cd123"
dependencies:
lodash "^3.9.3"
babel-plugin-react-constant-elements@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/babel-plugin-react-constant-elements/-/babel-plugin-react-constant-elements-1.0.3.tgz#946736e8378429cbc349dcff62f51c143b34e35a"
babel-plugin-react-display-name@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/babel-plugin-react-display-name/-/babel-plugin-react-display-name-1.0.3.tgz#754fe38926e8424a4e7b15ab6ea6139dee0514fc"
babel-plugin-remove-console@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-plugin-remove-console/-/babel-plugin-remove-console-1.0.1.tgz#d8f24556c3a05005d42aaaafd27787f53ff013a7"
babel-plugin-remove-debugger@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/babel-plugin-remove-debugger/-/babel-plugin-remove-debugger-1.0.1.tgz#fd2ea3cd61a428ad1f3b9c89882ff4293e8c14c7"
babel-plugin-runtime@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/babel-plugin-runtime/-/babel-plugin-runtime-1.0.7.tgz#bf7c7d966dd56ecd5c17fa1cb253c9acb7e54aaf"
babel-plugin-undeclared-variables-check@^1.0.2:
version "1.0.2"
resolved "http://registry.npmjs.org/babel-plugin-undeclared-variables-check/-/babel-plugin-undeclared-variables-check-1.0.2.tgz#5cf1aa539d813ff64e99641290af620965f65dee"
dependencies:
leven "^1.0.2"
babel-plugin-undefined-to-void@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/babel-plugin-undefined-to-void/-/babel-plugin-undefined-to-void-1.1.6.tgz#7f578ef8b78dfae6003385d8417a61eda06e2f81"
babylon@^5.8.38:
version "5.8.38"
resolved "http://registry.npmjs.org/babylon/-/babylon-5.8.38.tgz#ec9b120b11bf6ccd4173a18bf217e60b79859ffd"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
base64-js@1.3.0, base64-js@^1.0.2:
version "1.3.0"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3"
bluebird@^2.9.33:
version "2.11.0"
resolved "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
brace-expansion@^1.0.0, brace-expansion@^1.1.7:
version "1.1.11"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
breakable@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/breakable/-/breakable-1.0.0.tgz#784a797915a38ead27bad456b5572cb4bbaa78c1"
buffer@5.2.1:
version "5.2.1"
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.2.1.tgz#dd57fa0f109ac59c602479044dca7b8b3d0b71d6"
dependencies:
base64-js "^1.0.2"
ieee754 "^1.1.4"
camelcase@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39"
center-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad"
dependencies:
align-text "^0.1.3"
lazy-cache "^1.0.3"
chalk@^1.0.0:
version "1.1.3"
resolved "http://registry.npmjs.org/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"
cliui@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1"
dependencies:
center-align "^0.1.1"
right-align "^0.1.1"
wordwrap "0.0.2"
commander@^2.5.0:
version "2.19.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.19.0.tgz#f6198aa84e5b83c46054b94ddedbfed5ee9ff12a"
commoner@~0.10.3:
version "0.10.8"
resolved "https://registry.yarnpkg.com/commoner/-/commoner-0.10.8.tgz#34fc3672cd24393e8bb47e70caa0293811f4f2c5"
dependencies:
commander "^2.5.0"
detective "^4.3.1"
glob "^5.0.15"
graceful-fs "^4.1.2"
iconv-lite "^0.4.5"
mkdirp "^0.5.0"
private "^0.1.6"
q "^1.1.2"
recast "^0.11.17"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
convert-source-map@^1.1.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
dependencies:
safe-buffer "~5.1.1"
core-js@^1.0.0:
version "1.2.7"
resolved "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636"
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"
debug@^2.1.1:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
dependencies:
ms "2.0.0"
decamelize@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
defined@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693"
defs@~1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/defs/-/defs-1.1.1.tgz#b22609f2c7a11ba7a3db116805c139b1caffa9d2"
dependencies:
alter "~0.2.0"
ast-traverse "~0.1.1"
breakable "~1.0.0"
esprima-fb "~15001.1001.0-dev-harmony-fb"
simple-fmt "~0.1.0"
simple-is "~0.2.0"
stringmap "~0.2.2"
stringset "~0.2.1"
tryor "~0.1.2"
yargs "~3.27.0"
detect-indent@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-3.0.1.tgz#9dc5e5ddbceef8325764b9451b02bc6d54084f75"
dependencies:
get-stdin "^4.0.1"
minimist "^1.1.0"
repeating "^1.1.0"
detective@^4.3.1:
version "4.7.1"
resolved "https://registry.yarnpkg.com/detective/-/detective-4.7.1.tgz#0eca7314338442febb6d65da54c10bb1c82b246e"
dependencies:
acorn "^5.2.1"
defined "^1.0.0"
escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
eslint-plugin-react@^3.11.3:
version "3.16.1"
resolved "http://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-3.16.1.tgz#262d96b77d7c4a42af809a73c0e527a58612293c"
esprima-fb@~15001.1001.0-dev-harmony-fb:
version "15001.1001.0-dev-harmony-fb"
resolved "https://registry.yarnpkg.com/esprima-fb/-/esprima-fb-15001.1001.0-dev-harmony-fb.tgz#43beb57ec26e8cf237d3dd8b33e42533577f2659"
esprima@^2.6.0:
version "2.7.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581"
esprima@~3.1.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633"
esutils@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
events@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88"
fs-readdir-recursive@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-0.1.2.tgz#315b4fb8c1ca5b8c47defef319d073dad3568059"
get-stdin@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe"
glob@^5.0.15:
version "5.0.15"
resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1"
dependencies:
inflight "^1.0.4"
inherits "2"
minimatch "2 || 3"
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^6.4.0:
version "6.4.1"
resolved "http://registry.npmjs.org/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f"
graceful-fs@^4.1.2, graceful-fs@^4.1.4:
version "4.1.15"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
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"
home-or-tmp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-1.0.0.tgz#4b9f1e40800c3e50c6c27f781676afcce71f3985"
dependencies:
os-tmpdir "^1.0.1"
user-home "^1.1.1"
iconv-lite@^0.4.5:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
dependencies:
safer-buffer ">= 2.1.2 < 3"
ieee754@^1.1.4:
version "1.1.12"
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b"
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.3, inherits@~2.0.1, inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
invert-kv@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6"
ip-regex@3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-3.0.0.tgz#0a934694b4066558c46294244a23cc33116bf732"
is-buffer@^1.1.5:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
is-finite@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa"
dependencies:
number-is-nan "^1.0.0"
is-integer@^1.0.4:
version "1.0.7"
resolved "https://registry.yarnpkg.com/is-integer/-/is-integer-1.0.7.tgz#6bde81aacddf78b659b6629d629cadc51a886d5c"
dependencies:
is-finite "^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@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-1.0.1.tgz#cc435a5c8b94ad15acb7983140fc80182c89aeae"
jsesc@~0.5.0:
version "0.5.0"
resolved "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d"
json5@^0.4.0:
version "0.4.0"
resolved "http://registry.npmjs.org/json5/-/json5-0.4.0.tgz#054352e4c4c80c86c0923877d449de176a732c8d"
kind-of@^3.0.2:
version "3.2.2"
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
dependencies:
is-buffer "^1.1.5"
lazy-cache@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e"
lcid@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835"
dependencies:
invert-kv "^1.0.0"
leven@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/leven/-/leven-1.0.2.tgz#9144b6eebca5f1d0680169f1a6770dcea60b75c3"
lodash._baseassign@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
dependencies:
lodash._basecopy "^3.0.0"
lodash.keys "^3.0.0"
lodash._basecopy@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
lodash._baseflatten@^3.0.0:
version "3.1.4"
resolved "https://registry.yarnpkg.com/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz#0770ff80131af6e34f3b511796a7ba5214e65ff7"
dependencies:
lodash.isarguments "^3.0.0"
lodash.isarray "^3.0.0"
lodash._basefor@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash._basefor/-/lodash._basefor-3.0.3.tgz#7550b4e9218ef09fad24343b612021c79b4c20c2"
lodash._bindcallback@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
lodash._createassigner@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz#838a5bae2fdaca63ac22dee8e19fa4e6d6970b11"
dependencies:
lodash._bindcallback "^3.0.0"
lodash._isiterateecall "^3.0.0"
lodash.restparam "^3.0.0"
lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
lodash._isiterateecall@^3.0.0:
version "3.0.9"
resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
lodash._pickbyarray@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/lodash._pickbyarray/-/lodash._pickbyarray-3.0.2.tgz#1f898d9607eb560b0e167384b77c7c6d108aa4c5"
lodash._pickbycallback@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/lodash._pickbycallback/-/lodash._pickbycallback-3.0.0.tgz#ff61b9a017a7b3af7d30e6c53de28afa19b8750a"
dependencies:
lodash._basefor "^3.0.0"
lodash.keysin "^3.0.0"
lodash.assign@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa"
dependencies:
lodash._baseassign "^3.0.0"
lodash._createassigner "^3.0.0"
lodash.keys "^3.0.0"
lodash.isarguments@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
lodash.isarray@^3.0.0:
version "3.0.4"
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
lodash.keys@^3.0.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
dependencies:
lodash._getnative "^3.0.0"
lodash.isarguments "^3.0.0"
lodash.isarray "^3.0.0"
lodash.keysin@^3.0.0:
version "3.0.8"
resolved "https://registry.yarnpkg.com/lodash.keysin/-/lodash.keysin-3.0.8.tgz#22c4493ebbedb1427962a54b445b2c8a767fb47f"
dependencies:
lodash.isarguments "^3.0.0"
lodash.isarray "^3.0.0"
lodash.pick@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-3.1.0.tgz#f252a855b2046b61bcd3904b26f76bd2efc65550"
dependencies:
lodash._baseflatten "^3.0.0"
lodash._bindcallback "^3.0.0"
lodash._pickbyarray "^3.0.0"
lodash._pickbycallback "^3.0.0"
lodash.restparam "^3.0.0"
lodash.restparam@^3.0.0:
version "3.6.1"
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
lodash@^3.10.0, lodash@^3.9.3:
version "3.10.1"
resolved "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6"
longest@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097"
"minimatch@2 || 3":
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimatch@^2.0.3:
version "2.0.10"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7"
dependencies:
brace-expansion "^1.0.0"
minimist@0.0.8:
version "0.0.8"
resolved "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
minimist@^1.1.0:
version "1.2.0"
resolved "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
mkdirp@^0.5.0, mkdirp@^0.5.1:
version "0.5.1"
resolved "http://registry.npmjs.org/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"
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.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"
os-locale@^1.4.0:
version "1.4.0"
resolved "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9"
dependencies:
lcid "^1.0.0"
os-tmpdir@^1.0.1:
version "1.0.2"
resolved "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
output-file-sync@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/output-file-sync/-/output-file-sync-1.1.2.tgz#d0a33eefe61a205facb90092e826598d5245ce76"
dependencies:
graceful-fs "^4.1.4"
mkdirp "^0.5.1"
object-assign "^4.1.0"
path-exists@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-1.0.0.tgz#d5a8998eb71ef37a74c34eb0d9eba6e878eea081"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
path-parse@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c"
private@^0.1.6, private@~0.1.5:
version "0.1.8"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff"
process-nextick-args@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
process@0.11.10:
version "0.11.10"
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
q@^1.1.2:
version "1.5.1"
resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
readable-stream@^2.0.2:
version "2.3.6"
resolved "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~2.0.0"
safe-buffer "~5.1.1"
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
recast@0.10.33:
version "0.10.33"
resolved "http://registry.npmjs.org/recast/-/recast-0.10.33.tgz#942808f7aa016f1fa7142c461d7e5704aaa8d697"
dependencies:
ast-types "0.8.12"
esprima-fb "~15001.1001.0-dev-harmony-fb"
private "~0.1.5"
source-map "~0.5.0"
recast@^0.10.10:
version "0.10.43"
resolved "http://registry.npmjs.org/recast/-/recast-0.10.43.tgz#b95d50f6d60761a5f6252e15d80678168491ce7f"
dependencies:
ast-types "0.8.15"
esprima-fb "~15001.1001.0-dev-harmony-fb"
private "~0.1.5"
source-map "~0.5.0"
recast@^0.11.17:
version "0.11.23"
resolved "https://registry.yarnpkg.com/recast/-/recast-0.11.23.tgz#451fd3004ab1e4df9b4e4b66376b2a21912462d3"
dependencies:
ast-types "0.9.6"
esprima "~3.1.0"
private "~0.1.5"
source-map "~0.5.0"
regenerate@^1.2.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
regenerator@0.8.40:
version "0.8.40"
resolved "http://registry.npmjs.org/regenerator/-/regenerator-0.8.40.tgz#a0e457c58ebdbae575c9f8cd75127e93756435d8"
dependencies:
commoner "~0.10.3"
defs "~1.1.0"
esprima-fb "~15001.1001.0-dev-harmony-fb"
private "~0.1.5"
recast "0.10.33"
through "~2.3.8"
regexpu@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/regexpu/-/regexpu-1.3.0.tgz#e534dc991a9e5846050c98de6d7dd4a55c9ea16d"
dependencies:
esprima "^2.6.0"
recast "^0.10.10"
regenerate "^1.2.1"
regjsgen "^0.2.0"
regjsparser "^0.1.4"
regjsgen@^0.2.0:
version "0.2.0"
resolved "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7"
regjsparser@^0.1.4:
version "0.1.5"
resolved "http://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c"
dependencies:
jsesc "~0.5.0"
repeat-string@^1.5.2:
version "1.6.1"
resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637"
repeating@^1.1.0, repeating@^1.1.2:
version "1.1.3"
resolved "https://registry.yarnpkg.com/repeating/-/repeating-1.1.3.tgz#3d4114218877537494f97f77f9785fab810fa4ac"
dependencies:
is-finite "^1.0.0"
resolve@^1.1.6:
version "1.8.1"
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26"
dependencies:
path-parse "^1.0.5"
right-align@^0.1.1:
version "0.1.3"
resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef"
dependencies:
align-text "^0.1.1"
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.2"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
"safer-buffer@>= 2.1.2 < 3":
version "2.1.2"
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
shebang-regex@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3"
simple-fmt@~0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/simple-fmt/-/simple-fmt-0.1.0.tgz#191bf566a59e6530482cb25ab53b4a8dc85c3a6b"
simple-is@~0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/simple-is/-/simple-is-0.2.0.tgz#2abb75aade39deb5cc815ce10e6191164850baf0"
slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
source-map-support@^0.2.10:
version "0.2.10"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc"
dependencies:
source-map "0.1.32"
source-map@0.1.32:
version "0.1.32"
resolved "http://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz#c8b6c167797ba4740a8ea33252162ff08591b266"
dependencies:
amdefine ">=0.0.4"
source-map@^0.5.0, source-map@~0.5.0:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
stable@~0.1.3:
version "0.1.8"
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
stream-browserify@2.0.1:
version "2.0.1"
resolved "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db"
dependencies:
inherits "~2.0.1"
readable-stream "^2.0.2"
string_decoder@~1.1.1:
version "1.1.1"
resolved "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8"
dependencies:
safe-buffer "~5.1.0"
stringmap@~0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/stringmap/-/stringmap-0.2.2.tgz#556c137b258f942b8776f5b2ef582aa069d7d1b1"
stringset@~0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/stringset/-/stringset-0.2.1.tgz#ef259c4e349344377fcd1c913dd2e848c9c042b5"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
through@~2.3.8:
version "2.3.8"
resolved "http://registry.npmjs.org/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
to-fast-properties@^1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47"
trim-right@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
try-resolve@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/try-resolve/-/try-resolve-1.0.1.tgz#cfde6fabd72d63e5797cfaab873abbe8e700e912"
tryor@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/tryor/-/tryor-0.1.2.tgz#8145e4ca7caff40acde3ccf946e8b8bb75b4172b"
user-home@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
util@0.11.1:
version "0.11.1"
resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61"
dependencies:
inherits "2.0.3"
window-size@^0.1.2:
version "0.1.4"
resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.4.tgz#f8e1aa1ee5a53ec5bf151ffa09742a6ad7697876"
wordwrap@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
y18n@^3.2.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41"
yargs@~3.27.0:
version "3.27.0"
resolved "http://registry.npmjs.org/yargs/-/yargs-3.27.0.tgz#21205469316e939131d59f2da0c6d7f98221ea40"
dependencies:
camelcase "^1.2.1"
cliui "^2.1.0"
decamelize "^1.0.0"
os-locale "^1.4.0"
window-size "^0.1.2"
y18n "^3.2.0"