From 9354ad5afa57ad0f1b521c5e317616d899f38cf7 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 29 Jan 2020 13:12:30 +0100 Subject: [PATCH] Add packages/faucet --- NOTICE | 3 + packages/faucet/.eslintignore | 1 + packages/faucet/.gitignore | 3 + packages/faucet/bin/cosm-faucet | 6 + packages/faucet/nonces/README.txt | 1 + packages/faucet/package.json | 62 ++ packages/faucet/src/actions/generate.ts | 20 + packages/faucet/src/actions/help.ts | 33 + packages/faucet/src/actions/index.ts | 4 + .../src/actions/start/httperror.spec.ts | 20 + .../faucet/src/actions/start/httperror.ts | 5 + packages/faucet/src/actions/start/index.ts | 1 + .../src/actions/start/requestparser.spec.ts | 48 + .../faucet/src/actions/start/requestparser.ts | 35 + packages/faucet/src/actions/start/start.ts | 157 ++++ packages/faucet/src/actions/version.ts | 15 + packages/faucet/src/cashflow.spec.ts | 163 ++++ packages/faucet/src/cashflow.ts | 95 ++ packages/faucet/src/codec.spec.ts | 16 + packages/faucet/src/codec.ts | 80 ++ packages/faucet/src/constants.ts | 7 + packages/faucet/src/crypto.ts | 15 + packages/faucet/src/debugging.ts | 58 ++ packages/faucet/src/faucet.ts | 38 + packages/faucet/src/hdpaths.spec.ts | 45 + packages/faucet/src/hdpaths.ts | 10 + packages/faucet/src/multichainhelpers.spec.ts | 57 ++ packages/faucet/src/multichainhelpers.ts | 145 +++ packages/faucet/src/profile.ts | 34 + packages/faucet/src/types.ts | 10 + packages/faucet/tsconfig.json | 12 + packages/faucet/tslint.json | 3 + packages/faucet/typedoc.js | 14 + yarn.lock | 833 +++++++++++++++++- 34 files changed, 2006 insertions(+), 43 deletions(-) create mode 120000 packages/faucet/.eslintignore create mode 100644 packages/faucet/.gitignore create mode 100755 packages/faucet/bin/cosm-faucet create mode 100644 packages/faucet/nonces/README.txt create mode 100644 packages/faucet/package.json create mode 100644 packages/faucet/src/actions/generate.ts create mode 100644 packages/faucet/src/actions/help.ts create mode 100644 packages/faucet/src/actions/index.ts create mode 100644 packages/faucet/src/actions/start/httperror.spec.ts create mode 100644 packages/faucet/src/actions/start/httperror.ts create mode 100644 packages/faucet/src/actions/start/index.ts create mode 100644 packages/faucet/src/actions/start/requestparser.spec.ts create mode 100644 packages/faucet/src/actions/start/requestparser.ts create mode 100644 packages/faucet/src/actions/start/start.ts create mode 100644 packages/faucet/src/actions/version.ts create mode 100644 packages/faucet/src/cashflow.spec.ts create mode 100644 packages/faucet/src/cashflow.ts create mode 100644 packages/faucet/src/codec.spec.ts create mode 100644 packages/faucet/src/codec.ts create mode 100644 packages/faucet/src/constants.ts create mode 100644 packages/faucet/src/crypto.ts create mode 100644 packages/faucet/src/debugging.ts create mode 100644 packages/faucet/src/faucet.ts create mode 100644 packages/faucet/src/hdpaths.spec.ts create mode 100644 packages/faucet/src/hdpaths.ts create mode 100644 packages/faucet/src/multichainhelpers.spec.ts create mode 100644 packages/faucet/src/multichainhelpers.ts create mode 100644 packages/faucet/src/profile.ts create mode 100644 packages/faucet/src/types.ts create mode 100644 packages/faucet/tsconfig.json create mode 100644 packages/faucet/tslint.json create mode 100644 packages/faucet/typedoc.js diff --git a/NOTICE b/NOTICE index 24ba00c8..216009de 100644 --- a/NOTICE +++ b/NOTICE @@ -2,6 +2,9 @@ This repository was forked from the folders packages/iov-cosmos and scripts/cosm of https://github.com/iov-one/iov-core at tag v2.0.0-alpha.7. It was repurposed and heavily modified from there on. +The code in packages/faucet was forked from https://github.com/iov-one/iov-faucet on +2020-01-29 at commit 33e2d707e7. + Copyright 2018-2020 IOV SAS Copyright 2020 Confio UO Copyright 2020 Simon Warta diff --git a/packages/faucet/.eslintignore b/packages/faucet/.eslintignore new file mode 120000 index 00000000..86039baf --- /dev/null +++ b/packages/faucet/.eslintignore @@ -0,0 +1 @@ +../../.eslintignore \ No newline at end of file diff --git a/packages/faucet/.gitignore b/packages/faucet/.gitignore new file mode 100644 index 00000000..68bf3735 --- /dev/null +++ b/packages/faucet/.gitignore @@ -0,0 +1,3 @@ +build/ +dist/ +docs/ diff --git a/packages/faucet/bin/cosm-faucet b/packages/faucet/bin/cosm-faucet new file mode 100755 index 00000000..c44ac640 --- /dev/null +++ b/packages/faucet/bin/cosm-faucet @@ -0,0 +1,6 @@ +#!/usr/bin/env node +const path = require("path"); + +// attempt to call in main file.... +const faucet = require(path.join(__dirname, "..", "build", "faucet.js")); +faucet.main(process.argv.slice(2)); diff --git a/packages/faucet/nonces/README.txt b/packages/faucet/nonces/README.txt new file mode 100644 index 00000000..092fe732 --- /dev/null +++ b/packages/faucet/nonces/README.txt @@ -0,0 +1 @@ +Directory used to trigger lerna package updates for all packages diff --git a/packages/faucet/package.json b/packages/faucet/package.json new file mode 100644 index 00000000..4e156995 --- /dev/null +++ b/packages/faucet/package.json @@ -0,0 +1,62 @@ +{ + "name": "@cosmwasm/faucet", + "version": "0.0.1", + "description": "The faucet", + "author": "Ethan Frey ", + "license": "Apache-2.0", + "main": "build/index.js", + "types": "types/index.d.ts", + "files": [ + "build/", + "types/", + "*.md", + "!*.spec.*", + "!**/testdata/" + ], + "repository": { + "type": "git", + "url": "https://github.com/confio/cosm-js/tree/master/packages/faucet" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "docs": "shx rm -rf docs && typedoc --options typedoc.js", + "format": "prettier --write --loglevel warn \"./src/**/*.ts\"", + "lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && tslint -t verbose --project .", + "lint-fix": "eslint --max-warnings 0 \"**/*.{js,ts}\" --fix", + "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts", + "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", + "build": "shx rm -rf ./build && tsc && yarn move-types && yarn format-types", + "build-or-skip": "[ -n \"$SKIP_BUILD\" ] || yarn build", + "test-node": "mocha \"./build/**/*.spec.js\"", + "test": "yarn build-or-skip && yarn test-node" + }, + "dependencies": { + "@iov/bcp": "^2.0.0-alpha.7", + "@iov/bns": "^2.0.0-alpha.7", + "@iov/crypto": "^2.0.0-alpha.7", + "@iov/encoding": "^2.0.0-alpha.7", + "@iov/ethereum": "^2.0.0-alpha.7", + "@iov/lisk": "^2.0.0-alpha.7", + "@iov/multichain": "^2.0.0-alpha.7", + "@koa/cors": "^3.0.0", + "axios": "^0.19.0", + "bn.js": "^5.1.1", + "fast-deep-equal": "^3.1.1", + "koa": "^2.11.0", + "koa-bodyparser": "^4.2.1", + "readonly-date": "^1.0.0", + "xstream": "^11.11.0" + }, + "devDependencies": { + "@types/bn.js": "^4.11.6", + "@types/chai": "^4.2.7", + "@types/koa": "^2.11.0", + "@types/koa-bodyparser": "^4.3.0", + "@types/koa__cors": "^3.0.1", + "@types/mocha": "^5.2.7", + "chai": "^4.2.0", + "mocha": "^7.0.1" + } +} diff --git a/packages/faucet/src/actions/generate.ts b/packages/faucet/src/actions/generate.ts new file mode 100644 index 00000000..3ca673d2 --- /dev/null +++ b/packages/faucet/src/actions/generate.ts @@ -0,0 +1,20 @@ +import { ChainId } from "@iov/bcp"; +import { Bip39, Random } from "@iov/crypto"; +import { UserProfile } from "@iov/keycontrol"; + +import { codecFromString } from "../codec"; +import { setSecretAndCreateIdentities } from "../profile"; + +export async function generate(args: ReadonlyArray): Promise { + if (args.length < 2) { + throw Error(`Not enough arguments for action 'generate'. See 'iov-faucet help' or README for arguments.`); + } + const codecName = codecFromString(args[0]); + const chainId = args[1] as ChainId; + + const mnemonic = Bip39.encode(await Random.getBytes(16)).toString(); + console.info(`FAUCET_MNEMONIC="${mnemonic}"`); + + const profile = new UserProfile(); + await setSecretAndCreateIdentities(profile, mnemonic, chainId, codecName); +} diff --git a/packages/faucet/src/actions/help.ts b/packages/faucet/src/actions/help.ts new file mode 100644 index 00000000..14cfd7ad --- /dev/null +++ b/packages/faucet/src/actions/help.ts @@ -0,0 +1,33 @@ +export function help(): void { + const out = ` +Usage: iov-faucet action [arguments...] + +Positional arguments per action are listed below. Arguments in parentheses are optional. + +help Shows a help text and exits + +version Prints the version and exits + +generate Generates a random mnemonic, shows derived faucet addresses and exits + 1 Codec + 2 Chain ID + +start Starts the faucet + 1 Codec + 2 Node base URL, e.g. wss://bov.friendnet-fast.iov.one + +Environment variables + +FAUCET_CONCURRENCY Number of distributor accounts. Defaults to 5. +FAUCET_PORT Port of the webserver. Defaults to 8000. +FAUCET_MNEMONIC Secret mnemonic that serves as the base secret for the + faucet HD accounts +FAUCET_CREDIT_AMOUNT_TKN Send this amount of TKN to a user requesting TKN. TKN is + a placeholder for the token ticker. Defaults to 10. +FAUCET_REFILL_FACTOR Send factor times credit amount on refilling. Defauls to 8. +FAUCET_REFILL_THRESHOLD Refill when balance gets below factor times credit amount. + Defaults to 20. +`.trim(); + + process.stdout.write(`${out}\n`); +} diff --git a/packages/faucet/src/actions/index.ts b/packages/faucet/src/actions/index.ts new file mode 100644 index 00000000..036bb348 --- /dev/null +++ b/packages/faucet/src/actions/index.ts @@ -0,0 +1,4 @@ +export { generate } from "./generate"; +export { help } from "./help"; +export { start } from "./start"; +export { version } from "./version"; diff --git a/packages/faucet/src/actions/start/httperror.spec.ts b/packages/faucet/src/actions/start/httperror.spec.ts new file mode 100644 index 00000000..9505bce6 --- /dev/null +++ b/packages/faucet/src/actions/start/httperror.spec.ts @@ -0,0 +1,20 @@ +import { expect } from "chai"; + +import { HttpError } from "./httperror"; + +describe("HttpError", () => { + it("can be constructed", () => { + { + const error = new HttpError(400, "Invalid name field"); + expect(error.message).to.eql("Invalid name field"); + expect(error.status).to.eql(400); + expect(error.expose).to.eql(true); + } + { + const error = new HttpError(500, "Out of memory", false); + expect(error.message).to.eql("Out of memory"); + expect(error.status).to.eql(500); + expect(error.expose).to.eql(false); + } + }); +}); diff --git a/packages/faucet/src/actions/start/httperror.ts b/packages/faucet/src/actions/start/httperror.ts new file mode 100644 index 00000000..4bf02237 --- /dev/null +++ b/packages/faucet/src/actions/start/httperror.ts @@ -0,0 +1,5 @@ +export class HttpError extends Error { + constructor(public readonly status: number, text: string, public readonly expose: boolean = true) { + super(text); + } +} diff --git a/packages/faucet/src/actions/start/index.ts b/packages/faucet/src/actions/start/index.ts new file mode 100644 index 00000000..56e0e121 --- /dev/null +++ b/packages/faucet/src/actions/start/index.ts @@ -0,0 +1 @@ +export { start } from "./start"; diff --git a/packages/faucet/src/actions/start/requestparser.spec.ts b/packages/faucet/src/actions/start/requestparser.spec.ts new file mode 100644 index 00000000..c6d68e25 --- /dev/null +++ b/packages/faucet/src/actions/start/requestparser.spec.ts @@ -0,0 +1,48 @@ +import { expect } from "chai"; + +import { RequestParser } from "./requestparser"; + +describe("RequestParser", () => { + it("can process valid credit request", () => { + const body = { address: "abc", ticker: "CASH" }; + expect(RequestParser.parseCreditBody(body)).to.eql({ address: "abc", ticker: "CASH" }); + }); + + it("throws for invalid credit requests", () => { + // address unset + { + const body = { ticker: "CASH" }; + expect(() => RequestParser.parseCreditBody(body)).to.throw(/Property 'address' must be a string/i); + } + + // address wrong type + { + const body = { address: true, ticker: "CASH" }; + expect(() => RequestParser.parseCreditBody(body)).to.throw(/Property 'address' must be a string/i); + } + + // address empty + { + const body = { address: "", ticker: "CASH" }; + expect(() => RequestParser.parseCreditBody(body)).to.throw(/Property 'address' must not be empty/i); + } + + // ticker unset + { + const body = { address: "abc" }; + expect(() => RequestParser.parseCreditBody(body)).to.throw(/Property 'ticker' must be a string/i); + } + + // ticker wrong type + { + const body = { address: "abc", ticker: true }; + expect(() => RequestParser.parseCreditBody(body)).to.throw(/Property 'ticker' must be a string/i); + } + + // ticker empty + { + const body = { address: "abc", ticker: "" }; + expect(() => RequestParser.parseCreditBody(body)).to.throw(/Property 'ticker' must not be empty/i); + } + }); +}); diff --git a/packages/faucet/src/actions/start/requestparser.ts b/packages/faucet/src/actions/start/requestparser.ts new file mode 100644 index 00000000..2c9cfb4a --- /dev/null +++ b/packages/faucet/src/actions/start/requestparser.ts @@ -0,0 +1,35 @@ +import { Address, TokenTicker } from "@iov/bcp"; + +import { HttpError } from "./httperror"; + +export interface CreditRequestBodyData { + readonly ticker: TokenTicker; + readonly address: Address; +} + +export class RequestParser { + public static parseCreditBody(body: any): CreditRequestBodyData { + const { address, ticker } = body; + + if (typeof address !== "string") { + throw new HttpError(400, "Property 'address' must be a string."); + } + + if (address.length === 0) { + throw new HttpError(400, "Property 'address' must not be empty."); + } + + if (typeof ticker !== "string") { + throw new HttpError(400, "Property 'ticker' must be a string"); + } + + if (ticker.length === 0) { + throw new HttpError(400, "Property 'ticker' must not be empty."); + } + + return { + address: address as Address, + ticker: ticker as TokenTicker, + }; + } +} diff --git a/packages/faucet/src/actions/start/start.ts b/packages/faucet/src/actions/start/start.ts new file mode 100644 index 00000000..1cac66f6 --- /dev/null +++ b/packages/faucet/src/actions/start/start.ts @@ -0,0 +1,157 @@ +/* eslint-disable require-atomic-updates */ +import { UserProfile } from "@iov/keycontrol"; +import { MultiChainSigner } from "@iov/multichain"; +import cors = require("@koa/cors"); +import Koa from "koa"; +import bodyParser from "koa-bodyparser"; + +import { creditAmount, gasLimit, gasPrice, setFractionalDigits } from "../../cashflow"; +import { + codecDefaultFractionalDigits, + codecFromString, + codecImplementation, + createChainConnector, +} from "../../codec"; +import * as constants from "../../constants"; +import { logAccountsState, logSendJob } from "../../debugging"; +import { + accountsOfFirstChain, + availableTokensFromHolder, + identitiesOfFirstWallet, + refillFirstChain, + sendOnFirstChain, + tokenTickersOfFirstChain, +} from "../../multichainhelpers"; +import { setSecretAndCreateIdentities } from "../../profile"; +import { SendJob } from "../../types"; +import { HttpError } from "./httperror"; +import { RequestParser } from "./requestparser"; + +let count = 0; + +/** returns an integer >= 0 that increments and is unique in module scope */ +function getCount(): number { + return count++; +} + +export async function start(args: ReadonlyArray): Promise { + if (args.length < 2) { + throw Error(`Not enough arguments for action 'start'. See 'iov-faucet help' or README for arguments.`); + } + const codec = codecFromString(args[0]); + const blockchainBaseUrl: string = args[1]; + + const port = constants.port; + + const profile = new UserProfile(); + if (!constants.mnemonic) { + throw new Error("The FAUCET_MNEMONIC environment variable is not set"); + } + const signer = new MultiChainSigner(profile); + console.info(`Connecting to blockchain ${blockchainBaseUrl} ...`); + const connection = (await signer.addChain(createChainConnector(codec, blockchainBaseUrl))).connection; + + const connectedChainId = connection.chainId(); + console.info(`Connected to network: ${connectedChainId}`); + + setFractionalDigits(codecDefaultFractionalDigits(codec)); + await setSecretAndCreateIdentities(profile, constants.mnemonic, connectedChainId, codec); + + const chainTokens = await tokenTickersOfFirstChain(signer); + console.info("Chain tokens:", chainTokens); + + const accounts = await accountsOfFirstChain(profile, signer); + logAccountsState(accounts); + + let availableTokens = availableTokensFromHolder(accounts[0]); + console.info("Available tokens:", availableTokens); + setInterval(async () => { + const updatedAccounts = await accountsOfFirstChain(profile, signer); + availableTokens = availableTokensFromHolder(updatedAccounts[0]); + console.info("Available tokens:", availableTokens); + }, 60_000); + + const distibutorIdentities = identitiesOfFirstWallet(profile).slice(1); + + await refillFirstChain(profile, signer, codec); + setInterval(async () => refillFirstChain(profile, signer, codec), 60_000); // ever 60 seconds + + console.info("Creating webserver ..."); + const api = new Koa(); + api.use(cors()); + api.use(bodyParser()); + + api.use(async context => { + switch (context.path) { + case "/": + case "/healthz": + context.response.body = + "Welcome to the faucet!\n" + + "\n" + + "Check the full status via the /status endpoint.\n" + + "You can get tokens from here by POSTing to /credit.\n" + + "See https://github.com/iov-one/iov-faucet for all further information.\n"; + break; + case "/status": { + const updatedAccounts = await accountsOfFirstChain(profile, signer); + context.response.body = { + status: "ok", + nodeUrl: blockchainBaseUrl, + chainId: connectedChainId, + chainTokens: chainTokens, + availableTokens: availableTokens, + holder: updatedAccounts[0], + distributors: updatedAccounts.slice(1), + }; + break; + } + case "/credit": { + if (context.request.method !== "POST") { + throw new HttpError(405, "This endpoint requires a POST request"); + } + + if (context.request.type !== "application/json") { + throw new HttpError(415, "Content-type application/json expected"); + } + + // context.request.body is set by the bodyParser() plugin + const requestBody = (context.request as any).body; + const { address, ticker } = RequestParser.parseCreditBody(requestBody); + + if (!codecImplementation(codec).isValidAddress(address)) { + throw new HttpError(400, "Address is not in the expected format for this chain."); + } + + if (availableTokens.indexOf(ticker) === -1) { + const tokens = JSON.stringify(availableTokens); + throw new HttpError(422, `Token is not available. Available tokens are: ${tokens}`); + } + + const sender = distibutorIdentities[getCount() % distibutorIdentities.length]; + + try { + const job: SendJob = { + sender: sender, + recipient: address, + amount: creditAmount(ticker), + tokenTicker: ticker, + gasPrice: gasPrice(codec), + gasLimit: gasLimit(codec), + }; + logSendJob(signer, job); + await sendOnFirstChain(profile, signer, job); + } catch (e) { + console.error(e); + throw new HttpError(500, "Sending tokens failed"); + } + + context.response.body = "ok"; + break; + } + default: + // koa sends 404 by default + } + }); + console.info(`Starting webserver on port ${port} ...`); + api.listen(port); +} diff --git a/packages/faucet/src/actions/version.ts b/packages/faucet/src/actions/version.ts new file mode 100644 index 00000000..2863d786 --- /dev/null +++ b/packages/faucet/src/actions/version.ts @@ -0,0 +1,15 @@ +import fs from "fs"; + +export async function version(): Promise { + return new Promise((resolve, reject) => { + fs.readFile(__dirname + "/../../package.json", { encoding: "utf8" }, (error, data) => { + if (error) { + reject(error); + } else { + const packagejson = JSON.parse(data); + process.stdout.write(`${packagejson.version}\n`); + resolve(); + } + }); + }); +} diff --git a/packages/faucet/src/cashflow.spec.ts b/packages/faucet/src/cashflow.spec.ts new file mode 100644 index 00000000..7fed499e --- /dev/null +++ b/packages/faucet/src/cashflow.spec.ts @@ -0,0 +1,163 @@ +import { TokenTicker } from "@iov/bcp"; +import { expect } from "chai"; + +import { + creditAmount, + gasLimit, + gasPrice, + refillAmount, + refillThreshold, + setFractionalDigits, +} from "./cashflow"; +import { Codec } from "./codec"; + +describe("Cashflow", () => { + before(() => { + setFractionalDigits(3); + }); + + describe("creditAmount", () => { + it("returns '10' + '000' by default", () => { + expect(creditAmount("TOKENZ" as TokenTicker)).to.eql({ + quantity: "10000", + fractionalDigits: 3, + tokenTicker: "TOKENZ", + }); + expect(creditAmount("TRASH" as TokenTicker)).to.eql({ + quantity: "10000", + fractionalDigits: 3, + tokenTicker: "TRASH", + }); + }); + + it("returns value from env variable + '000' when set", () => { + process.env.FAUCET_CREDIT_AMOUNT_WTF = "22"; + expect(creditAmount("WTF" as TokenTicker)).to.eql({ + quantity: "22000", + fractionalDigits: 3, + tokenTicker: "WTF", + }); + }); + + it("returns default from env variable + '000' when set to empty", () => { + process.env.FAUCET_CREDIT_AMOUNT_WTF = ""; + expect(creditAmount("WTF" as TokenTicker)).to.eql({ + quantity: "10000", + fractionalDigits: 3, + tokenTicker: "WTF", + }); + }); + }); + + describe("refillAmount", () => { + beforeEach(() => { + process.env.FAUCET_REFILL_FACTOR = ""; + }); + it("returns 20*10 + '000' by default", () => { + expect(refillAmount("TOKENZ" as TokenTicker)).to.eql({ + quantity: "200000", + fractionalDigits: 3, + tokenTicker: "TOKENZ", + }); + }); + + it("returns 20*22 + '000' when credit amount is 22", () => { + process.env.FAUCET_CREDIT_AMOUNT_WTF = "22"; + expect(refillAmount("WTF" as TokenTicker)).to.eql({ + quantity: "440000", + fractionalDigits: 3, + tokenTicker: "WTF", + }); + }); + + it("returns 30*10 + '000' when refill factor is 30", () => { + process.env.FAUCET_REFILL_FACTOR = "30"; + expect(refillAmount("TOKENZ" as TokenTicker)).to.eql({ + quantity: "300000", + fractionalDigits: 3, + tokenTicker: "TOKENZ", + }); + }); + + it("returns 30*22 + '000' when refill factor is 30 and credit amount is 22", () => { + process.env.FAUCET_REFILL_FACTOR = "30"; + process.env.FAUCET_CREDIT_AMOUNT_WTF = "22"; + expect(refillAmount("WTF" as TokenTicker)).to.eql({ + quantity: "660000", + fractionalDigits: 3, + tokenTicker: "WTF", + }); + }); + }); + + describe("refillThreshold", () => { + beforeEach(() => { + process.env.FAUCET_REFILL_THRESHOLD = ""; + }); + it("returns 8*10 + '000' by default", () => { + expect(refillThreshold("TOKENZ" as TokenTicker)).to.eql({ + quantity: "80000", + fractionalDigits: 3, + tokenTicker: "TOKENZ", + }); + }); + + it("returns 8*22 + '000' when credit amount is 22", () => { + process.env.FAUCET_CREDIT_AMOUNT_WTF = "22"; + expect(refillThreshold("WTF" as TokenTicker)).to.eql({ + quantity: "176000", + fractionalDigits: 3, + tokenTicker: "WTF", + }); + }); + + it("returns 5*10 + '000' when refill threshold is 5", () => { + process.env.FAUCET_REFILL_THRESHOLD = "5"; + expect(refillThreshold("TOKENZ" as TokenTicker)).to.eql({ + quantity: "50000", + fractionalDigits: 3, + tokenTicker: "TOKENZ", + }); + }); + + it("returns 5*22 + '000' when refill threshold is 5 and credit amount is 22", () => { + process.env.FAUCET_REFILL_THRESHOLD = "5"; + process.env.FAUCET_CREDIT_AMOUNT_WTF = "22"; + expect(refillThreshold("WTF" as TokenTicker)).to.eql({ + quantity: "110000", + fractionalDigits: 3, + tokenTicker: "WTF", + }); + }); + }); + + describe("gasPrice", () => { + it("returns undefined for non-Ethereum codecs", () => { + expect(gasPrice(Codec.Lisk)).to.be.undefined; + expect(gasPrice(Codec.Bns)).to.be.undefined; + }); + + it("returns amount for Ethereum codec", () => { + expect(gasPrice(Codec.Ethereum)).to.be.eql({ + quantity: "20000000000", + fractionalDigits: 18, + tokenTicker: "ETH", + }); + }); + }); + + describe("gasLimit", () => { + it("returns undefined for non-Ethereum codecs", () => { + expect(gasLimit(Codec.Lisk)).to.be.undefined; + expect(gasLimit(Codec.Bns)).to.be.undefined; + }); + + it("returns amount for Ethereum codec", () => { + expect(gasLimit(Codec.Ethereum)).to.be.eql({ + quantity: "2100000", + fractionalDigits: 18, + tokenTicker: "ETH", + }); + }); + }); +}); diff --git a/packages/faucet/src/cashflow.ts b/packages/faucet/src/cashflow.ts new file mode 100644 index 00000000..079a5c37 --- /dev/null +++ b/packages/faucet/src/cashflow.ts @@ -0,0 +1,95 @@ +import BN = require("bn.js"); + +import { Account, Amount, TokenTicker } from "@iov/bcp"; +import { Int53 } from "@iov/encoding"; + +import { Codec } from "./codec"; +import * as constants from "./constants"; + +/** Send `factor` times credit amount on refilling */ +const defaultRefillFactor = 20; + +/** refill when balance gets below `factor` times credit amount */ +const defaultRefillThresholdFactor = 8; + +// Load this from connection? +let globalFractionalDigits: number | undefined; + +export function setFractionalDigits(input: number): void { + globalFractionalDigits = input; +} + +export function getFractionalDigits(): number { + if (globalFractionalDigits === undefined) { + throw new Error("Fractional digits not set"); + } + return globalFractionalDigits; +} + +/** The amount of tokens that will be sent to the user */ +export function creditAmount(token: TokenTicker, factor = 1): Amount { + const amountFromEnv = process.env[`FAUCET_CREDIT_AMOUNT_${token}`]; + const wholeNumber = amountFromEnv ? Int53.fromString(amountFromEnv).toNumber() : 10; + const total = wholeNumber * factor; + const fractionalDigits = getFractionalDigits(); + // replace BN with BigInt with TypeScript 3.2 and node 11 + const quantity = new BN(total).imul(new BN(10).pow(new BN(fractionalDigits))).toString(); + return { + quantity: quantity, + fractionalDigits: fractionalDigits, + tokenTicker: token, + }; +} + +export function refillAmount(token: TokenTicker): Amount { + const factorFromEnv = Number.parseInt(process.env.FAUCET_REFILL_FACTOR || "0", 10) || undefined; + const factor = factorFromEnv || defaultRefillFactor; + return creditAmount(token, factor); +} + +export function refillThreshold(token: TokenTicker): Amount { + const factorFromEnv = Number.parseInt(process.env.FAUCET_REFILL_THRESHOLD || "0", 10) || undefined; + const factor = factorFromEnv || defaultRefillThresholdFactor; + return creditAmount(token, factor); +} + +/** true iff the distributor account needs a refill */ +export function needsRefill(account: Account, token: TokenTicker): boolean { + const coin = account.balance.find(balance => balance.tokenTicker === token); + + const tokenBalance = coin ? coin.quantity : "0"; + const refillQty = new BN(refillThreshold(token).quantity); + return new BN(tokenBalance).lt(refillQty); +} + +export function gasPrice(codec: Codec): Amount | undefined { + switch (codec) { + case Codec.Bns: + case Codec.Lisk: + return undefined; + case Codec.Ethereum: + return { + quantity: constants.ethereum.gasPrice, + fractionalDigits: 18, + tokenTicker: "ETH" as TokenTicker, + }; + default: + throw new Error("No codec imlementation for this codec found"); + } +} + +export function gasLimit(codec: Codec): Amount | undefined { + switch (codec) { + case Codec.Bns: + case Codec.Lisk: + return undefined; + case Codec.Ethereum: + return { + quantity: constants.ethereum.gasLimit, + fractionalDigits: 18, + tokenTicker: "ETH" as TokenTicker, + }; + default: + throw new Error("Codec not supported"); + } +} diff --git a/packages/faucet/src/codec.spec.ts b/packages/faucet/src/codec.spec.ts new file mode 100644 index 00000000..bf5ff998 --- /dev/null +++ b/packages/faucet/src/codec.spec.ts @@ -0,0 +1,16 @@ +import { expect } from "chai"; + +import { Codec, codecFromString } from "./codec"; + +describe("Codec", () => { + it("can convert string to codec", () => { + expect(codecFromString("bns")).to.equal(Codec.Bns); + expect(codecFromString("lisk")).to.equal(Codec.Lisk); + expect(codecFromString("ethereum")).to.equal(Codec.Ethereum); + + expect(() => codecFromString("")).to.throw(/not supported/i); + expect(() => codecFromString("abc")).to.throw(/not supported/i); + expect(() => codecFromString("LISK")).to.throw(/not supported/i); + expect(() => codecFromString("ETHEREUM")).to.throw(/not supported/i); + }); +}); diff --git a/packages/faucet/src/codec.ts b/packages/faucet/src/codec.ts new file mode 100644 index 00000000..1080a85e --- /dev/null +++ b/packages/faucet/src/codec.ts @@ -0,0 +1,80 @@ +import { ChainConnector, TxCodec } from "@iov/bcp"; +import { bnsCodec, createBnsConnector } from "@iov/bns"; +import { Slip10RawIndex } from "@iov/crypto"; +import { createEthereumConnector, ethereumCodec } from "@iov/ethereum"; +import { HdPaths } from "@iov/keycontrol"; +import { createLiskConnector, liskCodec } from "@iov/lisk"; + +export const enum Codec { + Bns, + Lisk, + Ethereum, +} + +export function codecFromString(input: string): Codec { + switch (input) { + case "bns": + return Codec.Bns; + case "lisk": + return Codec.Lisk; + case "ethereum": + return Codec.Ethereum; + default: + throw new Error(`Codec '${input}' not supported`); + } +} + +export function codecImplementation(codec: Codec): TxCodec { + switch (codec) { + case Codec.Bns: + return bnsCodec; + case Codec.Lisk: + return liskCodec; + case Codec.Ethereum: + return ethereumCodec; + default: + throw new Error("No codec implementation for this codec found"); + } +} + +export function createPathBuilderForCodec(codec: Codec): (derivation: number) => readonly Slip10RawIndex[] { + const pathBuilder = (accountIndex: number): readonly Slip10RawIndex[] => { + switch (codec) { + case Codec.Bns: + return HdPaths.iov(accountIndex); + case Codec.Lisk: + return HdPaths.bip44Like(134, accountIndex); + case Codec.Ethereum: + return HdPaths.ethereum(accountIndex); + default: + throw new Error("No path builder for this codec found"); + } + }; + return pathBuilder; +} + +export function createChainConnector(codec: Codec, url: string): ChainConnector { + switch (codec) { + case Codec.Bns: + return createBnsConnector(url); + case Codec.Lisk: + return createLiskConnector(url); + case Codec.Ethereum: + return createEthereumConnector(url, {}); + default: + throw new Error("No connector for this codec found"); + } +} + +export function codecDefaultFractionalDigits(codec: Codec): number { + switch (codec) { + case Codec.Bns: + return 9; // fixed for all weave tokens + case Codec.Lisk: + return 8; + case Codec.Ethereum: + return 18; + default: + throw new Error("Unknown codec"); + } +} diff --git a/packages/faucet/src/constants.ts b/packages/faucet/src/constants.ts new file mode 100644 index 00000000..9ff6e410 --- /dev/null +++ b/packages/faucet/src/constants.ts @@ -0,0 +1,7 @@ +export const concurrency: number = Number.parseInt(process.env.FAUCET_CONCURRENCY || "", 10) || 5; +export const port: number = Number.parseInt(process.env.FAUCET_PORT || "", 10) || 8000; +export const mnemonic: string | undefined = process.env.FAUCET_MNEMONIC; +export const ethereum = { + gasPrice: "20000000000", + gasLimit: "2100000", +}; diff --git a/packages/faucet/src/crypto.ts b/packages/faucet/src/crypto.ts new file mode 100644 index 00000000..59424ef9 --- /dev/null +++ b/packages/faucet/src/crypto.ts @@ -0,0 +1,15 @@ +import { Ed25519HdWallet, Secp256k1HdWallet, Wallet } from "@iov/keycontrol"; + +import { Codec } from "./codec"; + +export function createWalletForCodec(input: Codec, mnemonic: string): Wallet { + switch (input) { + case Codec.Bns: + case Codec.Lisk: + return Ed25519HdWallet.fromMnemonic(mnemonic); + case Codec.Ethereum: + return Secp256k1HdWallet.fromMnemonic(mnemonic); + default: + throw new Error(`Codec '${input}' not supported`); + } +} diff --git a/packages/faucet/src/debugging.ts b/packages/faucet/src/debugging.ts new file mode 100644 index 00000000..5b5adc09 --- /dev/null +++ b/packages/faucet/src/debugging.ts @@ -0,0 +1,58 @@ +import { Account, Amount } from "@iov/bcp"; +import { MultiChainSigner } from "@iov/multichain"; + +import { SendJob } from "./types"; + +export function amountToNumber(amount: Amount): number { + const { quantity, fractionalDigits } = amount; + if (!quantity.match(/^[0-9]+$/)) { + throw new Error(`quantity must be a number, got ${quantity}`); + } + if (fractionalDigits < 0) { + throw new Error(`invalid fractional digits: ${fractionalDigits}`); + } + // let's remove those leading zeros... + const temp = quantity.replace(/^0+/, ""); + // unless we need them to reach a decimal point + const pad = fractionalDigits - temp.length; + const trimmed = pad > 0 ? "0".repeat(pad) + temp : temp; + + const cut = trimmed.length - fractionalDigits; + const whole = cut === 0 ? "0" : trimmed.slice(0, cut); + const decimal = fractionalDigits === 0 ? "" : `.${trimmed.slice(cut)}`; + const value = `${whole}${decimal}`; + + return Number(value); +} + +/** A string representation of a coin in a human-readable format that can change at any time */ +export function debugCoin(coin: Amount): string { + return `${amountToNumber(coin)} ${coin.tokenTicker}`; +} + +/** A string representation of a balance in a human-readable format that can change at any time */ +export function debugBalance(data: ReadonlyArray): string { + return `[${data.map(debugCoin).join(", ")}]`; +} + +/** A string representation of an account in a human-readable format that can change at any time */ +export function debugAccount(account: Account): string { + return `${account.address}: ${debugBalance(account.balance)}`; +} + +export function logAccountsState(accounts: ReadonlyArray): void { + if (accounts.length < 2) { + throw new Error("List of accounts must contain at least one token holder and one distributor"); + } + const holder = accounts[0]; + const distributors = accounts.slice(1); + console.info("Holder:\n" + ` ${debugAccount(holder)}`); + console.info("Distributors:\n" + distributors.map(r => ` ${debugAccount(r)}`).join("\n")); +} + +export function logSendJob(signer: MultiChainSigner, job: SendJob): void { + const from = signer.identityToAddress(job.sender); + const to = job.recipient; + const amount = debugCoin(job.amount); + console.info(`Sending ${amount} from ${from} to ${to} ...`); +} diff --git a/packages/faucet/src/faucet.ts b/packages/faucet/src/faucet.ts new file mode 100644 index 00000000..3587566a --- /dev/null +++ b/packages/faucet/src/faucet.ts @@ -0,0 +1,38 @@ +import { generate, help, start, version } from "./actions"; + +export function main(args: ReadonlyArray): void { + if (args.length < 1) { + help(); + process.exit(1); + return; + } + + const action = args[0]; + const restArgs = args.slice(1); + + switch (action) { + case "generate": + generate(restArgs).catch(error => { + console.error(error); + process.exit(1); + }); + break; + case "help": + help(); + break; + case "version": + version().catch(error => { + console.error(error); + process.exit(1); + }); + break; + case "start": + start(restArgs).catch(error => { + console.error(error); + process.exit(1); + }); + break; + default: + throw new Error("Unexpected action argument"); + } +} diff --git a/packages/faucet/src/hdpaths.spec.ts b/packages/faucet/src/hdpaths.spec.ts new file mode 100644 index 00000000..ff92f9f1 --- /dev/null +++ b/packages/faucet/src/hdpaths.spec.ts @@ -0,0 +1,45 @@ +import { Slip10RawIndex } from "@iov/crypto"; +import { expect } from "chai"; + +import { debugPath } from "./hdpaths"; + +describe("hdpaths", () => { + describe("debugPath", () => { + it("works for no component", () => { + // See https://github.com/bitcoin/bips/blob/master/bip-0032/derivation.png from BIP32 + expect(debugPath([])).to.eql("m"); + }); + + it("works for normal components", () => { + const one = Slip10RawIndex.normal(1); + expect(debugPath([one])).to.eql("m/1"); + expect(debugPath([one, one])).to.eql("m/1/1"); + expect(debugPath([one, one, one])).to.eql("m/1/1/1"); + + const min = Slip10RawIndex.normal(0); + expect(debugPath([min])).to.eql("m/0"); + + const max = Slip10RawIndex.normal(2 ** 31 - 1); + expect(debugPath([max])).to.eql("m/2147483647"); + }); + + it("works for hardened components", () => { + const one = Slip10RawIndex.hardened(1); + expect(debugPath([one])).to.eql("m/1'"); + expect(debugPath([one, one])).to.eql("m/1'/1'"); + expect(debugPath([one, one, one])).to.eql("m/1'/1'/1'"); + + const min = Slip10RawIndex.hardened(0); + expect(debugPath([min])).to.eql("m/0'"); + + const max = Slip10RawIndex.hardened(2 ** 31 - 1); + expect(debugPath([max])).to.eql("m/2147483647'"); + }); + + it("works for mixed components", () => { + const one = Slip10RawIndex.normal(1); + const two = Slip10RawIndex.hardened(2); + expect(debugPath([one, two, two, one])).to.eql("m/1/2'/2'/1"); + }); + }); +}); diff --git a/packages/faucet/src/hdpaths.ts b/packages/faucet/src/hdpaths.ts new file mode 100644 index 00000000..f61e35ba --- /dev/null +++ b/packages/faucet/src/hdpaths.ts @@ -0,0 +1,10 @@ +import { Slip10RawIndex } from "@iov/crypto"; + +export function debugPath(path: readonly Slip10RawIndex[]): string { + return path.reduce((current, component): string => { + const componentString = component.isHardened() + ? `${component.toNumber() - 2 ** 31}'` + : component.toString(); + return current + "/" + componentString; + }, "m"); +} diff --git a/packages/faucet/src/multichainhelpers.spec.ts b/packages/faucet/src/multichainhelpers.spec.ts new file mode 100644 index 00000000..0531c26e --- /dev/null +++ b/packages/faucet/src/multichainhelpers.spec.ts @@ -0,0 +1,57 @@ +import { Address, Algorithm, PubkeyBundle, PubkeyBytes, TokenTicker } from "@iov/bcp"; +import { expect } from "chai"; + +import { availableTokensFromHolder } from "./multichainhelpers"; + +describe("multichainhelpers", () => { + describe("availableTokensFromHolder", () => { + const defaultPubkey: PubkeyBundle = { + algo: Algorithm.Ed25519, + data: new Uint8Array([0, 1, 2, 3]) as PubkeyBytes, + }; + + it("works for an empty account", () => { + const tickers = availableTokensFromHolder({ + address: "aabbccdd" as Address, + pubkey: defaultPubkey, + balance: [], + }); + expect(tickers).to.be.empty; + }); + + it("works for one token", () => { + const tickers = availableTokensFromHolder({ + address: "aabbccdd" as Address, + pubkey: defaultPubkey, + balance: [ + { + quantity: "1", + fractionalDigits: 9, + tokenTicker: "CASH" as TokenTicker, + }, + ], + }); + expect(tickers).to.eql(["CASH"]); + }); + + it("works for two tokens", () => { + const tickers = availableTokensFromHolder({ + address: "aabbccdd" as Address, + pubkey: defaultPubkey, + balance: [ + { + quantity: "1", + fractionalDigits: 9, + tokenTicker: "CASH" as TokenTicker, + }, + { + quantity: "1", + fractionalDigits: 9, + tokenTicker: "TRASH" as TokenTicker, + }, + ], + }); + expect(tickers).to.eql(["CASH", "TRASH"]); + }); + }); +}); diff --git a/packages/faucet/src/multichainhelpers.ts b/packages/faucet/src/multichainhelpers.ts new file mode 100644 index 00000000..6b98d0ab --- /dev/null +++ b/packages/faucet/src/multichainhelpers.ts @@ -0,0 +1,145 @@ +import { + Account, + Identity, + isBlockInfoFailed, + isBlockInfoPending, + SendTransaction, + TokenTicker, + WithCreator, +} from "@iov/bcp"; +import { UserProfile } from "@iov/keycontrol"; +import { MultiChainSigner } from "@iov/multichain"; + +import { gasLimit, gasPrice, needsRefill, refillAmount } from "./cashflow"; +import { Codec } from "./codec"; +import { debugAccount, logAccountsState, logSendJob } from "./debugging"; +import { SendJob } from "./types"; + +async function sleep(ms: number): Promise { + return new Promise(resolve => setTimeout(resolve, ms)); +} + +export function identitiesOfFirstWallet(profile: UserProfile): ReadonlyArray { + const wallet = profile.wallets.value[0]; + return profile.getIdentities(wallet.id); +} + +export async function accountsOfFirstChain( + profile: UserProfile, + signer: MultiChainSigner, +): Promise> { + const addresses = identitiesOfFirstWallet(profile).map(identity => signer.identityToAddress(identity)); + const chainId = signer.chainIds()[0]; + + const out: Account[] = []; + for (const address of addresses) { + const response = await signer.connection(chainId).getAccount({ address: address }); + if (response) { + out.push({ + address: response.address, + balance: response.balance, + }); + } else { + out.push({ + address: address, + balance: [], + }); + } + } + + return out; +} + +export async function tokenTickersOfFirstChain( + signer: MultiChainSigner, +): Promise> { + const chainId = signer.chainIds()[0]; + return (await signer.connection(chainId).getAllTokens()).map(token => token.tokenTicker); +} + +/** + * Creates and posts a send transaction. Then waits until the transaction is in a block. + */ +export async function sendOnFirstChain( + profile: UserProfile, + signer: MultiChainSigner, + job: SendJob, +): Promise { + const chainId = signer.chainIds()[0]; + const connection = signer.connection(chainId); + + const sendWithFee = await connection.withDefaultFee({ + kind: "bcp/send", + creator: { + chainId: chainId, + pubkey: job.sender.pubkey, + }, + sender: signer.identityToAddress(job.sender), + recipient: job.recipient, + memo: "We ❤️ developers – iov.one", + amount: job.amount, + }); + + const post = await signer.signAndPost(sendWithFee); + const blockInfo = await post.blockInfo.waitFor(info => !isBlockInfoPending(info)); + if (isBlockInfoFailed(blockInfo)) { + throw new Error(`Sending tokens failed. Code: ${blockInfo.code}, message: ${blockInfo.message}`); + } +} + +export function availableTokensFromHolder(holderAccount: Account): ReadonlyArray { + return holderAccount.balance.map(coin => coin.tokenTicker); +} + +export async function refillFirstChain( + profile: UserProfile, + signer: MultiChainSigner, + codec: Codec, +): Promise { + const chainId = signer.chainIds()[0]; + + console.info(`Connected to network: ${chainId}`); + console.info(`Tokens on network: ${(await tokenTickersOfFirstChain(signer)).join(", ")}`); + + const holderIdentity = identitiesOfFirstWallet(profile)[0]; + + const accounts = await accountsOfFirstChain(profile, signer); + logAccountsState(accounts); + const holderAccount = accounts[0]; + const distributorAccounts = accounts.slice(1); + + const availableTokens = availableTokensFromHolder(holderAccount); + console.info("Available tokens:", availableTokens); + + const jobs: SendJob[] = []; + + for (const token of availableTokens) { + const refillDistibutors = distributorAccounts.filter(account => needsRefill(account, token)); + console.info(`Refilling ${token} of:`); + console.info( + refillDistibutors.length ? refillDistibutors.map(r => ` ${debugAccount(r)}`).join("\n") : " none", + ); + for (const refillDistibutor of refillDistibutors) { + jobs.push({ + sender: holderIdentity, + recipient: refillDistibutor.address, + tokenTicker: token, + amount: refillAmount(token), + gasPrice: gasPrice(codec), + gasLimit: gasLimit(codec), + }); + } + } + if (jobs.length > 0) { + for (const job of jobs) { + logSendJob(signer, job); + await sendOnFirstChain(profile, signer, job); + await sleep(50); + } + + console.info("Done refilling accounts."); + logAccountsState(await accountsOfFirstChain(profile, signer)); + } else { + console.info("Nothing to be done. Anyways, thanks for checking."); + } +} diff --git a/packages/faucet/src/profile.ts b/packages/faucet/src/profile.ts new file mode 100644 index 00000000..36c0352e --- /dev/null +++ b/packages/faucet/src/profile.ts @@ -0,0 +1,34 @@ +import { ChainId } from "@iov/bcp"; +import { UserProfile } from "@iov/keycontrol"; + +import { Codec, codecImplementation, createPathBuilderForCodec } from "./codec"; +import * as constants from "./constants"; +import { createWalletForCodec } from "./crypto"; +import { debugPath } from "./hdpaths"; + +export async function setSecretAndCreateIdentities( + profile: UserProfile, + mnemonic: string, + chainId: ChainId, + codecName: Codec, +): Promise { + if (profile.wallets.value.length !== 0) { + throw new Error("Profile already contains wallets"); + } + const wallet = profile.addWallet(createWalletForCodec(codecName, mnemonic)); + + const pathBuilder = createPathBuilderForCodec(codecName); + + // first account is the token holder + const numberOfIdentities = 1 + constants.concurrency; + for (let i = 0; i < numberOfIdentities; i++) { + // create + const path = pathBuilder(i); + const identity = await profile.createIdentity(wallet.id, chainId, path); + + // log + const role = i === 0 ? "token holder " : `distributor ${i}`; + const address = codecImplementation(codecName).identityToAddress(identity); + console.info(`Created ${role} (${debugPath(path)}): ${address}`); + } +} diff --git a/packages/faucet/src/types.ts b/packages/faucet/src/types.ts new file mode 100644 index 00000000..a4a0cc34 --- /dev/null +++ b/packages/faucet/src/types.ts @@ -0,0 +1,10 @@ +import { Address, Amount, Identity, TokenTicker } from "@iov/bcp"; + +export interface SendJob { + readonly sender: Identity; + readonly recipient: Address; + readonly tokenTicker: TokenTicker; + readonly amount: Amount; + readonly gasPrice?: Amount; + readonly gasLimit?: Amount; +} diff --git a/packages/faucet/tsconfig.json b/packages/faucet/tsconfig.json new file mode 100644 index 00000000..167e8c02 --- /dev/null +++ b/packages/faucet/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "baseUrl": ".", + "outDir": "build", + "declarationDir": "build/types", + "rootDir": "src" + }, + "include": [ + "src/**/*" + ] +} diff --git a/packages/faucet/tslint.json b/packages/faucet/tslint.json new file mode 100644 index 00000000..0946f209 --- /dev/null +++ b/packages/faucet/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "../../tslint.json" +} diff --git a/packages/faucet/typedoc.js b/packages/faucet/typedoc.js new file mode 100644 index 00000000..e2387c7d --- /dev/null +++ b/packages/faucet/typedoc.js @@ -0,0 +1,14 @@ +const packageJson = require("./package.json"); + +module.exports = { + src: ["./src"], + out: "docs", + exclude: "**/*.spec.ts", + target: "es6", + name: `${packageJson.name} Documentation`, + readme: "README.md", + mode: "file", + excludeExternals: true, + excludeNotExported: true, + excludePrivate: true, +}; diff --git a/yarn.lock b/yarn.lock index fc1ff754..52522ace 100644 --- a/yarn.lock +++ b/yarn.lock @@ -103,6 +103,25 @@ type-tagger "^1.0.0" xstream "^11.10.0" +"@iov/bns@^2.0.0-alpha.7": + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@iov/bns/-/bns-2.0.0-alpha.7.tgz#83a9ab0fa97631c7d42f32038b8fb1b86d318405" + integrity sha512-xX/o65HC78SfxJLLZE6pSUcfszwDezXovYBuhoelR0vIHqGbZjetksWwXrBz7zgkyBXQnXcfUDFgyaefFfmJjw== + dependencies: + "@iov/bcp" "^2.0.0-alpha.7" + "@iov/crypto" "^2.0.0-alpha.7" + "@iov/encoding" "^2.0.0-alpha.7" + "@iov/stream" "^2.0.0-alpha.7" + "@iov/tendermint-rpc" "^2.0.0-alpha.7" + "@types/long" "^4.0.0" + "@types/node" "^10.12.18" + bn.js "^4.11.8" + fast-deep-equal "^3.1.1" + long "^4.0.0" + protobufjs "^6.8.6" + type-tagger "^1.0.0" + xstream "^11.10.0" + "@iov/crypto@^2.0.0-alpha.7": version "2.0.0-alpha.7" resolved "https://registry.yarnpkg.com/@iov/crypto/-/crypto-2.0.0-alpha.7.tgz#5cb24dbc3cdd344bf782039f1fe6d55975d171f6" @@ -130,6 +149,37 @@ bn.js "^4.11.8" readonly-date "^1.0.0" +"@iov/ethereum@^2.0.0-alpha.7": + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@iov/ethereum/-/ethereum-2.0.0-alpha.7.tgz#f1a72947e5ce62a7afc56f0320866f08b2bf01b9" + integrity sha512-q+AJsIuwbBbrEMpztgGQIsApFJQ/n7t9Uq/pi3OGqUdcXCG6JYJH+XjClv0yIVcMB8pxfNwQ9RvYy75Zpn0icw== + dependencies: + "@iov/bcp" "^2.0.0-alpha.7" + "@iov/crypto" "^2.0.0-alpha.7" + "@iov/encoding" "^2.0.0-alpha.7" + "@iov/jsonrpc" "^2.0.0-alpha.7" + "@iov/keycontrol" "^2.0.0-alpha.7" + "@iov/socket" "^2.0.0-alpha.7" + "@iov/stream" "^2.0.0-alpha.7" + "@iov/utils" "^2.0.0-alpha.7" + "@types/long" "^4.0.0" + axios "^0.19.0" + bn.js "^4.11.8" + fast-deep-equal "^3.1.1" + long "^4.0.0" + readonly-date "^1.0.0" + rlp "^2.2.3" + xstream "^11.10.0" + +"@iov/jsonrpc@^2.0.0-alpha.7": + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@iov/jsonrpc/-/jsonrpc-2.0.0-alpha.7.tgz#7bff8e1f21d52ff07482212ded8cc00e01dda964" + integrity sha512-eVCfNi3Zg4ZUEXOxhzRb3kcoBupBGQWmU4pYu7OYBi3uvuUz8KP6kcIdsy+51+y/nqrnk3H2Ur7MWCzwsu215w== + dependencies: + "@iov/encoding" "^2.0.0-alpha.7" + "@iov/stream" "^2.0.0-alpha.7" + xstream "^11.10.0" + "@iov/keycontrol@^2.0.0-alpha.7": version "2.0.0-alpha.7" resolved "https://registry.yarnpkg.com/@iov/keycontrol/-/keycontrol-2.0.0-alpha.7.tgz#d115a1b536664afb64b40a6db87aaf19f8d07afd" @@ -150,6 +200,45 @@ type-tagger "^1.0.0" xstream "^11.10.0" +"@iov/lisk@^2.0.0-alpha.7": + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@iov/lisk/-/lisk-2.0.0-alpha.7.tgz#5ff6c617ac00e6be736ada34ad68dce0efd64637" + integrity sha512-m5mr2NDU7pxuS8d6SBXCZ1WBtCSXtV+EWqMEIuPSCJwZxnwmWotowX+WhSYn+dGyuvgTd7DpfQ5C6pliAyhcyQ== + dependencies: + "@iov/bcp" "^2.0.0-alpha.7" + "@iov/crypto" "^2.0.0-alpha.7" + "@iov/encoding" "^2.0.0-alpha.7" + "@iov/keycontrol" "^2.0.0-alpha.7" + "@iov/stream" "^2.0.0-alpha.7" + "@types/long" "^4.0.0" + axios "^0.19.0" + fast-deep-equal "^3.1.1" + long "^4.0.0" + readonly-date "^1.0.0" + xstream "^11.10.0" + +"@iov/multichain@^2.0.0-alpha.7": + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@iov/multichain/-/multichain-2.0.0-alpha.7.tgz#29ec9f61ec2fa60c17d462c9be48feb7196c28ba" + integrity sha512-hhEyqalADrQa4JS99JqawM7jWLYGqb52Ipq/49Zz5eDG9/nj9QyLn5nayWLTbm60ZXzHvvGr5oJpZx8Xb2PzfA== + dependencies: + "@iov/bcp" "^2.0.0-alpha.7" + "@iov/encoding" "^2.0.0-alpha.7" + "@iov/jsonrpc" "^2.0.0-alpha.7" + "@iov/keycontrol" "^2.0.0-alpha.7" + "@types/long" "^4.0.0" + long "^4.0.0" + +"@iov/socket@^2.0.0-alpha.7": + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@iov/socket/-/socket-2.0.0-alpha.7.tgz#d88baf91617a91d87b5f5d51a11b2bc0800cf532" + integrity sha512-4c96cvwRJTEuG2vrUM36v3sFq5tkxZ3afn21zqUXIfaAo9VC3wFSpEUXjyx7/j1iwC7SOPOT2ExckiyMWBTa9A== + dependencies: + "@iov/stream" "^2.0.0-alpha.7" + isomorphic-ws "^4.0.1" + ws "^6.2.0" + xstream "^11.10.0" + "@iov/stream@^2.0.0-alpha.7": version "2.0.0-alpha.7" resolved "https://registry.yarnpkg.com/@iov/stream/-/stream-2.0.0-alpha.7.tgz#212c3f684f592ec04ac43e166183d946a49b895c" @@ -157,6 +246,32 @@ dependencies: xstream "^11.10.0" +"@iov/tendermint-rpc@^2.0.0-alpha.7": + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@iov/tendermint-rpc/-/tendermint-rpc-2.0.0-alpha.7.tgz#5c70bdcb0c2850be4012812116cbe1188bc9bdd6" + integrity sha512-UaMu7wCGiiT5baIDdeTwQ3gCWFd4J1fJDDico/RuAqxbGhtvZSUpzevv+r/xeysydviNLue1J1w2ZdqTS9mJRg== + dependencies: + "@iov/crypto" "^2.0.0-alpha.7" + "@iov/encoding" "^2.0.0-alpha.7" + "@iov/jsonrpc" "^2.0.0-alpha.7" + "@iov/socket" "^2.0.0-alpha.7" + axios "^0.19.0" + readonly-date "^1.0.0" + type-tagger "^1.0.0" + xstream "^11.10.0" + +"@iov/utils@^2.0.0-alpha.7": + version "2.0.0-alpha.7" + resolved "https://registry.yarnpkg.com/@iov/utils/-/utils-2.0.0-alpha.7.tgz#af9aebcb9e221e53cf62c5511f007c65d95f5c0c" + integrity sha512-myWATqmlCFZ/jSrsBQlyn+6D2ViAscZVAqBAw38kbIfv3TiKTjWb2RqhlNDnlVgt3uD0ZtQFyY9hkRMCwfIk+w== + +"@koa/cors@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@koa/cors/-/cors-3.0.0.tgz#df021b4df2dadf1e2b04d7c8ddf93ba2d42519cb" + integrity sha512-hDp+cXj6vTYSwHRJfiSpnf5dTMv3FmqNKh1or9BPJk4SHOviHnK9GoL9dT0ypt/E+hlkRkZ9edHylcosW3Ghrw== + dependencies: + vary "^1.1.2" + "@lerna/add@3.20.0": version "3.20.0" resolved "https://registry.yarnpkg.com/@lerna/add/-/add-3.20.0.tgz#bea7edf36fc93fb72ec34cb9ba854c48d4abf309" @@ -925,6 +1040,59 @@ dependencies: "@types/node" ">= 8" +"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= + +"@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + +"@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + +"@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= + +"@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + +"@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= + +"@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= + +"@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= + +"@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= + +"@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= + "@tendermint/amino-js@^0.7.0-alpha.1": version "0.7.0-alpha.1" resolved "https://registry.yarnpkg.com/@tendermint/amino-js/-/amino-js-0.7.0-alpha.1.tgz#5d9f689fb601a0c0a6bb245a16d0b9a197f616e5" @@ -950,6 +1118,50 @@ resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-5.0.1.tgz#3c7750d0186b954c7f2d2f6acc8c3c7ba0c3412e" integrity sha512-wYxU3kp5zItbxKmeRYCEplS2MW7DzyBnxPGj+GJVHZEUZiK/nn5Ei1sUFgURDh+X051+zsGe28iud3oHjrYWQQ== +"@types/accepts@*": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/accepts/-/accepts-1.3.5.tgz#c34bec115cfc746e04fe5a059df4ce7e7b391575" + integrity sha512-jOdnI/3qTpHABjM5cx1Hc0sKsPoYCp+DP/GJRGtDlPd7fiV9oXGGIcjW/ZOxLIvjGz8MA+uMZI9metHlgqbgwQ== + dependencies: + "@types/node" "*" + +"@types/bn.js@^4.11.6": + version "4.11.6" + resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" + integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== + dependencies: + "@types/node" "*" + +"@types/body-parser@*": + version "1.17.1" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.17.1.tgz#18fcf61768fb5c30ccc508c21d6fd2e8b3bf7897" + integrity sha512-RoX2EZjMiFMjZh9lmYrwgoP9RTpAjSHiJxdp4oidAQVO02T7HER3xj9UKue5534ULWeqVEkujhWcyvUce+d68w== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/chai@^4.2.7": + version "4.2.7" + resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.2.7.tgz#1c8c25cbf6e59ffa7d6b9652c78e547d9a41692d" + integrity sha512-luq8meHGYwvky0O7u0eQZdA7B4Wd9owUCqvbw2m3XCrCU8mplYOujMBbvyS547AxJkC+pGnd0Cm15eNxEUNU8g== + +"@types/connect@*": + version "3.4.33" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.33.tgz#31610c901eca573b8713c3330abc6e6b9f588546" + integrity sha512-2+FrkXY4zllzTNfJth7jOqEHC+enpLeGslEhpnTAkg21GkRrWV4SsAtqchtT4YS9/nODBU2/ZfsBY2X4J/dX7A== + dependencies: + "@types/node" "*" + +"@types/cookies@*": + version "0.7.4" + resolved "https://registry.yarnpkg.com/@types/cookies/-/cookies-0.7.4.tgz#26dedf791701abc0e36b5b79a5722f40e455f87b" + integrity sha512-oTGtMzZZAVuEjTwCjIh8T8FrC8n/uwy+PG0yTvQcdZ7etoel7C7/3MSd7qrukENTgQtotG7gvBlBojuVs7X5rw== + dependencies: + "@types/connect" "*" + "@types/express" "*" + "@types/keygrip" "*" + "@types/node" "*" + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -960,6 +1172,23 @@ resolved "https://registry.yarnpkg.com/@types/events/-/events-3.0.0.tgz#2862f3f58a9a7f7c3e78d79f130dd4d71c25c2a7" integrity sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g== +"@types/express-serve-static-core@*": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.2.tgz#f6f41fa35d42e79dbf6610eccbb2637e6008a0cf" + integrity sha512-El9yMpctM6tORDAiBwZVLMcxoTMcqqRO9dVyYcn7ycLWbvR8klrDn8CAOwRfZujZtWD7yS/mshTdz43jMOejbg== + dependencies: + "@types/node" "*" + "@types/range-parser" "*" + +"@types/express@*": + version "4.17.2" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.2.tgz#a0fb7a23d8855bac31bc01d5a58cadd9b2173e6c" + integrity sha512-5mHFNyavtLoJmnusB8OKJ5bshSzw+qkMIBAobLrIM48HJvunFva9mOa6aBwh64lBFyNwBbs0xiEFuj4eU/NjCA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "*" + "@types/serve-static" "*" + "@types/glob@^7.1.1": version "7.1.1" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575" @@ -969,6 +1198,11 @@ "@types/minimatch" "*" "@types/node" "*" +"@types/http-assert@*": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@types/http-assert/-/http-assert-1.5.1.tgz#d775e93630c2469c2f980fc27e3143240335db3b" + integrity sha512-PGAK759pxyfXE78NbKxyfRcWYA/KwW17X290cNev/qAsn9eQIxkH4shoNBafH37wewhDG/0p1cHPbK6+SzZjWQ== + "@types/jasmine@^3.3.7": version "3.5.1" resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.5.1.tgz#e417aa74738aa9e9285016abbfcae68d5be0f827" @@ -979,6 +1213,44 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== +"@types/keygrip@*": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/keygrip/-/keygrip-1.0.2.tgz#513abfd256d7ad0bf1ee1873606317b33b1b2a72" + integrity sha512-GJhpTepz2udxGexqos8wgaBx4I/zWIDPh/KOGEwAqtuGDkOUJu5eFvwmdBX4AmB8Odsr+9pHCQqiAqDL/yKMKw== + +"@types/koa-bodyparser@^4.3.0": + version "4.3.0" + resolved "https://registry.yarnpkg.com/@types/koa-bodyparser/-/koa-bodyparser-4.3.0.tgz#54ecd662c45f3a4fa9de849528de5fc8ab269ba5" + integrity sha512-aB/vwwq4G9FAtKzqZ2p8UHTscXxZvICFKVjuckqxCtkX1Ro7F5KHkTCUqTRZFBgDoEkmeca+bFLI1bIsdPPZTA== + dependencies: + "@types/koa" "*" + +"@types/koa-compose@*": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@types/koa-compose/-/koa-compose-3.2.5.tgz#85eb2e80ac50be95f37ccf8c407c09bbe3468e9d" + integrity sha512-B8nG/OoE1ORZqCkBVsup/AKcvjdgoHnfi4pZMn5UwAPCbhk/96xyv284eBYW8JlQbQ7zDmnpFr68I/40mFoIBQ== + dependencies: + "@types/koa" "*" + +"@types/koa@*", "@types/koa@^2.11.0": + version "2.11.0" + resolved "https://registry.yarnpkg.com/@types/koa/-/koa-2.11.0.tgz#394a3e9ec94f796003a6c8374b4dbc2778746f20" + integrity sha512-Hgx/1/rVlJvqYBrdeCsS7PDiR2qbxlMt1RnmNWD4Uxi5FF9nwkYqIldo7urjc+dfNpk+2NRGcnAYd4L5xEhCcQ== + dependencies: + "@types/accepts" "*" + "@types/cookies" "*" + "@types/http-assert" "*" + "@types/keygrip" "*" + "@types/koa-compose" "*" + "@types/node" "*" + +"@types/koa__cors@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/koa__cors/-/koa__cors-3.0.1.tgz#a8cf8535f0fe682c9421f1b9379837c585f8b66b" + integrity sha512-loqZNXliley8kncc4wrX9KMqLGN6YfiaO3a3VFX+yVkkXJwOrZU4lipdudNjw5mFyC+5hd7h9075hQWcVVpeOg== + dependencies: + "@types/koa" "*" + "@types/levelup@^3.1.0": version "3.1.1" resolved "https://registry.yarnpkg.com/@types/levelup/-/levelup-3.1.1.tgz#f7cc08f248f14cb6c92914e91bceb8761020e8f0" @@ -987,6 +1259,11 @@ "@types/abstract-leveldown" "*" "@types/node" "*" +"@types/long@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" + integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== + "@types/memdown@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/memdown/-/memdown-3.0.0.tgz#2d909cb507afd341e3132d77dafa213347e47455" @@ -994,11 +1271,21 @@ dependencies: "@types/abstract-leveldown" "*" +"@types/mime@*": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" + integrity sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== +"@types/mocha@^5.2.7": + version "5.2.7" + resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.7.tgz#315d570ccb56c53452ff8638738df60726d5b6ea" + integrity sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ== + "@types/node@*", "@types/node@>= 8": version "13.5.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-13.5.0.tgz#4e498dbf355795a611a87ae5ef811a8660d42662" @@ -1009,6 +1296,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-11.11.6.tgz#df929d1bb2eee5afdda598a41930fe50b43eaa6a" integrity sha512-Exw4yUWMBXM3X+8oqzJNRqZSwUAaS4+7NdvHqQuFi/d+synz++xmX3QIf+BFqneW8N31R8Ky+sikfZUXq07ggQ== +"@types/node@^10.1.0": + version "10.17.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.14.tgz#b6c60ebf2fb5e4229fdd751ff9ddfae0f5f31541" + integrity sha512-G0UmX5uKEmW+ZAhmZ6PLTQ5eu/VPaT+d/tdLd5IFsKRPcbe6lPxocBtcYBFSaLaCW8O60AX90e91Nsp8lVHCNw== + "@types/node@^10.12.18": version "10.17.13" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.13.tgz#ccebcdb990bd6139cd16e84c39dc2fb1023ca90c" @@ -1019,6 +1311,19 @@ resolved "https://registry.yarnpkg.com/@types/random-js/-/random-js-1.0.31.tgz#18a8bcc075afa504421e638fcbe021f27e802941" integrity sha512-EAM56DrKw3VhcE4HV0/YlVKeJI07We4Mz1ra6TNtZpaMoiBVMA2bkLEcoFpYOyxoDXfVZWojxkR617LTqtRI0A== +"@types/range-parser@*": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.3.tgz#7ee330ba7caafb98090bece86a5ee44115904c2c" + integrity sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA== + +"@types/serve-static@*": + version "1.13.3" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.3.tgz#eb7e1c41c4468272557e897e9171ded5e2ded9d1" + integrity sha512-oprSwp094zOglVrXdlo/4bAHtKTAxX6VT8FOZlBKrmyLbNvE1zxZyJ6yikMVtHIvwP45+ZQGJn+FdXGKTozq0g== + dependencies: + "@types/express-serve-static-core" "*" + "@types/mime" "*" + "@typescript-eslint/eslint-plugin@^2.10.0": version "2.17.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.17.0.tgz#880435a9f9bdd50b45fa286ba63fed723d73c837" @@ -1257,7 +1562,7 @@ abstract-leveldown@~6.2.1: level-supports "~1.0.0" xtend "~4.0.0" -accepts@~1.3.4: +accepts@^1.3.5, accepts@~1.3.4: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== @@ -1326,6 +1631,11 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ansi-colors@3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" + integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== + ansi-escapes@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" @@ -1365,7 +1675,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -any-promise@^1.0.0: +any-promise@^1.0.0, any-promise@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= @@ -1519,6 +1829,11 @@ assert@^1.1.1: object-assign "^4.1.1" util "0.10.3" +assertion-error@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" + integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" @@ -1682,11 +1997,16 @@ bluebird@^3.3.0, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.8, bn.js@^4.4.0: +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.1, bn.js@^4.11.8, bn.js@^4.4.0: version "4.11.8" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== +bn.js@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.1.1.tgz#48efc4031a9c4041b9c99c6941d903463ab62eb5" + integrity sha512-IUTD/REb78Z2eodka1QZyyEk66pciRcP6Sroka0aI3tG/iwIdYLrBD62RsubR7vqdt3WyX8p4jxeatzmRSphtA== + body-parser@^1.16.1: version "1.19.0" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" @@ -1739,6 +2059,11 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -1906,6 +2231,14 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" +cache-content-type@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-content-type/-/cache-content-type-1.0.1.tgz#035cde2b08ee2129f4a8315ea8f00a00dba1453c" + integrity sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA== + dependencies: + mime-types "^2.1.18" + ylru "^1.2.0" + call-me-maybe@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" @@ -1977,7 +2310,19 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= -chalk@2.4.2, chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.2: +chai@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/chai/-/chai-4.2.0.tgz#760aa72cf20e3795e84b12877ce0e83737aa29e5" + integrity sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw== + dependencies: + assertion-error "^1.1.0" + check-error "^1.0.2" + deep-eql "^3.0.1" + get-func-name "^2.0.0" + pathval "^1.1.0" + type-detect "^4.0.5" + +chalk@2.4.2, chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -1991,6 +2336,26 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +check-error@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" + integrity sha1-V00xLt2Iu13YkS6Sht1sCu1KrII= + +chokidar@3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" + integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.2.0" + optionalDependencies: + fsevents "~2.1.1" + chokidar@^2.0.2: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" @@ -2102,6 +2467,21 @@ clone@^1.0.2: resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +co-body@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/co-body/-/co-body-6.0.0.tgz#965b9337d7f5655480787471f4237664820827e3" + integrity sha512-9ZIcixguuuKIptnY8yemEOuhb71L/lLf+Rl5JfJEUiDNJk0e02MBt7BPxR2GEh5mw8dPthQYR4jPI/BnS1MQgw== + dependencies: + inflation "^2.0.0" + qs "^6.5.2" + raw-body "^2.3.3" + type-is "^1.6.16" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -2253,7 +2633,14 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -content-type@~1.0.4: +content-disposition@~0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== + dependencies: + safe-buffer "5.1.2" + +content-type@^1.0.4, content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== @@ -2346,6 +2733,14 @@ cookie@0.3.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= +cookies@~0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.8.0.tgz#1293ce4b391740a8406e3c9870e828c4b54f3f90" + integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow== + dependencies: + depd "~2.0.0" + keygrip "~1.1.0" + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -2363,6 +2758,11 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +copy-to@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/copy-to/-/copy-to-2.0.1.tgz#2680fbb8068a48d08656b6098092bdafc906f4a5" + integrity sha1-JoD7uAaKSNCGVrYJgJK9r8kG9KU= + core-util-is@1.0.2, 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" @@ -2492,7 +2892,7 @@ debug@3.1.0, debug@=3.1.0, debug@~3.1.0: dependencies: ms "2.0.0" -debug@^3.0.0, debug@^3.1.0, debug@^3.2.6: +debug@3.2.6, debug@^3.0.0, debug@^3.1.0, debug@^3.2.6: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -2534,6 +2934,18 @@ dedent@^0.7.0: resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" integrity sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw= +deep-eql@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" + integrity sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw== + dependencies: + type-detect "^4.0.0" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" @@ -2593,11 +3005,16 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -depd@~1.1.2: +depd@^1.1.2, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + deprecation@^2.0.0: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -2611,6 +3028,11 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +destroy@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + detect-file@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/detect-file/-/detect-file-1.0.0.tgz#f0d66d03672a825cb1b73bdb3fe62310c8e552b7" @@ -2634,6 +3056,11 @@ di@^0.0.1: resolved "https://registry.yarnpkg.com/di/-/di-0.0.1.tgz#806649326ceaa7caa3306d75d985ea2748ba913c" integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw= +diff@3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + diff@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" @@ -2760,7 +3187,7 @@ emojis-list@^2.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= -encodeurl@~1.0.2: +encodeurl@^1.0.2, encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= @@ -2871,6 +3298,11 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" +error-inject@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" + integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= + es-abstract@^1.17.0, es-abstract@^1.17.0-next.1: version "1.17.4" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184" @@ -2914,12 +3346,12 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -escape-html@~1.0.3: +escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= -escape-string-regexp@^1.0.5: +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -3299,6 +3731,13 @@ find-cache-dir@^2.1.0: make-dir "^2.0.0" pkg-dir "^3.0.0" +find-up@3.0.0, find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -3314,13 +3753,6 @@ find-up@^2.0.0, find-up@^2.1.0: dependencies: locate-path "^2.0.0" -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - findup-sync@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" @@ -3340,6 +3772,13 @@ flat-cache@^2.0.1: rimraf "2.6.3" write "1.0.3" +flat@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.0.tgz#090bec8b05e39cba309747f1d588f04dbaf98db2" + integrity sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw== + dependencies: + is-buffer "~2.0.3" + flatted@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" @@ -3393,6 +3832,11 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" +fresh@~0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + from2@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" @@ -3456,7 +3900,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@~2.1.2: +fsevents@~2.1.1, fsevents@~2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.2.tgz#4c0a1fb34bc68e543b4b82a9ec392bfbda840805" integrity sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA== @@ -3495,6 +3939,11 @@ get-caller-file@^2.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-func-name@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" + integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= + get-pkg-repo@^1.0.0: version "1.4.0" resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz#c73b489c06d80cc5536c2c853f9e05232056972d" @@ -3609,6 +4058,18 @@ glob-to-regexp@^0.3.0: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" integrity sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs= +glob@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.0.0, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.1.6" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" @@ -3683,6 +4144,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6 resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== +growl@1.10.5: + version "1.10.5" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" + integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== + handlebars@^4.4.0: version "4.7.2" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.2.tgz#01127b3840156a0927058779482031afe0e730d7" @@ -3788,6 +4254,11 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + hmac-drbg@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -3809,6 +4280,14 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.7.1: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c" integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg== +http-assert@^1.3.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.4.1.tgz#c5f725d677aa7e873ef736199b89686cceb37878" + integrity sha512-rdw7q6GTlibqVVbXr0CKelfV5iY8G2HqEUkhSk297BMbSpSL8crXC+9rjKoMcZZEsksX30le6f/4ul4E28gegw== + dependencies: + deep-equal "~1.0.1" + http-errors "~1.7.2" + http-cache-semantics@^3.8.1: version "3.8.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" @@ -3825,6 +4304,17 @@ http-errors@1.7.2: statuses ">= 1.5.0 < 2" toidentifier "1.0.0" +http-errors@1.7.3, http-errors@^1.6.3, http-errors@~1.7.2: + version "1.7.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" + integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== + dependencies: + depd "~1.1.2" + inherits "2.0.4" + setprototypeof "1.1.1" + statuses ">= 1.5.0 < 2" + toidentifier "1.0.0" + http-proxy-agent@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz#e4821beef5b2142a2026bd73926fe537631c5405" @@ -3956,6 +4446,11 @@ infer-owner@^1.0.3, infer-owner@^1.0.4: resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== +inflation@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/inflation/-/inflation-2.0.0.tgz#8b417e47c28f925a45133d914ca1fd389107f30f" + integrity sha1-i0F+R8KPklpFEz2RTKH9OJEH8w8= + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -3964,7 +4459,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -4089,6 +4584,11 @@ is-buffer@^1.1.5: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-buffer@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" + integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== + is-callable@^1.1.4, is-callable@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" @@ -4184,6 +4684,11 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-generator-function@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" + integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== + is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" @@ -4341,6 +4846,11 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== +isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" @@ -4376,7 +4886,7 @@ js-tokens@^4.0.0: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.1: +js-yaml@3.13.1, js-yaml@^3.13.1: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -4514,6 +5024,13 @@ karma@^4.1.0: tmp "0.0.33" useragent "2.3.0" +keygrip@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.1.0.tgz#871b1681d5e159c62a445b0c74b615e0917e7226" + integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== + dependencies: + tsscmp "1.0.6" + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -4538,6 +5055,64 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +koa-bodyparser@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/koa-bodyparser/-/koa-bodyparser-4.2.1.tgz#4d7dacb5e6db1106649b595d9e5ccb158b6f3b29" + integrity sha512-UIjPAlMZfNYDDe+4zBaOAUKYqkwAGcIU6r2ARf1UOXPAlfennQys5IiShaVeNf7KkVBlf88f2LeLvBFvKylttw== + dependencies: + co-body "^6.0.0" + copy-to "^2.0.1" + +koa-compose@^3.0.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" + integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec= + dependencies: + any-promise "^1.1.0" + +koa-compose@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" + integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== + +koa-convert@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" + integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA= + dependencies: + co "^4.6.0" + koa-compose "^3.0.0" + +koa@^2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.11.0.tgz#fe5a51c46f566d27632dd5dc8fd5d7dd44f935a4" + integrity sha512-EpR9dElBTDlaDgyhDMiLkXrPwp6ZqgAIBvhhmxQ9XN4TFgW+gEz6tkcsNI6BnUbUftrKDjVFj4lW2/J2aNBMMA== + dependencies: + accepts "^1.3.5" + cache-content-type "^1.0.0" + content-disposition "~0.5.2" + content-type "^1.0.4" + cookies "~0.8.0" + debug "~3.1.0" + delegates "^1.0.0" + depd "^1.1.2" + destroy "^1.0.4" + encodeurl "^1.0.2" + error-inject "^1.0.0" + escape-html "^1.0.3" + fresh "~0.5.2" + http-assert "^1.3.0" + http-errors "^1.6.3" + is-generator-function "^1.0.7" + koa-compose "^4.1.0" + koa-convert "^1.2.0" + on-finished "^2.3.0" + only "~0.0.2" + parseurl "^1.3.2" + statuses "^1.5.0" + type-is "^1.6.16" + vary "^1.1.2" + lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -4755,6 +5330,13 @@ lodash@^4.17.12, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.2.1: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +log-symbols@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg== + dependencies: + chalk "^2.0.1" + log4js@^4.0.0: version "4.5.1" resolved "https://registry.yarnpkg.com/log4js/-/log4js-4.5.1.tgz#e543625e97d9e6f3e6e7c9fc196dd6ab2cae30b5" @@ -5004,7 +5586,7 @@ mime-db@1.43.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58" integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ== -mime-types@^2.1.12, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.1.12, mime-types@^2.1.18, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.26" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06" integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ== @@ -5036,7 +5618,7 @@ minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= -minimatch@^3.0.2, minimatch@^3.0.4: +minimatch@3.0.4, minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== @@ -5117,13 +5699,43 @@ mkdirp@*: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.3.tgz#4cf2e30ad45959dddea53ad97d518b6c8205e1ea" integrity sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g== -mkdirp@^0.5.0, mkdirp@^0.5.1: +mkdirp@0.5.1, mkdirp@^0.5.0, mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= dependencies: minimist "0.0.8" +mocha@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.0.1.tgz#276186d35a4852f6249808c6dd4a1376cbf6c6ce" + integrity sha512-9eWmWTdHLXh72rGrdZjNbG3aa1/3NRPpul1z0D979QpEnFdCG0Q5tv834N+94QEN2cysfV72YocQ3fn87s70fg== + dependencies: + ansi-colors "3.2.3" + browser-stdout "1.3.1" + chokidar "3.3.0" + debug "3.2.6" + diff "3.5.0" + escape-string-regexp "1.0.5" + find-up "3.0.0" + glob "7.1.3" + growl "1.10.5" + he "1.2.0" + js-yaml "3.13.1" + log-symbols "2.2.0" + minimatch "3.0.4" + mkdirp "0.5.1" + ms "2.1.1" + node-environment-flags "1.0.6" + object.assign "4.1.0" + strip-json-comments "2.0.1" + supports-color "6.0.0" + which "1.3.1" + wide-align "1.1.3" + yargs "13.3.0" + yargs-parser "13.1.1" + yargs-unparser "1.6.0" + modify-values@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -5146,6 +5758,11 @@ ms@2.0.0: resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= +ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + ms@^2.0.0, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -5222,6 +5839,14 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +node-environment-flags@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" + integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== + dependencies: + object.getownpropertydescriptors "^2.0.3" + semver "^5.7.0" + node-fetch-npm@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7" @@ -5439,7 +6064,7 @@ object-visit@^1.0.0: dependencies: isobject "^3.0.0" -object.assign@^4.1.0: +object.assign@4.1.0, object.assign@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== @@ -5479,7 +6104,7 @@ octokit-pagination-methods@^1.1.0: resolved "https://registry.yarnpkg.com/octokit-pagination-methods/-/octokit-pagination-methods-1.1.0.tgz#cf472edc9d551055f9ef73f6e42b4dbb4c80bea4" integrity sha512-fZ4qZdQ2nxJvtcasX7Ghl+WlWS/d9IgnBIwFZXVNNZUmzpno91SX5bc5vuxiuKoCtK78XxGGNuSCrDC7xYB3OQ== -on-finished@~2.3.0: +on-finished@^2.3.0, on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= @@ -5507,6 +6132,11 @@ onetime@^5.1.0: dependencies: mimic-fn "^2.1.0" +only@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" + integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= + optimist@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" @@ -5746,7 +6376,7 @@ parseuri@0.0.5: dependencies: better-assert "~1.0.0" -parseurl@~1.3.3: +parseurl@^1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== @@ -5816,6 +6446,11 @@ path-type@^3.0.0: dependencies: pify "^3.0.0" +pathval@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" + integrity sha1-uULm1L3mUwBe9rcTYd74cn0GReA= + pbkdf2@^3.0.16, pbkdf2@^3.0.3, pbkdf2@^3.0.9: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -5940,6 +6575,25 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= +protobufjs@^6.8.6: + version "6.8.8" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.8.8.tgz#c8b4f1282fd7a90e6f5b109ed11c84af82908e7c" + integrity sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.0" + "@types/node" "^10.1.0" + long "^4.0.0" + protocols@^1.1.0, protocols@^1.4.0: version "1.4.7" resolved "https://registry.yarnpkg.com/protocols/-/protocols-1.4.7.tgz#95f788a4f0e979b291ffefcf5636ad113d037d32" @@ -6034,6 +6688,11 @@ qs@6.7.0: resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@^6.5.2: + version "6.9.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.9.1.tgz#20082c65cb78223635ab1a9eaca8875a29bf8ec9" + integrity sha512-Cxm7/SS/y/Z3MHWSxXb8lIFqgqBowP5JMlTUFyJN88y0SGQhVmZnqFK/PeuMX9LzUyWsqqhNxIyg0jlzq946yA== + qs@~6.5.2: version "6.5.2" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" @@ -6089,6 +6748,16 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +raw-body@^2.3.3: + version "2.4.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.1.tgz#30ac82f98bb5ae8c152e67149dac8d55153b168c" + integrity sha512-9WmIKF6mkvA0SLmA2Knm9+qj89e+j1zqgyn8aXGd7+nAduPoqgI9lO57SAZNn/Byzo5P7JhXTyg9PzaJbH73bA== + dependencies: + bytes "3.1.0" + http-errors "1.7.3" + iconv-lite "0.4.24" + unpipe "1.0.0" + read-cmd-shim@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-1.0.5.tgz#87e43eba50098ba5a32d0ceb583ab8e43b961c16" @@ -6216,6 +6885,13 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" +readdirp@~3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" + integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== + dependencies: + picomatch "^2.0.4" + readdirp@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.3.0.tgz#984458d13a1e42e2e9f5841b129e162f369aff17" @@ -6422,6 +7098,13 @@ ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: hash-base "^3.0.0" inherits "^2.0.1" +rlp@^2.2.3: + version "2.2.4" + resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.4.tgz#d6b0e1659e9285fc509a5d169a9bd06f704951c1" + integrity sha512-fdq2yYCWpAQBhwkZv+Z8o/Z4sPmYm1CUq6P7n6lVTOdb949CnqA0sndXal5C1NleSVSZm6q5F3iEbauyVln/iw== + dependencies: + bn.js "^4.11.1" + run-async@^2.2.0: version "2.3.0" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" @@ -6443,16 +7126,16 @@ rxjs@^6.4.0, rxjs@^6.5.3: dependencies: tslib "^1.9.0" +safe-buffer@5.1.2, 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" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== -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" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" @@ -6808,7 +7491,7 @@ static-extend@^0.1.1: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: +"statuses@>= 1.5.0 < 2", statuses@^1.5.0, statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= @@ -6978,6 +7661,11 @@ strip-indent@^2.0.0: resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" integrity sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g= +strip-json-comments@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + strip-json-comments@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" @@ -6992,6 +7680,13 @@ strong-log-transformer@^2.0.0: minimist "^1.2.0" through "^2.3.4" +supports-color@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" + integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== + dependencies: + has-flag "^3.0.0" + supports-color@6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" @@ -7251,6 +7946,11 @@ tslint@^5.19.0: tslib "^1.8.0" tsutils "^2.29.0" +tsscmp@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb" + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== + "tsutils@^2.28.0 || ^3.0.0", tsutils@^3.17.1: version "3.17.1" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759" @@ -7289,6 +7989,11 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" +type-detect@^4.0.0, type-detect@^4.0.5: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + type-fest@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" @@ -7299,7 +8004,7 @@ type-fest@^0.8.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== -type-is@~1.6.17: +type-is@^1.6.16, type-is@~1.6.17: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -7498,6 +8203,11 @@ validate-npm-package-name@^3.0.0: dependencies: builtins "^1.0.3" +vary@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= + verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -7606,14 +8316,14 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@^1.2.1, which@^1.2.14, which@^1.2.9, which@^1.3.1: +which@1.3.1, which@^1.2.1, which@^1.2.14, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== dependencies: isexe "^2.0.0" -wide-align@^1.1.0: +wide-align@1.1.3, wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== @@ -7706,6 +8416,13 @@ write@1.0.3: dependencies: mkdirp "^0.5.1" +ws@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.1.tgz#442fdf0a47ed64f59b6a5d8ff130f4748ed524fb" + integrity sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA== + dependencies: + async-limiter "~1.0.0" + ws@~3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" @@ -7747,14 +8464,7 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== -yargs-parser@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" - integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== - dependencies: - camelcase "^4.1.0" - -yargs-parser@^13.1.0: +yargs-parser@13.1.1, yargs-parser@^13.1.0, yargs-parser@^13.1.1: version "13.1.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.1.tgz#d26058532aa06d365fe091f6a1fc06b2f7e5eca0" integrity sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ== @@ -7762,6 +8472,13 @@ yargs-parser@^13.1.0: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-parser@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" + integrity sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ== + dependencies: + camelcase "^4.1.0" + yargs-parser@^15.0.0: version "15.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-15.0.0.tgz#cdd7a97490ec836195f59f3f4dbe5ea9e8f75f08" @@ -7770,6 +8487,15 @@ yargs-parser@^15.0.0: camelcase "^5.0.0" decamelize "^1.2.0" +yargs-unparser@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" + integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== + dependencies: + flat "^4.1.0" + lodash "^4.17.15" + yargs "^13.3.0" + yargs@13.2.4: version "13.2.4" resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" @@ -7787,6 +8513,22 @@ yargs@13.2.4: y18n "^4.0.0" yargs-parser "^13.1.0" +yargs@13.3.0, yargs@^13.3.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" + integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== + dependencies: + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.1" + yargs@^14.2.2: version "14.2.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.2.tgz#2769564379009ff8597cdd38fba09da9b493c4b5" @@ -7808,3 +8550,8 @@ yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= + +ylru@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ylru/-/ylru-1.2.1.tgz#f576b63341547989c1de7ba288760923b27fe84f" + integrity sha512-faQrqNMzcPCHGVC2aaOINk13K+aaBDUPjGWl0teOXywElLjyVAB6Oe2jj62jHYtwsU49jXhScYbvPENK+6zAvQ==