Merge branch 'service-testing'
parent
9d4697d8d6
commit
301e3eacea
|
|
@ -1,26 +0,0 @@
|
|||
(async () => {
|
||||
const { title } = require('../lib/title');
|
||||
const net = require('net');
|
||||
const os = require('os');
|
||||
const log = require('signale');
|
||||
const { config } = require('./../package.json');
|
||||
const { hri } = require('human-readable-ids');
|
||||
const { Profiles } = require('../lib/Profiles');
|
||||
const profiles = new Profiles('client');
|
||||
const yargs = require('yargs').argv;
|
||||
const identity = yargs.profile ?
|
||||
await profiles.get(yargs.profile) :
|
||||
await profiles.get((await profiles.all())[0]);
|
||||
|
||||
// const id = hri.random();
|
||||
|
||||
// console.log(id)
|
||||
|
||||
// title(id);
|
||||
// title(identity.name.replace(/-/g, ' '));
|
||||
|
||||
// await profiles.create();
|
||||
|
||||
|
||||
|
||||
})();
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
const { config } = require('./config');
|
||||
const Keyv = require('keyv');
|
||||
const { KeyvFile } = require('keyv-file');
|
||||
const { Signale } = require('signale');
|
||||
const log = new Signale().scope('GTWY');
|
||||
const interactive = new Signale({ interactive: true, scope: 'GTWY' });
|
||||
const stp = require('./STP');
|
||||
const appdata = require('./appdata');
|
||||
|
||||
class Gateway {
|
||||
constructor(identity, endpoints) {
|
||||
this.identity = identity;
|
||||
|
||||
this.endpoints = new Keyv({
|
||||
store: new KeyvFile({
|
||||
filename: `${appdata}/valnet/relay/${this.identity.name}-endpoints.json`
|
||||
})
|
||||
});
|
||||
|
||||
this.ready = this.insertEndpoints(endpoints)
|
||||
.then(this.networkTest.bind(this));
|
||||
}
|
||||
|
||||
async insertEndpoints(endpoints) {
|
||||
for (const endpoint of endpoints) {
|
||||
const storeValue = await this.endpoints.get(endpoint);
|
||||
if (storeValue) continue;
|
||||
|
||||
const [host, port] = endpoint.split(':');
|
||||
const record = new EndpointRecord(host, port, null, 'unknown');
|
||||
const currentEnpoints = await this.endpoints.get('cache') || [];
|
||||
|
||||
if (currentEnpoints.indexOf(endpoint) === -1) {
|
||||
currentEnpoints.push(endpoint);
|
||||
await this.endpoints.set('cache', currentEnpoints);
|
||||
}
|
||||
|
||||
await this.endpoints.set(endpoint, record);
|
||||
}
|
||||
|
||||
log.info('gateway endpoints:');
|
||||
log.info('\t' + (await this.endpoints.get('cache')).join('\n\t'));
|
||||
}
|
||||
|
||||
async networkTest() {
|
||||
const endpoints = (await Promise.all(
|
||||
(await this.endpoints.get('cache'))
|
||||
.map(endpoint => this.endpoints.get(endpoint))
|
||||
)).map(EndpointRecord.fromJson);
|
||||
|
||||
for (const endpoint of endpoints) {
|
||||
await this.testEndpoint(endpoint.host, endpoint.port);
|
||||
}
|
||||
}
|
||||
|
||||
async testEndpoint(host, port) {
|
||||
await new Promise(async (res, rej) => {
|
||||
let pings = [];
|
||||
let maxPings = 10;
|
||||
let connectionAttempts = 0;
|
||||
log.info(`Connecting to ${host}:${port}...`);
|
||||
|
||||
while (connectionAttempts < 10 && pings.length < maxPings) {
|
||||
|
||||
await new Promise(async (res) => {
|
||||
const client = stp.connect({
|
||||
identity: this.identity,
|
||||
ip: host,
|
||||
port: parseInt(port)
|
||||
});
|
||||
|
||||
client.on('error', _ => _);
|
||||
|
||||
client.on('ready', async () => {
|
||||
while (pings.length < maxPings) {
|
||||
interactive.info(`[${pings.length + 1}/${maxPings}] Testing connection...`);
|
||||
pings.push(await client.ping());
|
||||
// pings.push(10);
|
||||
await new Promise(res => setTimeout(res, 100));
|
||||
}
|
||||
const average = Math.round(pings.reduce((a, v) => a + v, 0) / maxPings);
|
||||
interactive.success(`Test complete. Average Ping: ${average}`)
|
||||
client.tcpSocket.destroy();
|
||||
res();
|
||||
});
|
||||
|
||||
client.on('close', () => {
|
||||
res();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class EndpointRecord {
|
||||
|
||||
/**
|
||||
* @param {Object|string} json string / object representation
|
||||
* @returns {EndpointRecord}
|
||||
*/
|
||||
static fromJson(obj) {
|
||||
if (typeof obj === 'string')
|
||||
return EndpointRecord.fromJson(JSON.parse(obj));
|
||||
|
||||
return new EndpointRecord(
|
||||
obj.host,
|
||||
obj.port,
|
||||
obj.lastPing ? new PingRecord(
|
||||
obj.lastPing.average,
|
||||
obj.lastPing.tests,
|
||||
obj.lastPing.date
|
||||
) : null,
|
||||
obj.status
|
||||
);
|
||||
}
|
||||
|
||||
constructor(host, port, lastPing, status) {
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.lastPing = lastPing;
|
||||
this.status = status;
|
||||
}
|
||||
}
|
||||
|
||||
class PingRecord {
|
||||
constructor(average, tests, date) {
|
||||
this.average = average;
|
||||
this.tests = tests;
|
||||
this.date = date;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Gateway
|
||||
|
|
@ -4,6 +4,7 @@ const { hri } = require('human-readable-ids');
|
|||
const os = require('os');
|
||||
const NodeRSA = require('node-rsa');
|
||||
let log = require('signale').scope('Identity(null)');
|
||||
const appdata = require('./appdata');
|
||||
|
||||
module.exports.Identity = class Identity {
|
||||
kv;
|
||||
|
|
@ -13,9 +14,10 @@ module.exports.Identity = class Identity {
|
|||
/// ASYNC CONSTRUCTOR
|
||||
constructor(module, id) {
|
||||
return new Promise(async (res, rej) => {
|
||||
|
||||
const kv = new Keyv({
|
||||
store: new KeyvFile({
|
||||
filename: `${os.tmpdir()}/valnet/${module}/${id}.json`
|
||||
filename: `${appdata}/valnet/${module}/${id}.json`
|
||||
})
|
||||
});
|
||||
|
||||
|
|
@ -67,6 +69,6 @@ module.exports.Identity = class Identity {
|
|||
}
|
||||
|
||||
toString() {
|
||||
return `[Identity(${this.name})]`;
|
||||
return `[Identity ${this.name}]`;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,13 @@
|
|||
const net = require('net');
|
||||
const EventEmitter = require('events');
|
||||
const NodeRSA = require('node-rsa');
|
||||
const log = require('signale').scope('stp');
|
||||
const log = require('signale').scope('_STP');
|
||||
const {
|
||||
KeyExchangePacket,
|
||||
AckPacket
|
||||
AckPacket,
|
||||
PingPacket,
|
||||
PongPacket
|
||||
} = require('./packets');
|
||||
const { rejects } = require('assert');
|
||||
|
||||
module.exports.createServer = function({identity = {}, port = 5000} = {}, cb = _ => _) {
|
||||
const server = new Server(identity, port);
|
||||
|
|
@ -37,7 +38,7 @@ class Server extends EventEmitter {
|
|||
}
|
||||
|
||||
openServer() {
|
||||
log.info(`opening STP server on ${this.port}`);
|
||||
// log.info(`opening STP server on ${this.port}`);
|
||||
this.tcpServer = net.createServer(this.tcpConnectClient.bind(this));
|
||||
this.tcpServer.on('error', e => {
|
||||
log.warn(e)
|
||||
|
|
@ -56,11 +57,17 @@ class Server extends EventEmitter {
|
|||
|
||||
class STPSocket extends EventEmitter {
|
||||
tcpSocket;
|
||||
readyState = 0;
|
||||
buffer = '';
|
||||
externalKey;
|
||||
identity;
|
||||
|
||||
CONNECTING = Symbol('connecting');
|
||||
EXCHANGE = Symbol('exchange');
|
||||
SECURED = Symbol('secured');
|
||||
readyState = this.CONNECTING;
|
||||
|
||||
pingCallbacks = new Map();
|
||||
|
||||
get loopback() {
|
||||
return this.identity.publicKey ===
|
||||
this.externalKey.exportKey('pkcs8-public-pem');
|
||||
|
|
@ -113,24 +120,33 @@ class STPSocket extends EventEmitter {
|
|||
}
|
||||
|
||||
processMessage(obj) {
|
||||
switch(obj.cmd) {
|
||||
case 'KEY': {
|
||||
if(this.readyState === 0) {
|
||||
this.externalKey = new NodeRSA();
|
||||
this.externalKey.importKey(obj.data.key, 'pkcs8-public-pem');
|
||||
this.tcpSocket.write(new AckPacket().toBuffer());
|
||||
this.readyState = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'ACK': {
|
||||
if(this.readyState === 1) {
|
||||
this.readyState = 2;
|
||||
this.emit('ready');
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(this.readyState === this.CONNECTING && obj.cmd === 'KEY') {
|
||||
this.externalKey = new NodeRSA();
|
||||
this.externalKey.importKey(obj.data.key, 'pkcs8-public-pem');
|
||||
this.tcpSocket.write(new AckPacket().toBuffer());
|
||||
this.readyState = this.EXCHANGE;
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.readyState === this.EXCHANGE && obj.cmd === 'ACK') {
|
||||
this.readyState = this.SECURED;
|
||||
this.emit('ready');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.readyState === this.SECURED && obj.cmd === 'PING') {
|
||||
this.tcpSocket.write(new PongPacket(obj.data.id).toBuffer());
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.readyState === this.SECURED && obj.cmd === 'PONG') {
|
||||
if (this.pingCallbacks.has(obj.data.id)) {
|
||||
this.pingCallbacks.get(obj.data.id)();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handshake() {
|
||||
|
|
@ -139,4 +155,17 @@ class STPSocket extends EventEmitter {
|
|||
const buffer = packet.toBuffer();
|
||||
this.tcpSocket.write(buffer);
|
||||
}
|
||||
|
||||
async ping() {
|
||||
const startTime = new Date().getTime();
|
||||
return await new Promise(async (res) => {
|
||||
const packet = new PingPacket();
|
||||
this.pingCallbacks.set(packet.data.id, _ => {
|
||||
res(new Date().getTime() - startTime);
|
||||
this.pingCallbacks.delete(packet.data.id);
|
||||
});
|
||||
this.tcpSocket.write(packet.toBuffer());
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
const md5 = require('md5');
|
||||
|
||||
// #region === [ private lib functions ] ===
|
||||
|
||||
class STPPacket {
|
||||
cmd = 'NOOP';
|
||||
|
|
@ -14,15 +16,6 @@ class STPPacket {
|
|||
}
|
||||
}
|
||||
|
||||
class KeyExchangePacket extends STPPacket {
|
||||
constructor(key, type = 'pkcs8-pem') {
|
||||
super();
|
||||
this.cmd = 'KEY';
|
||||
this.data.key = key;
|
||||
this.meta.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
function basicPacket(commandName) {
|
||||
return class extends STPPacket {
|
||||
constructor() {
|
||||
|
|
@ -32,7 +25,87 @@ function basicPacket(commandName) {
|
|||
}
|
||||
}
|
||||
|
||||
module.exports.STPPacket = STPPacket;
|
||||
// #endregion
|
||||
|
||||
// #region === [ exotic packet classes ] ===
|
||||
|
||||
class KeyExchangePacket extends STPPacket {
|
||||
constructor(key, type = 'pkcs8-pem') {
|
||||
super();
|
||||
this.cmd = 'KEY';
|
||||
this.data.key = key;
|
||||
this.meta.type = type;
|
||||
}
|
||||
}
|
||||
|
||||
class ClientsPacket extends STPPacket {
|
||||
constructor(clients) {
|
||||
super();
|
||||
this.cmd = 'NODES'
|
||||
this.data.clients = clients;
|
||||
}
|
||||
}
|
||||
|
||||
class PingPacket extends STPPacket {
|
||||
constructor() {
|
||||
super();
|
||||
this.cmd = 'PING';
|
||||
this.data.id = md5(Date());
|
||||
}
|
||||
}
|
||||
|
||||
class PongPacket extends STPPacket {
|
||||
constructor(id) {
|
||||
super();
|
||||
this.cmd = 'PONG';
|
||||
this.data.id = id;
|
||||
}
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region === [ ordinary packet classes ] ===
|
||||
|
||||
const AckPacket = basicPacket('ACK');
|
||||
const GetClientsPacket = basicPacket('QNODES');
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region === [ public lib functions ] ===
|
||||
|
||||
function reconstructPacket(packet) {
|
||||
|
||||
if(packet.startsWith('\02'))
|
||||
return reconstructPacket(packet.substr(1));
|
||||
if(packet.endsWith('\x03'))
|
||||
return reconstructPacket(packet.substr(0, packet.length - 1));
|
||||
|
||||
const obj = JSON.parse(packet);
|
||||
|
||||
switch(obj.cmd) {
|
||||
case 'KEY': return new KeyExchangePacket(obj.data.key, obj.meta.type);
|
||||
case 'NODES': return new ClientsPacket(obj.data.clients);
|
||||
case 'QNODES': return new GetClientsPacket();
|
||||
case 'ACK': return new AckPacket();
|
||||
|
||||
case 'NOOP': return new STPPacket();
|
||||
default: throw new TypeError(`Unknown command ${obj.cmd}`);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// #endregion
|
||||
|
||||
// #region === [ exports ] ===
|
||||
|
||||
module.exports.KeyExchangePacket = KeyExchangePacket;
|
||||
module.exports.AckPacket = basicPacket('ACK')
|
||||
module.exports.GetClientsPacket = basicPacket('NODES')
|
||||
module.exports.ClientsPacket = ClientsPacket;
|
||||
module.exports.PingPacket = PingPacket;
|
||||
module.exports.PongPacket = PongPacket;
|
||||
|
||||
module.exports.AckPacket = AckPacket;
|
||||
module.exports.GetClientsPacket = GetClientsPacket;
|
||||
|
||||
module.exports.reconstructPacket = reconstructPacket;
|
||||
|
||||
// #endregion
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
const appdata = process.env.APPDATA || (process.platform == 'darwin' ? process.env.HOME + '/Library/Preferences' : process.env.HOME + "/.local/share");
|
||||
|
||||
module.exports = appdata;
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
const pkg = require('./../package.json');
|
||||
const { readFileSync, writeFileSync } = require('fs');
|
||||
const { ensureDirSync } = require('fs-extra');
|
||||
|
||||
const appdata = require('./appdata');
|
||||
ensureDirSync(`${appdata}/valnet/relay`);
|
||||
const filepath = `${appdata}/valnet/relay/config.json`;
|
||||
|
||||
const configObject = {}
|
||||
|
||||
module.exports.config = configObject;
|
||||
|
||||
module.exports.write = write;
|
||||
|
||||
function write() {
|
||||
writeFileSync(filepath, JSON.stringify(configObject, null, 2));
|
||||
}
|
||||
|
||||
function importFromPackage() {
|
||||
loadObject(pkg.config);
|
||||
}
|
||||
|
||||
function loadObject(obj) {
|
||||
for(const key in obj) {
|
||||
configObject[key] = obj[key];
|
||||
}
|
||||
|
||||
write();
|
||||
}
|
||||
|
||||
try {
|
||||
const json = readFileSync(filepath);
|
||||
const data = JSON.parse(json);
|
||||
|
||||
loadObject(data);
|
||||
|
||||
} catch(e) {
|
||||
importFromPackage();
|
||||
}
|
||||
106
lib/node.js
106
lib/node.js
|
|
@ -1,11 +1,111 @@
|
|||
const EventEmitter = require('events')
|
||||
|
||||
const stp = require('./STP');
|
||||
const upnp = require('./upnp');
|
||||
const md5 = require('md5');
|
||||
const pkg = require('./../package.json');
|
||||
const { config, write } = require('./config.js');
|
||||
const log = require('signale').scope('NODE');
|
||||
const bonjour = require('bonjour')();
|
||||
const Gateway = require('./Gateway');
|
||||
|
||||
class Node extends EventEmitter {
|
||||
constructor() {
|
||||
clients = [];
|
||||
hash = null;
|
||||
name = null;
|
||||
readyPromise = null;
|
||||
port = null;
|
||||
identity;
|
||||
multicastAd = null;
|
||||
multicastBrowser = null;
|
||||
connected = false;
|
||||
|
||||
constructor(identity) {
|
||||
super();
|
||||
this.identity = identity;
|
||||
this.hash = md5(identity.publicKey);
|
||||
this.name = `valnet-node-${identity.name}`;
|
||||
|
||||
this.readyPromise = this.negotiatePort()
|
||||
.then(this.startServer.bind(this))
|
||||
.catch(this.serverStartupFailed.bind(this))
|
||||
.then(this.connectNetwork.bind(this))
|
||||
}
|
||||
|
||||
async connectNetwork() {
|
||||
const gateway = new Gateway(this.identity, config.endpoints);
|
||||
}
|
||||
|
||||
async serverStartupFailed(error) {
|
||||
log.warn('Failed to set up Valet server on node.')
|
||||
}
|
||||
|
||||
async startServer() {
|
||||
log.info('creating Valnet Node on port ' + this.port + '...');
|
||||
|
||||
stp.createServer({
|
||||
identity: this.identity,
|
||||
port: this.port
|
||||
}, (connection) => {
|
||||
log.info('incomming connection from ' + connection.remoteAddress);
|
||||
});
|
||||
|
||||
log.info('advertising node on multicast...')
|
||||
this.multicastAd = bonjour.publish({
|
||||
name: this.name,
|
||||
type: 'STP',
|
||||
port: this.port
|
||||
});
|
||||
|
||||
this.multicastBrowser = bonjour.find({});
|
||||
|
||||
this.multicastBrowser.on('up', this.serviceUp.bind(this));
|
||||
this.multicastBrowser.on('down', this.serviceDown.bind(this));
|
||||
|
||||
// log.success('Node successfully registered!');
|
||||
}
|
||||
|
||||
async serviceUp({name, address, port, protocol}) {
|
||||
// log.debug(`Found ${name} @ ${address}:${port} using ${protocol}`);
|
||||
}
|
||||
|
||||
async serviceDown(service) {
|
||||
log.debug('down', service);
|
||||
}
|
||||
|
||||
async negotiatePort() {
|
||||
const mappings = await upnp.mappings();
|
||||
const matchingMappings = mappings.filter(mapping => {
|
||||
return mapping.description === this.name
|
||||
});
|
||||
const alreadyMapped = matchingMappings.length > 0;
|
||||
const takenPorts = mappings.map(mapping => mapping.public.port);
|
||||
|
||||
if(alreadyMapped) {
|
||||
this.port = matchingMappings[0].public.port;
|
||||
log.success(`upnp port ${this.port} already registered!`);
|
||||
return;
|
||||
}
|
||||
|
||||
for(let port = config.ports.relay; port <= config.ports.relayEnd; port ++) {
|
||||
if(takenPorts.indexOf(port) === -1) {
|
||||
await upnp.mapIndefinite(port, this.name);
|
||||
this.port = port;
|
||||
log.success(`registered upnp port ${this.port}`);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// console.log(mappings, this.hash);
|
||||
}
|
||||
|
||||
static get Node() {
|
||||
return Node;
|
||||
}
|
||||
|
||||
get ready() {
|
||||
return this.readyPromise;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
module.exports.Node = Node;
|
||||
module.exports = Node;
|
||||
22
lib/upnp.js
22
lib/upnp.js
|
|
@ -1,31 +1,34 @@
|
|||
const natUpnp = require('nat-upnp');
|
||||
const client = natUpnp.createClient();
|
||||
module.exports.map = function(port) {
|
||||
|
||||
module.exports.map = function(port, ttl = 10, name = 'upnp application') {
|
||||
return new Promise((res, rej) => {
|
||||
client.portMapping({
|
||||
private: port,
|
||||
public: port,
|
||||
ttl: 10,
|
||||
description: 'valnet'
|
||||
ttl,
|
||||
description: name
|
||||
}, (err) => {
|
||||
if(err) rej(err);
|
||||
res();
|
||||
});
|
||||
});
|
||||
}
|
||||
module.exports.mapIndefinite = function(port) {
|
||||
};
|
||||
|
||||
module.exports.mapIndefinite = function(port, name = 'upnp application') {
|
||||
return new Promise((res, rej) => {
|
||||
client.portMapping({
|
||||
private: port,
|
||||
public: port,
|
||||
ttl: 0,
|
||||
description: 'valnet'
|
||||
description: name
|
||||
}, (err) => {
|
||||
if(err) rej(err);
|
||||
res();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.unmap = function(port) {
|
||||
return new Promise((res, rej) => {
|
||||
client.portUnmapping({
|
||||
|
|
@ -36,7 +39,8 @@ module.exports.unmap = function(port) {
|
|||
res();
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
module.exports.mappings = function() {
|
||||
return new Promise((res, rej) => {
|
||||
client.getMappings((err, mappings) => {
|
||||
|
|
@ -44,7 +48,7 @@ module.exports.mappings = function() {
|
|||
res(mappings);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
(async () => {
|
||||
const { config } = require('./../package.json');
|
||||
const net = require('net');
|
||||
const dns = require('dns');
|
||||
const stp = require('../lib/STP');
|
||||
const os = require('os');
|
||||
const { title } = require('../lib/title');
|
||||
const { hri } = require('human-readable-ids');
|
||||
const log = require('signale');
|
||||
const Keyv = require('keyv');
|
||||
const { KeyvFile } = require('keyv-file');
|
||||
const kv = new Keyv({
|
||||
store: new KeyvFile({
|
||||
filename: `${os.tmpdir()}/valnet/name-server/data.json`
|
||||
})
|
||||
});
|
||||
const { Identity } = require('./../lib/Identity');
|
||||
title('Name Server');
|
||||
|
||||
const identity = new Identity('name-server', 'default');
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
})();
|
||||
13
package.json
13
package.json
|
|
@ -6,29 +6,34 @@
|
|||
"config": {
|
||||
"ports": {
|
||||
"relay": 5600,
|
||||
"relayEnd": 5699,
|
||||
"http": 5700,
|
||||
"service": 5000
|
||||
},
|
||||
"addresses": {
|
||||
"relay": "valnet.xyz"
|
||||
}
|
||||
},
|
||||
"endpoints": [
|
||||
"valnet.xyz:5500"
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"name-server": "supervisor -w name-server,lib -n exit name-server/index.js",
|
||||
"relay": "supervisor -w relay,lib -n exit relay/index.js",
|
||||
"relay:service": "supervisor -- relay/service",
|
||||
"client:a": "supervisor -w client,lib -n exit -- client/index.js --profile J2aV59rsIgcdd5k2",
|
||||
"client:b": "supervisor -w client,lib -n exit -- client/index.js --profile LsE8OnVzr1iYrkT0"
|
||||
"sloc": "find lib -type f | xargs wc -l"
|
||||
},
|
||||
"dependencies": {
|
||||
"bonjour": "^3.5.0",
|
||||
"express": "^4.17.1",
|
||||
"express-ws": "^4.0.0",
|
||||
"font-ascii": "^1.2.1",
|
||||
"fs-extra": "^9.1.0",
|
||||
"gradient-string": "^1.2.0",
|
||||
"human-readable-ids": "^1.0.4",
|
||||
"ip": "^1.1.5",
|
||||
"keyv": "^4.0.3",
|
||||
"keyv-file": "^0.2.0",
|
||||
"md5": "^2.3.0",
|
||||
"nat-upnp": "^1.1.1",
|
||||
"nedb": "^1.8.0",
|
||||
"node-rsa": "^1.1.1",
|
||||
|
|
|
|||
|
|
@ -1,51 +1,16 @@
|
|||
(async () => {
|
||||
const { title } = require('../lib/title');
|
||||
const net = require('net');
|
||||
const log = require('signale').scope('relay');
|
||||
const { config } = require('../package.json');
|
||||
const log = require('signale').scope('RLAY');
|
||||
const { Identity } = require('../lib/Identity');
|
||||
const stp = require('../lib/STP');
|
||||
title('relay', false);
|
||||
const identity = await new Identity('relay', 'default');
|
||||
const upnp = require('../lib/upnp');
|
||||
const Node = require('../lib/node');
|
||||
const { config } = require('../lib/config');
|
||||
const { ensureDirSync } = require('fs-extra');
|
||||
const appdata = require('../lib/appdata');
|
||||
|
||||
const clients = [];
|
||||
|
||||
// const client = stp.connect(identity, config.ports.relay, '127.0.0.1');
|
||||
|
||||
// upnp.mapIndefinite(5600);
|
||||
|
||||
// ==================================== [STP SERVER]
|
||||
stp.createServer({
|
||||
identity: identity,
|
||||
port: config.ports.relay
|
||||
}, socket => {
|
||||
log.info('secured connection from ' + socket.remoteAddress);
|
||||
clients.push(socket);
|
||||
});
|
||||
|
||||
function connectNetwork(t = 1000) {
|
||||
if(t > 60000) t /= 2;
|
||||
|
||||
const client = stp.connect({
|
||||
identity,
|
||||
port: config.ports.relay,
|
||||
ip: config.addresses.relay
|
||||
});
|
||||
client.on('ready', () => {
|
||||
log.success('connectd to relay!');
|
||||
t = 500;
|
||||
})
|
||||
client.on('error', e => {
|
||||
});
|
||||
client.on('close', e => {
|
||||
t *= 2;
|
||||
setTimeout(connectNetwork.bind(global, t), t);
|
||||
log.warn('disconnected from relay');
|
||||
log.warn('retrying connection... ' + (t/1000) + 's')
|
||||
});
|
||||
}
|
||||
connectNetwork();
|
||||
ensureDirSync(`${appdata}/valnet/relay`);
|
||||
const node = new Node(identity);
|
||||
|
||||
// ==================================== [EXPRESS]
|
||||
const express = require('express');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
(async () => {
|
||||
const log = require('signale').scope('service');
|
||||
const log = require('signale').scope('SRVC');
|
||||
const { execSync, spawn } = require('child_process');
|
||||
const branch = execSync('git rev-parse --abbrev-ref HEAD').toString().trim();
|
||||
let proc;
|
||||
|
|
@ -12,6 +12,12 @@ const { config } = require('../package.json');
|
|||
const express = require('express');
|
||||
const app = express();
|
||||
|
||||
try {
|
||||
appendLogs('yarn', execSync(`yarn`));
|
||||
} catch (e) {
|
||||
appendLogs('failed to yarn install...')
|
||||
}
|
||||
|
||||
logp('==================================');
|
||||
logp('Starting Valnet Node as a Service!');
|
||||
logp('Syncing to branch: ' + branch);
|
||||
|
|
@ -130,14 +136,14 @@ ${docs.map(logItem => logItem.message).join('').replace(/\u001B\[.*?[A-Za-z]/g,
|
|||
</pre>
|
||||
<br><br><br><br><br><br>
|
||||
<script>
|
||||
requestAnimationFrame(_ => {
|
||||
requestAnimationFrame(_ => {
|
||||
window.scrollTo(0,document.body.scrollHeight);
|
||||
});
|
||||
});
|
||||
setTimeout(_ => {
|
||||
location.reload();
|
||||
}, 2000);
|
||||
// requestAnimationFrame(_ => {
|
||||
// requestAnimationFrame(_ => {
|
||||
// window.scrollTo(0,document.body.scrollHeight);
|
||||
// });
|
||||
// });
|
||||
// setTimeout(_ => {
|
||||
// location.reload();
|
||||
// }, 2000);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
2
upnp.js
2
upnp.js
|
|
@ -42,8 +42,6 @@ function searchGateway(timeout, callback) {
|
|||
|
||||
var onlistening = function() {
|
||||
|
||||
console.log('listening?')
|
||||
|
||||
socket.setBroadcast(socket.fd, true);
|
||||
// send a few packets just in case.
|
||||
socket.send(reqbuf, 0, reqbuf.length, SSDP_PORT,bcast);
|
||||
|
|
|
|||
160
yarn.lock
160
yarn.lock
|
|
@ -52,6 +52,10 @@ array-flatten@1.1.1:
|
|||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2"
|
||||
|
||||
array-flatten@^2.1.0:
|
||||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099"
|
||||
|
||||
array-includes@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.1.tgz#cdd67e6852bdf9c1215460786732255ed2459348"
|
||||
|
|
@ -95,6 +99,11 @@ asynckit@^0.4.0:
|
|||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||
|
||||
at-least-node@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
|
||||
integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==
|
||||
|
||||
aws-sign2@~0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
|
||||
|
|
@ -134,6 +143,17 @@ body-parser@1.19.0:
|
|||
raw-body "2.4.0"
|
||||
type-is "~1.6.17"
|
||||
|
||||
bonjour@^3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5"
|
||||
dependencies:
|
||||
array-flatten "^2.1.0"
|
||||
deep-equal "^1.0.1"
|
||||
dns-equal "^1.0.0"
|
||||
dns-txt "^2.0.2"
|
||||
multicast-dns "^6.0.1"
|
||||
multicast-dns-service-types "^1.1.0"
|
||||
|
||||
brace-expansion@^1.1.7:
|
||||
version "1.1.11"
|
||||
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||
|
|
@ -141,6 +161,10 @@ brace-expansion@^1.1.7:
|
|||
balanced-match "^1.0.0"
|
||||
concat-map "0.0.1"
|
||||
|
||||
buffer-indexof@^1.0.0:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c"
|
||||
|
||||
bytes@3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6"
|
||||
|
|
@ -152,6 +176,13 @@ call-bind@^1.0.0:
|
|||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.0.0"
|
||||
|
||||
call-bind@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c"
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
get-intrinsic "^1.0.2"
|
||||
|
||||
caseless@~0.12.0:
|
||||
version "0.12.0"
|
||||
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
|
||||
|
|
@ -175,6 +206,10 @@ chardet@^0.7.0:
|
|||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
|
||||
|
||||
charenc@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
|
||||
|
||||
cli-cursor@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307"
|
||||
|
|
@ -253,6 +288,10 @@ core-util-is@1.0.2:
|
|||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||
|
||||
crypt@0.0.2:
|
||||
version "0.0.2"
|
||||
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
|
||||
|
||||
dashdash@^1.12.0:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
|
||||
|
|
@ -271,6 +310,17 @@ debug@^4.1.1:
|
|||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
deep-equal@^1.0.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
|
||||
dependencies:
|
||||
is-arguments "^1.0.4"
|
||||
is-date-object "^1.0.1"
|
||||
is-regex "^1.0.4"
|
||||
object-is "^1.0.1"
|
||||
object-keys "^1.1.1"
|
||||
regexp.prototype.flags "^1.2.0"
|
||||
|
||||
define-properties@^1.1.3:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1"
|
||||
|
|
@ -289,6 +339,23 @@ destroy@~1.0.4:
|
|||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80"
|
||||
|
||||
dns-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d"
|
||||
|
||||
dns-packet@^1.3.1:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.1.tgz#12aa426981075be500b910eedcd0b47dd7deda5a"
|
||||
dependencies:
|
||||
ip "^1.1.0"
|
||||
safe-buffer "^5.0.1"
|
||||
|
||||
dns-txt@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6"
|
||||
dependencies:
|
||||
buffer-indexof "^1.0.0"
|
||||
|
||||
doctrine@1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-1.5.0.tgz#379dce730f6166f76cefa4e6707a159b02c5a6fa"
|
||||
|
|
@ -594,6 +661,16 @@ fs-extra@^4.0.1:
|
|||
jsonfile "^4.0.0"
|
||||
universalify "^0.1.0"
|
||||
|
||||
fs-extra@^9.1.0:
|
||||
version "9.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d"
|
||||
integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==
|
||||
dependencies:
|
||||
at-least-node "^1.0.0"
|
||||
graceful-fs "^4.2.0"
|
||||
jsonfile "^6.0.1"
|
||||
universalify "^2.0.0"
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
|
|
@ -610,6 +687,14 @@ get-intrinsic@^1.0.0:
|
|||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
get-intrinsic@^1.0.2:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6"
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
getpass@^0.1.1:
|
||||
version "0.1.7"
|
||||
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
|
||||
|
|
@ -620,6 +705,11 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6:
|
|||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||
|
||||
graceful-fs@^4.2.0:
|
||||
version "4.2.6"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
|
||||
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
|
||||
|
||||
gradient-string@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/gradient-string/-/gradient-string-1.2.0.tgz#93f39f2c7c8dcb095608c2ccf0aac24aa315fbac"
|
||||
|
|
@ -734,7 +824,7 @@ inquirer@^7.0.0:
|
|||
strip-ansi "^6.0.0"
|
||||
through "^2.3.6"
|
||||
|
||||
ip@^1.1.4, ip@^1.1.5:
|
||||
ip@^1.1.0, ip@^1.1.4, ip@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a"
|
||||
|
||||
|
|
@ -742,10 +832,20 @@ ipaddr.js@1.9.1:
|
|||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3"
|
||||
|
||||
is-arguments@^1.0.4:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
|
||||
dependencies:
|
||||
call-bind "^1.0.0"
|
||||
|
||||
is-arrayish@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||
|
||||
is-buffer@~1.1.6:
|
||||
version "1.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
|
||||
is-callable@^1.1.4, is-callable@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.2.tgz#c7c6715cd22d4ddb48d3e19970223aceabb080d9"
|
||||
|
|
@ -768,6 +868,13 @@ is-negative-zero@^2.0.0:
|
|||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.0.tgz#9553b121b0fac28869da9ed459e20c7543788461"
|
||||
|
||||
is-regex@^1.0.4:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.2.tgz#81c8ebde4db142f2cf1c53fc86d6a45788266251"
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
is-regex@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.1.tgz#c6f98aacc546f6cec5468a07b7b153ab564a57b9"
|
||||
|
|
@ -832,6 +939,15 @@ jsonfile@^4.0.0:
|
|||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsonfile@^6.0.1:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
|
||||
integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
|
||||
dependencies:
|
||||
universalify "^2.0.0"
|
||||
optionalDependencies:
|
||||
graceful-fs "^4.1.6"
|
||||
|
||||
jsprim@^1.2.2:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
|
||||
|
|
@ -900,6 +1016,14 @@ lodash@^4.17.14, lodash@^4.17.19:
|
|||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
|
||||
md5@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/md5/-/md5-2.3.0.tgz#c3da9a6aae3a30b46b7b0c349b87b110dc3bda4f"
|
||||
dependencies:
|
||||
charenc "0.0.2"
|
||||
crypt "0.0.2"
|
||||
is-buffer "~1.1.6"
|
||||
|
||||
media-typer@0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748"
|
||||
|
|
@ -968,6 +1092,17 @@ ms@2.1.2:
|
|||
version "2.1.2"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||
|
||||
multicast-dns-service-types@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901"
|
||||
|
||||
multicast-dns@^6.0.1:
|
||||
version "6.2.3"
|
||||
resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229"
|
||||
dependencies:
|
||||
dns-packet "^1.3.1"
|
||||
thunky "^1.0.2"
|
||||
|
||||
mute-stream@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
|
||||
|
|
@ -1018,6 +1153,13 @@ object-inspect@^1.8.0:
|
|||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
|
||||
|
||||
object-is@^1.0.1:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
object-keys@^1.0.12, object-keys@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
|
||||
|
|
@ -1191,6 +1333,13 @@ read-pkg@^2.0.0:
|
|||
normalize-package-data "^2.3.2"
|
||||
path-type "^2.0.0"
|
||||
|
||||
regexp.prototype.flags@^1.2.0:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26"
|
||||
dependencies:
|
||||
call-bind "^1.0.2"
|
||||
define-properties "^1.1.3"
|
||||
|
||||
regexpp@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
|
||||
|
|
@ -1407,6 +1556,10 @@ through@^2.3.6:
|
|||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
|
||||
|
||||
thunky@^1.0.2:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d"
|
||||
|
||||
tinycolor2@^1.0.0:
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.2.tgz#3f6a4d1071ad07676d7fa472e1fac40a719d8803"
|
||||
|
|
@ -1477,6 +1630,11 @@ universalify@^0.1.0:
|
|||
version "0.1.2"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
|
||||
|
||||
universalify@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
|
||||
integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
|
||||
|
||||
unpipe@1.0.0, unpipe@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec"
|
||||
|
|
|
|||
Reference in New Issue